[m-rev.] for review: inter-module optimization with sub-modules

Simon Taylor stayl at cs.mu.OZ.AU
Sun Apr 7 20:21:59 AEST 2002


On 27-Mar-2002, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 26-Mar-2002, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > 
> > Index: compiler/mercury_to_mercury.m
> > +++ compiler/mercury_to_mercury.m	23 Mar 2002 07:03:59 -0000
> > @@ -885,7 +885,9 @@
> >  		io__write_string(").\n")
> >  	;
> >  		% XXX unimplemented
> > -		io__write_string("% unimplemented module declaration\n")
> > +		io__write_string("% unimplemented module declaration "),
> > +		io__write(ModuleDefn),
> > +		io__nl
> 
> That wasn't mentioned in the log message.
> What's the point of this change?

compiler/mercury_to_mercury.m:
	Improve the comment generated for module_defn items which shouldn't
	appear in Mercury source.
 
> > @@ -610,6 +610,8 @@
> >  :- pred get_ancestors(module_name, list(module_name)).
> >  :- mode get_ancestors(in, out) is det.
> >  
> > +:- func get_ancestors(module_name) = list(module_name).
> 
> For the compiler, IMHO it's better to just change the predicate into a
> function, rather than having two versions.

Done.

> >  	% init_dependencies(FileName, SourceFileModuleName, NestedModuleNames,
> >  	%	Error, Globals, ModuleName - Items, ModuleImports).
> >  :- pred init_dependencies(file_name, module_name, list(module_name),
> > @@ -2056,15 +2058,20 @@
> >  				JavaDateFileName, " : "
> >  			]),
> >  
> > -			% The target (e.g. C) file only depends on the .opt files
> > -			% from  the current directory, so that inter-module
> > -			% optimization works when the .opt files for the 
> > -			% library are unavailable. This is only necessary 
> > -			% because make doesn't allow conditional dependencies.
> > +			% The target (e.g. C) file only depends on the .opt
> > +			% files from the current directory, so that
> > +			% inter-module optimization works when the .opt files
> > +			% for the library are unavailable. This is only
> > +			% necessary because make doesn't allow conditional
> > +			% dependencies.
> >  			% The dependency on the current module's .opt file
> >  			% is to make sure the module gets type-checked without
> >  			% having the definitions of abstract types from other
> >  			% modules.
> > +			%
> > +			% XXX The code here doesn't correctly handle
> > +			% dependencies on `.int' and `.int2' files needed
> > +			% by the `.opt' files.
> 
> Won't the `.opt' files themselves have dependencies on the `.int'
> and `.int2' files that they need?
> So doesn't that guarantee that the `.int' and `.int2' files
> needed must have been built before the `.opt' file can be used?

They will be built before the `.opt' file can be used, but if
they change in a way that doesn't change the `.opt' file, modules
using the `.opt' file won't be recompiled.
 
> > @@ -2645,6 +2663,8 @@
> >  	% If --use-opt-files is set, don't look for `.m' files, since
> >  	% we are not building `.opt' files, only using those which
> >  	% are available.
> > +	% XXX This doesn't do the right thing for nested sub-modules.
> > +	% XXX Use `mmc --make' if that matters.
> >  :- pred get_both_opt_deps(bool::in, list(module_name)::in, list(string)::in, 
> 
> What does it do wrong for nested sub-modules?

-       % XXX This doesn't do the right thing for nested sub-modules.
+       % XXX This won't find nested sub-modules.

> > @@ -4785,68 +4805,66 @@
> >  	maybe_write_string(VeryVerbose, FileName0),
> >  	maybe_write_string(VeryVerbose, "'... "),
> >  	maybe_flush_output(VeryVerbose),
> > +	( { Extension = ".m" } ->
> > +		{ OpenFile = search_for_module_source(ModuleName) }
> > +	;
> > +		( { Search = yes } ->
> > +			globals__io_lookup_accumulating_option(
> > +				search_directories, SearchDirs)
> > +		;
> > +			{ SearchDirs = [dir__this_directory] }
> > +		),
> > +		{ OpenFile = search_for_file(SearchDirs, FileName0) }
> > +	),
> 
> What is this complicated if-then-else for?
> Why does the Extension = ".m" case get handled specially?
> A comment or two here would help.
> 
> > Index: compiler/post_typecheck.m
> 
> The changes here should be documented at the top of the module
> and in compilers/notes/compiler_design.html.

Done.
 
> It might be better to move the mode-checking-related code in
> post_typecheck.m into a separate module, and just call it from
> post_typecheck.m.

I don't see much point in doing this.
 
> > Index: compiler/prog_io.m
> > +:- type open_file(T) == pred(maybe_error(T), io__state, io__state).
> > +:- inst open_file == (pred(out, di, uo) is det).
> > +
> > +	% prog_io__read_module(OpenFile, FileName, DefaultModuleName,
> >  	%		ReturnTimestamp, Error, ActualModuleName,
> >  	%		Messages, Program, MaybeModuleTimestamp)
> > -	% Reads and parses the module in file `FileName',
> > +	% Reads and parses the file opened by `OpenFile'
> ...
> > +:- pred prog_io__read_module(open_file(T), module_name, bool,
> > +		module_error, maybe(T), module_name, message_list, item_list,
> >  		maybe(io__res(timestamp)), io__state, io__state).
> > +:- mode prog_io__read_module(in(open_file), in, in,
> > +		out, out, out, out, out, out, di, uo) is det.
> 
> You should explain what `OpenFile' is, and it's interface.
> What's the `T' in its interface?
> How does prog_io__read_module get the file that `OpenFile' opened?
> 
> What's the `maybe(T)' parameter to prog_io__read_module?
> This is not mentioned in the comment.

Fixed.
 
> > Index: tests/invalid/duplicate_modes.err_exp
> > ===================================================================
> > RCS file: /home/mercury1/repository/tests/invalid/duplicate_modes.err_exp,v
> > retrieving revision 1.4
> > diff -u -u -r1.4 duplicate_modes.err_exp
> > --- tests/invalid/duplicate_modes.err_exp	31 Aug 1999 05:25:59 -0000	1.4
> > +++ tests/invalid/duplicate_modes.err_exp	25 Mar 2002 14:10:39 -0000
> > @@ -4,15 +4,15 @@
> >  		`:- import_module' in its interface section(s).
> >  		This would normally be a `:- pred', `:- func', `:- type',
> >  		`:- inst' or `:- mode' declaration.
> > -duplicate_modes.m:008: In mode declarations for predicate `duplicate_modes:q/2':
> > -duplicate_modes.m:008:   error: duplicate mode declaration.
> > -duplicate_modes.m:008:   Modes `q(in, out) is det'
> > -duplicate_modes.m:008:   and `q((ground -> ground), (free -> ground)) is det'
> > -duplicate_modes.m:008:   are indistinguishable.
> > -duplicate_modes.m:009:   Here is the conflicting mode declaration.
> > +duplicate_modes.m:009: In mode declarations for predicate `duplicate_modes:q/2':
> > +duplicate_modes.m:009:   error: duplicate mode declaration.
> > +duplicate_modes.m:009:   Modes `q((ground -> ground), (free -> ground)) is det'
> > +duplicate_modes.m:009:   and `q(in, out) is det'
> > +duplicate_modes.m:009:   are indistinguishable.
> > +duplicate_modes.m:008:   Here is the conflicting mode declaration.
> 
> This change is undesirable, IMHO, because it makes the error messages
> harder to read when using the `error' utility.

Fixed.

Simon.


Estimated hours taken: 15
Branches: main

Make inter-module optimization work properly with sub-modules.

compiler/intermod.m:
	Write `exported_to_submodules' predicates to the `.opt' file.

	Read `.int0' files needed by the `.opt' files.

compiler/make.dependencies.m:
compiler/modules.m:
	Handle dependencies on the extra `.int0' files when compiling
	with `--intermodule-optimization'.

compiler/modules.m:
compiler/prog_io.m:
compiler/*.m:
	Handle partially qualified file names when searching for
	the `.m' file for a module when checking whether there
	should be a dependency on the `.opt' file for the module.

	Separate out the code to find for the source file for a module
	from the code to read the source file for a module.

	Remove an unnecessary argument from prog_io__read_opt_file
	(`.opt' files are always searched for).

compiler/modules.m:
	Export process_module_private_interfaces, for use by intermod.m.

	Remove process_module_indirect_imports, which isn't used anywhere.

	Change get_ancestors from a predicate to a function.

compiler/make_hlds.m:
	Don't report duplicate declaration errors for items imported
	for inter-module optimization. Sometimes both the `.int' and
	`.int0' file for a module are read, and the `.int0' file contains
	everything in the `.int' file..

compiler/modes.m:
compiler/post_typecheck.m:
	Don't report errors for duplicate mode declarations for imported
	predicates when performing inter-module optimization. If the
	`.int' and `.int0' files for a module are both read, the mode
	declarations for a predicate can be read twice.

	Where there are duplicate mode declarations, remove the
	duplicate procedures.

	Move the code to check for indistinguishable modes into
	post_typecheck.m. It only needs to be done once, not
	on every iteration of mode inference.

compiler/hlds_pred.m:
	Add a predicate pred_info_remove_procid, for use by post_typecheck.m.

compiler/mercury_to_mercury.m:
	Improve the comment generated for module_defn items which shouldn't
	appear in Mercury source.

compiler/notes/compiler_design.html:
	Improve the documentation of post_typecheck.m.

tests/invalid/qualified_cons_id2.err_exp:
	Update expected output.

diff -u compiler/make.dependencies.m compiler/make.dependencies.m
--- compiler/make.dependencies.m
+++ compiler/make.dependencies.m
@@ -310,8 +310,8 @@
 :- pred parents(module_name::in, bool::out, set(module_name)::out,
 	make_info::in, make_info::out, io__state::di, io__state::uo) is det.
 
-parents(ModuleName, yes, set__list_to_set(Ancestors), Info, Info) -->
-	{ get_ancestors(ModuleName, Ancestors) }.
+parents(ModuleName, yes, set__list_to_set(get_ancestors(ModuleName)),
+		Info, Info) --> [].
 
 %-----------------------------------------------------------------------------%
 
diff -u compiler/make.module_dep_file.m compiler/make.module_dep_file.m
--- compiler/make.module_dep_file.m
+++ compiler/make.module_dep_file.m
@@ -51,7 +51,7 @@
 		% generated as a side effect of generating the parent's
 		% dependencies.
 		%
-		{ get_ancestors(ModuleName, Ancestors) },
+		{ Ancestors = get_ancestors(ModuleName) },
 		list__foldl3(
 			generate_ancestor_dependencies(RebuildDeps),
 				Ancestors, no, Error, Info0, Info1),
diff -u compiler/modules.m compiler/modules.m
--- compiler/modules.m
+++ compiler/modules.m
@@ -582,7 +582,7 @@
 	%	using `:- use_module'.
 	%	N.B. Typically you also need to consider the module's
 	%	implicit dependencies (see get_implicit_dependencies/3),
-	%	its parent modules (see get_ancestors/2) and possibly
+	%	its parent modules (see get_ancestors/1) and possibly
 	%	also the module's child modules (see get_children/2).
 	%	You may also need to consider indirect dependencies.
 	%
@@ -602,14 +602,11 @@
 		list(module_name), list(module_name)).
 :- mode get_implicit_dependencies(in, in, out, out) is det.
 
-	% get_ancestors(ModuleName, ParentDeps):
+	% get_ancestors(ModuleName) =  ParentDeps:
 	%	ParentDeps is the list of ancestor modules for this
 	%	module, oldest first; e.g. if the ModuleName is 
 	%	`foo:bar:baz', then ParentDeps would be [`foo', `foo:bar'].
 	%
-:- pred get_ancestors(module_name, list(module_name)).
-:- mode get_ancestors(in, out) is det.
-
 :- func get_ancestors(module_name) = list(module_name).
 
 	% init_dependencies(FileName, SourceFileModuleName, NestedModuleNames,
@@ -1432,7 +1429,7 @@
 		%
 		% Find out which modules this one depends on
 		%
-	{ get_ancestors(ModuleName, AncestorModules) },
+	{ AncestorModules = get_ancestors(ModuleName) },
 	{ get_dependencies(Items0, IntImportedModules0, IntUsedModules0,
 			ImpImportedModules0, ImpUsedModules0) },
 
@@ -1548,7 +1545,7 @@
 		%
 		% Find out which modules this one depends on
 		%
-	{ get_ancestors(ModuleName, ParentDeps) },
+	{ ParentDeps = get_ancestors(ModuleName) },
 	{ get_dependencies(Items0, IntImportDeps0, IntUseDeps0,
 			ImpImportDeps0, ImpUseDeps0) },
 
@@ -2663,7 +2660,7 @@
 	% If --use-opt-files is set, don't look for `.m' files, since
 	% we are not building `.opt' files, only using those which
 	% are available.
-	% XXX This doesn't do the right thing for nested sub-modules.
+	% XXX This won't find nested sub-modules.
 	% XXX Use `mmc --make' if that matters.
 :- pred get_both_opt_deps(bool::in, list(module_name)::in, list(string)::in, 
 	list(module_name)::out, list(module_name)::out, 
@@ -2674,7 +2671,7 @@
 	get_both_opt_deps(BuildOptFiles, Deps, IntermodDirs,
 		OptDeps0, TransOptDeps0),
 	( { BuildOptFiles = yes } ->
-		search_for_module_source(Dep, Result1),
+		search_for_module_source(IntermodDirs, Dep, Result1),
 		( { Result1 = ok(_) } ->
 			{ OptDeps1 = [Dep | OptDeps0] },
 			{ TransOptDeps1 = [Dep | TransOptDeps0] },
@@ -2717,7 +2714,7 @@
 	% file or a .m file, filtering out those for which the search fails.
 	% If --use-opt-files is set, only look for `.opt' files,
 	% not `.m' files.
-	% XXX This doesn't do the right thing for nested sub-modules.
+	% XXX This won't find nested sub-modules.
 	% XXX Use `mmc --make' if that matters.
 :- pred get_opt_deps(bool::in, list(module_name)::in, list(string)::in,
 	string::in, list(module_name)::out,
@@ -2726,7 +2723,7 @@
 get_opt_deps(BuildOptFiles, [Dep | Deps], IntermodDirs, Suffix, OptDeps) -->
 	get_opt_deps(BuildOptFiles, Deps, IntermodDirs, Suffix, OptDeps0),
 	( { BuildOptFiles = yes } ->
-		search_for_module_source(Dep, Result1),
+		search_for_module_source(IntermodDirs, Dep, Result1),
 		( { Result1 = ok(_) } ->
 			{ OptDeps1 = [Dep | OptDeps0] },
 			{ Found = yes },
@@ -3199,7 +3196,7 @@
 
 :- func get_submodule_kind(module_name, deps_map) = submodule_kind.
 get_submodule_kind(ModuleName, DepsMap) = Kind :-
-	get_ancestors(ModuleName, Ancestors),
+	Ancestors = get_ancestors(ModuleName),
 	( list__last(Ancestors, Parent) ->
 		map__lookup(DepsMap, ModuleName, deps(_, ModuleImports)),
 		map__lookup(DepsMap, Parent, deps(_, ParentImports)),
@@ -4674,7 +4671,7 @@
 
 init_dependencies(FileName, SourceFileModuleName, NestedModuleNames,
 		Error, Globals, ModuleName - Items, ModuleImports) :-
-	get_ancestors(ModuleName, ParentDeps),
+	ParentDeps = get_ancestors(ModuleName),
 
 	get_dependencies(Items, ImplImportDeps0, ImplUseDeps0),
 	add_implicit_imports(Items, Globals, ImplImportDeps0, ImplUseDeps0,
@@ -4805,17 +4802,20 @@
 	maybe_write_string(VeryVerbose, FileName0),
 	maybe_write_string(VeryVerbose, "'... "),
 	maybe_flush_output(VeryVerbose),
-	( { Extension = ".m" } ->
-		{ OpenFile = search_for_module_source(ModuleName) }
+
+	( { Search = yes } ->
+		globals__io_lookup_accumulating_option(search_directories,
+			SearchDirs)
 	;
-		( { Search = yes } ->
-			globals__io_lookup_accumulating_option(
-				search_directories, SearchDirs)
-		;
-			{ SearchDirs = [dir__this_directory] }
-		),
-		{ OpenFile = search_for_file(SearchDirs, FileName0) }
+		{ SearchDirs = [dir__this_directory] }
 	),
+	{ Extension = ".m" ->
+		% For `.m' files we need to deal with the case where
+		% the module name does not match the file name.
+		OpenFile = search_for_module_source(SearchDirs, ModuleName)
+	;
+		OpenFile = search_for_file(SearchDirs, FileName0)
+	},
 	( { MaybeOldTimestamp = yes(OldTimestamp) } ->
 		prog_io__read_module_if_changed(OpenFile, ModuleName,
 			OldTimestamp, Error0, MaybeFileName, ActualModuleName,
@@ -5260,19 +5260,13 @@
 
 %-----------------------------------------------------------------------------%
 
-get_ancestors(ModuleName) = Ancestors :-
-	get_ancestors(ModuleName, Ancestors).
+get_ancestors(ModuleName) = get_ancestors_2(ModuleName, []).
+
+:- func get_ancestors_2(module_name, list(module_name)) = list(module_name).
 
-get_ancestors(ModuleName, Ancestors) :-
-	get_ancestors_2(ModuleName, [], Ancestors).
-	
-:- pred get_ancestors_2(module_name, list(module_name), list(module_name)).
-:- mode get_ancestors_2(in, in, out) is det.
-
-get_ancestors_2(unqualified(_), Ancestors, Ancestors).
-get_ancestors_2(qualified(Parent, _), Ancestors0, Ancestors) :-
-	Ancestors1 = [Parent | Ancestors0],
-	get_ancestors_2(Parent, Ancestors1, Ancestors).
+get_ancestors_2(unqualified(_), Ancestors) = Ancestors.
+get_ancestors_2(qualified(Parent, _), Ancestors0) = 
+	get_ancestors_2(Parent, [Parent | Ancestors0]).
 
 %-----------------------------------------------------------------------------%
 
@@ -5320,7 +5314,7 @@
 	%	implementation.
 	%	N.B. Typically you also need to consider the module's
 	%	implicit dependencies (see get_implicit_dependencies/3),
-	%	its parent modules (see get_ancestors/2) and possibly
+	%	its parent modules (see get_ancestors/1) and possibly
 	%	also the module's child modules (see get_children/2).
 	%	You may also need to consider indirect dependencies.
 	%
diff -u compiler/post_typecheck.m compiler/post_typecheck.m
--- compiler/post_typecheck.m
+++ compiler/post_typecheck.m
@@ -12,24 +12,21 @@
 %
 %	- it resolves predicate overloading
 %	- it resolves function overloading
+%	- it expands field access functions
+%	- it propagates type information into the modes of procedures
 %	- it checks for unbound type variables and if there are any,
 %	  it reports an error (or a warning, binding them to the type `void').
+%	- it reports errors for unbound inst variables in predicate or
+%	  function mode declarations
+%	- it reports errors for unsatisfied type class constraints
+%	- it reports an error if there are indistinguishable modes for
+%	  a predicate of function.
 %
 % These actions cannot be done until after type inference is complete,
 % so they need to be a separate "post-typecheck pass".  For efficiency
 % reasons, this is in fact done at the same time as purity analysis --
 % the routines here are called from purity.m rather than mercury_compile.m.
 %
-% This module also copies the clause_info structure
-% to the proc_info structures. This is done in the post_typecheck pass
-% and not at the start of modecheck because modecheck may be
-% reinvoked after HLDS transformations. Any transformation that
-% needs typechecking should work with the clause_info structure.
-% Type information is also propagated into the modes of procedures
-% by this pass if the ModeError parameter is no. 
-% ModeError should be yes if any undefined modes	
-% were found by previous passes.
-%
 
 :- module check_hlds__post_typecheck.
 :- interface.
@@ -983,8 +980,8 @@
 				MakeOptInt = yes
 			}
 		->
-			report_indistinguishable_modes_error(ProcId,
-				ProcId1, PredId, PredInfo0, ModuleInfo)
+			report_indistinguishable_modes_error(ProcId1,
+				ProcId, PredId, PredInfo0, ModuleInfo)
 		;
 			[]
 		),
diff -u compiler/prog_io.m compiler/prog_io.m
--- compiler/prog_io.m
+++ compiler/prog_io.m
@@ -67,18 +67,26 @@
 :- type file_name == string.
 :- type dir_name == string.
 
-:- type open_file(T) == pred(maybe_error(T), io__state, io__state).
+	% Open a source or interface file, returning `ok(FileInfo)' on
+	% success (where FileInfo is information about the file such as
+	% the file name or the directory in which it was found), or
+	% `error(Message)' on failure.
+:- type open_file(FileInfo) ==
+		pred(maybe_error(FileInfo), io__state, io__state).
 :- inst open_file == (pred(out, di, uo) is det).
 
 	% prog_io__read_module(OpenFile, FileName, DefaultModuleName,
-	%		ReturnTimestamp, Error, ActualModuleName,
-	%		Messages, Program, MaybeModuleTimestamp)
-	% Reads and parses the file opened by `OpenFile'
-	% using the default module name `DefaultModuleName'.
+	%		ReturnTimestamp, Error, MaybeFileInfo,
+	%		ActualModuleName, Messages, Program,
+	%		MaybeModuleTimestamp)
+	% Reads and parses the file opened by OpenFile
+	% using the default module name DefaultModuleName.
 	% If ReturnTimestamp is `yes', attempt to return the 
 	% modification timestamp in MaybeModuleTimestamp.
 	% Error is `fatal' if the file coudn't be opened, `yes'
 	% if a syntax error was detected, and `no' otherwise.
+	% MaybeFileInfo is the information about the file (usually
+	% the file or directory name) returned by OpenFile.
 	% ActualModuleName is the module name specified in the
 	% `:- module' declaration, if any, or the DefaultModuleName
 	% if there is no `:- module' declaration.
@@ -90,14 +98,14 @@
 	;	some_module_errors	% some syntax errors
 	;	fatal_module_errors.	% couldn't open the file
 
-:- pred prog_io__read_module(open_file(T), module_name, bool,
-		module_error, maybe(T), module_name, message_list, item_list,
-		maybe(io__res(timestamp)), io__state, io__state).
+:- pred prog_io__read_module(open_file(FileInfo), module_name, bool,
+		module_error, maybe(FileInfo), module_name, message_list,
+		item_list, maybe(io__res(timestamp)), io__state, io__state).
 :- mode prog_io__read_module(in(open_file), in, in,
 		out, out, out, out, out, out, di, uo) is det.
 
-:- pred prog_io__read_module_if_changed(open_file(T), module_name,
-		timestamp, module_error, maybe(T), module_name,
+:- pred prog_io__read_module_if_changed(open_file(FileInfo), module_name,
+		timestamp, module_error, maybe(FileInfo), module_name,
 		message_list, item_list, maybe(io__res(timestamp)),
 		io__state, io__state).
 :- mode prog_io__read_module_if_changed(in(open_file), in, in, 
@@ -135,13 +143,17 @@
 		maybe_error(dir_name), io__state, io__state).
 :- mode search_for_file_returning_dir(in, in, out, di, uo) is det.
 
-	% search_for_module_source(ModuleName, FoundSourceFileName, IO0, IO)
+	% search_for_module_source(Dirs, ModuleName,
+	%	FoundSourceFileName, IO0, IO)
 	%
-	% Look for the source for ModuleName in the current directory.
-	% 
-:- pred search_for_module_source(module_name, maybe_error(file_name), 
-		io__state, io__state).
-:- mode search_for_module_source(in, out, di, uo) is det.
+	% Look for the source for ModuleName in Dirs.
+	% This will also search for files matching partially
+	% qualified versions of ModuleName.
+	% For example, module foo:bar:baz can be found
+	% in foo.bar.m, bar.baz.m or bar.m.
+:- pred search_for_module_source(list(dir_name), module_name,
+		maybe_error(file_name), io__state, io__state).
+:- mode search_for_module_source(in, in, out, di, uo) is det.
 
 	% parse_item(ModuleName, VarSet, Term, MaybeItem)
 	%
@@ -392,26 +404,26 @@
 		search_for_file_returning_dir(Dirs, FileName, R)
 	).
 
-search_for_module_source(ModuleName, MaybeFileName) -->
-	search_for_module_source(ModuleName, ModuleName, MaybeFileName).	
+search_for_module_source(Dirs, ModuleName, MaybeFileName) -->
+	search_for_module_source(Dirs, ModuleName, ModuleName, MaybeFileName).	
 
-:- pred search_for_module_source(module_name, module_name,
+:- pred search_for_module_source(list(dir_name), module_name, module_name,
 		maybe_error(file_name), io__state, io__state).
-:- mode search_for_module_source(in, in, out, di, uo) is det.
+:- mode search_for_module_source(in, in, in, out, di, uo) is det.
 
-search_for_module_source(ModuleName, PartialModuleName, Result) -->
+search_for_module_source(Dirs, ModuleName, PartialModuleName, Result) -->
 	module_name_to_file_name(PartialModuleName, ".m", no, FileName),
-	io__see(FileName, OpenResult),
+	search_for_file(Dirs, FileName, Result0),
 	(
-		{ OpenResult = ok },
-		{ Result = ok(FileName) }
-	;	
-		{ OpenResult = error(_) },
+		{ Result0 = ok(_) },
+		{ Result = Result0 }
+	;
+		{ Result0 = error(_) },
 		(
 			{ PartialModuleName1 =
 				drop_one_qualifier(PartialModuleName) }
 		->
-			search_for_module_source(ModuleName,
+			search_for_module_source(Dirs, ModuleName,
 				PartialModuleName1, Result)
 		;
 			{ sym_name_to_string(ModuleName, ModuleNameStr) },
reverted:
--- tests/invalid/duplicate_modes.err_exp	25 Mar 2002 14:10:39 -0000
+++ tests/invalid/duplicate_modes.err_exp	31 Aug 1999 05:25:59 -0000	1.4
@@ -4,15 +4,15 @@
 		`:- import_module' in its interface section(s).
 		This would normally be a `:- pred', `:- func', `:- type',
 		`:- inst' or `:- mode' declaration.
+duplicate_modes.m:008: In mode declarations for predicate `duplicate_modes:q/2':
+duplicate_modes.m:008:   error: duplicate mode declaration.
+duplicate_modes.m:008:   Modes `q(in, out) is det'
+duplicate_modes.m:008:   and `q((ground -> ground), (free -> ground)) is det'
+duplicate_modes.m:008:   are indistinguishable.
+duplicate_modes.m:009:   Here is the conflicting mode declaration.
+duplicate_modes.m:014: In mode declarations for predicate `duplicate_modes:r/2':
+duplicate_modes.m:014:   error: duplicate mode declaration.
+duplicate_modes.m:014:   Modes `r(in, in) is semidet'
+duplicate_modes.m:014:   and `r(in, in) is det'
+duplicate_modes.m:014:   are indistinguishable.
+duplicate_modes.m:015:   Here is the conflicting mode declaration.
-duplicate_modes.m:009: In mode declarations for predicate `duplicate_modes:q/2':
-duplicate_modes.m:009:   error: duplicate mode declaration.
-duplicate_modes.m:009:   Modes `q((ground -> ground), (free -> ground)) is det'
-duplicate_modes.m:009:   and `q(in, out) is det'
-duplicate_modes.m:009:   are indistinguishable.
-duplicate_modes.m:008:   Here is the conflicting mode declaration.
-duplicate_modes.m:015: In mode declarations for predicate `duplicate_modes:r/2':
-duplicate_modes.m:015:   error: duplicate mode declaration.
-duplicate_modes.m:015:   Modes `r(in, in) is det'
-duplicate_modes.m:015:   and `r(in, in) is semidet'
-duplicate_modes.m:015:   are indistinguishable.
-duplicate_modes.m:014:   Here is the conflicting mode declaration.
diff -u tests/invalid/qualified_cons_id2.err_exp tests/invalid/qualified_cons_id2.err_exp
--- tests/invalid/qualified_cons_id2.err_exp
+++ tests/invalid/qualified_cons_id2.err_exp
@@ -1,6 +1,6 @@
-qualified_cons_id2.m:016: In mode declarations for predicate `qualified_cons_id2:test/2':
-qualified_cons_id2.m:016:   error: duplicate mode declaration.
-qualified_cons_id2.m:015:   Here is the conflicting mode declaration.
+qualified_cons_id2.m:015: In mode declarations for predicate `qualified_cons_id2:test/2':
+qualified_cons_id2.m:015:   error: duplicate mode declaration.
+qualified_cons_id2.m:016:   Here is the conflicting mode declaration.
 qualified_cons_id2.m:015: In `test(in(bound(qualified_cons_id2:yes(ground))), out)':
 qualified_cons_id2.m:015:   error: determinism declaration not satisfied.
 qualified_cons_id2.m:015:   Declared `det', inferred `failure'.
only in patch2:
--- compiler/notes/compiler_design.html	28 Mar 2002 03:44:36 -0000	1.76
+++ compiler/notes/compiler_design.html	28 Mar 2002 05:26:27 -0000
@@ -377,6 +377,9 @@
 	  analysis (see below).  It contains the stuff related to
 	  type checking that can't be done in the main type checking pass.
 	  It also removes assertions from further processing.
+	  post_typecheck.m reports errors for unbound type and inst variables,
+	  for unsatisified type class constraints, for indistinguishable
+	  predicate or function modes, and for invalid Aditi calls and updates.
 	</ul>
 
 <dt> assertions
only in patch2:
--- compiler/typecheck.m	28 Mar 2002 03:43:42 -0000	1.316
+++ compiler/typecheck.m	28 Mar 2002 06:05:12 -0000
@@ -5616,7 +5616,7 @@
 get_unimported_parent(ModuleQualifier, ModuleInfo, UnimportedParent) :-
 	visible_module(ModuleName, ModuleInfo),
 	match_sym_name(ModuleQualifier, ModuleName),
-	get_ancestors(ModuleName, ParentModules),
+	ParentModules = get_ancestors(ModuleName),
 	list__member(UnimportedParent, ParentModules),
 	\+ visible_module(UnimportedParent, ModuleInfo).
 
only in patch2:
--- compiler/hlds_module.m	20 Mar 2002 12:36:18 -0000	1.73
+++ compiler/hlds_module.m	27 Mar 2002 05:56:21 -0000
@@ -899,13 +899,13 @@
 	;
 		set__member(VisibleModule, ImportedModules)
 	;
-		get_ancestors(ThisModule, ParentModules),
+		ParentModules = get_ancestors(ThisModule),
 		list__member(VisibleModule, ParentModules)
 	).
 
 module_info_get_all_deps(ModuleInfo, AllImports) :-
 	module_info_name(ModuleInfo, ModuleName),
-	get_ancestors(ModuleName, Parents),
+	Parents = get_ancestors(ModuleName),
 	module_info_get_imported_module_specifiers(ModuleInfo, DirectImports),
 	module_info_get_indirectly_imported_module_specifiers(ModuleInfo,
 		IndirectImports),
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list