[m-rev.] for review: expand equivalence types fully

Simon Taylor stayl at cs.mu.OZ.AU
Mon Dec 1 14:06:18 AEDT 2003


On 29-Nov-2003, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 29-Nov-2003, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > 
> > Make definitions of abstract types available when generating
> > code for importing modules.  This is necessary for the .NET
> > back-end, and for `:- pragma export' on the C back-end.
> 
> > Index: compiler/mercury_to_mercury.m
> ...
> >  :- pred mercury_output_begin_type_decl(is_solver_type, io__state, io__state).
> >  :- mode mercury_output_begin_type_decl(in, di, uo) is det.
> >  
> > -mercury_output_begin_type_decl(solver_type) -->
> > -	io__write_string(":- solver type ").
> > -mercury_output_begin_type_decl(non_solver_type) -->
> > -	io__write_string(":- type ").
> > +mercury_output_begin_type_decl(IsSolverType) -->
> > +	io__write_string(":- "),
> > +	( { IsSolverType = solver_type }, io__write_string("solver ")
> > +	; { IsSolverType = non_solver_type }
> > +	),
> > +	io__write_string("type ").
> 
> IMHO the original code is considerably easier to read.

Fixed.  (This change, and the references to `type_impl' below
were left over from a previous attempt at this change).
 
> > Index: compiler/module_qual.m
> ...
> > +:- pred add_imports_2(list(sym_name)::in, mq_info::in, mq_info::out) is det.
> > +
> > +add_imports_2(Imports, !Info) :-
> > +	mq_info_get_import_status(!.Info, Status),
> > +	(
> > +		( Status = local 
> > +		; Status = exported
> > +		; Status = imported(ancestor_private_interface)
> >  		)
> > +	->
> > +		mq_info_get_imported_modules(!.Info, Modules0),
> > +		set__insert_list(Modules0, Imports, Modules),
> > +		mq_info_set_imported_modules(!.Info, Modules, !:Info)
> >  	;
> > -		Info = Info0
> > -	).
> > +		true
> > +	),
> > +
> > +	(
> > +		Status = exported
> > +	->
> > +		mq_info_get_unused_interface_modules(!.Info,
> > +			UnusedIntModules0),
> > +		set__insert_list(UnusedIntModules0, Imports, UnusedIntModules),
> > +		mq_info_set_unused_interface_modules(!.Info,
> > +			UnusedIntModules, !:Info)
> > +	;
> > +			true
> > +	),
> > +
> > +	(
> > +		( Status = exported
> > +		; Status = imported(ancestor_private_interface)
> > +		)
> > +	->
> > +		mq_info_get_interface_visible_modules(!.Info, IntModules0),
> > +		set__insert_list(IntModules0, Imports, IntModules),
> > +		mq_info_set_interface_visible_modules(!.Info,
> > +			IntModules, !:Info)
> > +	;
> > +		true
> > +	).	
> 
> Some comments there would be helpful.

Done.
 
> > @@ -513,13 +585,16 @@
> >  module_qualify_item(clause(A,B,C,D,E) - Con, clause(A,B,C,D,E) - Con,
> >  			Info, Info, yes) --> [].
> >  
> > -module_qualify_item(type_defn(A, SymName, Params, TypeDefn0, C) - Context,
> > -		type_defn(A, SymName, Params, TypeDefn, C) - Context,
> > +module_qualify_item(
> > +		type_defn(TVarSet, SymName, Params, TypeDefn0, C) - Context,
> > +		type_defn(TVarSet, SymName, Params, TypeDefn, C) - Context,
> >  		Info0, Info, yes) --> 
> > +	{ mq_info_get_types(Info0, Types0)  },
> >  	{ list__length(Params, Arity) },
> >  	{ mq_info_set_error_context(Info0,
> >  		type(SymName - Arity) - Context, Info1) },
> > -	qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info).  
> > +	qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info2),
> > +	{ mq_info_set_types(Info2, Types0, Info) }. 
> 
> I don't understand why you reset the types field to its old value there.
> A comment might help.

Fixed (it wasn't necessary).
 
> > @@ -1226,6 +1314,28 @@
> >  		mercury_output_bracketed_sym_name(ModuleName),
> >  		io__write_string("' has not been imported).\n")
> >  	;
> > +		{ MatchingModules = [_ | MatchingModules1] }
> > +	->
> > +		{ MatchingModules1 = [],
> > +			ModuleWord = "module ",
> > +			HasWord = "has"
> > +		; MatchingModules1 = [_|_],
> > +			ModuleWord = "modules ",
> > +			HasWord = "have"
> > +		},
> > +
> > +		io__write_string("\n"),
> > +		prog_out__write_context(Context),
> > +		io__write_string("  (the "),
> > +		io__write_string(ModuleWord),
> > +		io__write_string(" "),
> > +		prog_out__write_module_list(MatchingModules),
> > +		io__nl,
> > +		prog_out__write_context(Context),
> > +		io__write_string("  "),
> > +		io__write_string(HasWord),
> > +		io__write_string(" not been imported in the interface).\n")
> > +	;
> 
> That looks like it outputs two spaces after "module" or "modules",
> but I think it should only output one.
> 
> There should be a test case for both variations (singular and plural)
> of this new error message.

Done.

> > Index: compiler/module_qual.m
> > @@ -1418,6 +1528,10 @@
> >  	set__init(InterfaceModules0),
> >  	get_implicit_dependencies(Items, Globals, ImportDeps, UseDeps),
> >  	set__list_to_set(ImportDeps `list__append` UseDeps, ImportedModules),
> > +	set__insert_list(ImportedModules,
> > +		[ModuleName | get_ancestors(ModuleName)],
> > +		InterfaceVisibleModules),
> 
> Why do the ancestor modules need to get included in InterfaceVisibleModules
> here?

Because they are visible without an explicit import.
 
> > Index: compiler/modules.m
> > @@ -520,60 +523,114 @@
> >  		item_list, module_imports, module_error, io__state, io__state).
> >  :- mode grab_unqual_imported_modules(in, in, in, in, out, out, di, uo) is det.
> >  
> > -	% process_module_private_interfaces(Ancestors, DirectImports0,
> > -	%			DirectImports, DirectUses0, DirectUses,
> > -	%			Module0, Module):
> > +	% process_module_private_interfaces(Ancestors,
> > +	%	IntStatusItem, ImpStatusItem, DirectImports0, DirectImports,
> > +	%	DirectUses0, DirectUses, Module0, Module):
> 
> I suggest using state var notation here, i.e.

Done.
 
> 	% process_module_private_interfaces(Ancestors,
> 	%	IntStatusItem, ImpStatusItem, !DirectImports, !DirectUses,
> 	%	!Module):
> 
> > @@ -1422,6 +1484,139 @@
> > +:- pred strip_unnecessary_impl_defns(item_list::in, item_list::out) is det.
> > +
> > +strip_unnecessary_impl_defns(Items0,
> > +	promise_only_solution(strip_unnecessary_impl_defns_2(Items0))).
> 
> There should be a comment explaining why that promise is safe.

Done.

> > @@ -1782,7 +1979,7 @@
> >  
> >  update_interface_create_file(Msg, OutputFileName,
> >  			TmpOutputFileName, Succeeded) -->
> > -	globals__io_lookup_bool_option(verbose, Verbose),
> > +	globals__io_lookup_bool_option(verbose_make, Verbose),
> 
> I don't think that was mentioned in the log message.
> It appears to be unrelated to the rest of your changes
> and hence ideally should be committed separately (if at all).

Undone.

> > @@ -6509,6 +6839,43 @@
> >  include_in_short_interface(module_defn(_, _)).
> >  include_in_short_interface(instance(_, _, _, _, _, _)).
> >  
> > +:- func item_needs_imports(item) = bool.
> 
> A comment explaining the meaning of this function would be helpful.

Done.
 
> > +:- pred include_in_int_file_implementation(item).
> > +:- mode include_in_int_file_implementation(in) is semidet.
> > +
> > +include_in_int_file_implementation(type_defn(_, _, _, _, _)).
> > +include_in_int_file_implementation(module_defn(_, Defn)) :-
> > +	Defn \= external(_).
> > +include_in_int_file_implementation(typeclass(_, _, _, _, _)).
> 
> It would be nice to put a comment explaining why typeclass declarations
> need to be included, but instance declarations don't.

Done.

> > +++ compiler/prog_data.m	26 Nov 2003 08:46:41 -0000
> > @@ -56,8 +56,15 @@
> >  			cl_body			:: goal
> >  		)
> >  
> > -		% `:- type ...':
> > +		% `:- type ...' or `:- type_impl':
> >  		% a definition of a type, or a declaration of an abstract type.
> > +		% The compiler places `:- type_impl' declarations in `.int'
> > +		% and `.int2' files to propagate definitions of abstract
> > +		% foreign types and equivalence types which should not be
> > +		% visible to importing modules (and shouldn't be used when
> > +		% typechecking those modules), but which are necessary for
> > +		% code generation.  For examples the MS Common Language Runtime
> > +		% doesn't support equivalence types.
> >  	; 	type_defn(
> 
> Is the comment about ":- type_impl" correct?
> It doesn't match the description in the log message.

Fixed.
 
> > @@ -1234,6 +1233,11 @@
> >  		% `:- use_module', and items from `.opt'
> >  		% and `.int2' files. It also records from which
> >  		% section the module was imported.
> > +	;	abstract_imported
> > +		% This is used internally by the compiler,
> > +		% to identify items which originally
> > +		% came from the implementation section
> > +		% of an interface file.
> 
> It would be good to just mention here what implementation sections
> in interface files are for.

Done.
 
> >  	;	opt_imported
> >  		% This is used internally by the compiler,
> >  		% to identify items which originally
> > @@ -1270,7 +1274,8 @@
> >  :- type import_locn
> >  	--->	implementation
> >  	;	interface
> > -	;	ancestor.
> > +	;	ancestor
> > +	;	ancestor_private_interface.
> 
> It would be helpful to have a comment here explaining what that new
> alternative means.

Done.

> > Index: compiler/recompilation.usage.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/compiler/recompilation.usage.m,v
> > retrieving revision 1.10
> > diff -u -u -r1.10 recompilation.usage.m
> > --- compiler/recompilation.usage.m	24 Oct 2003 06:17:47 -0000	1.10
> > +++ compiler/recompilation.usage.m	26 Nov 2003 04:45:01 -0000
> > @@ -79,6 +79,7 @@
> >  %-----------------------------------------------------------------------------%
> >  :- implementation.
> >  
> > +:- import_module check_hlds.
> >  :- import_module check_hlds__type_util.
> >  :- import_module hlds__hlds_data.
> >  :- import_module hlds__hlds_out.
> 
> IMHO that declaration should go in recompilation.m
> rather than here and in recompilation.version.m.

Done.
 
> > +++ compiler/notes/compiler_design.html	24 Nov 2003 14:33:23 -0000
> > @@ -689,6 +689,20 @@
> >  
> >  (Is there any good reason why lambda.m comes after table_gen.m?)
> >  
> > +
> > +<p>
> > +
> > +Expansion of equivalence types (equiv_type_hlds.m)
> > +
> > +<ul>
> > +<li>
> > +	This pass expands equivalences which are not meant to
> > +	be visible to the user of imported modules.  This
> > +	is necessary for the IL back-end and in some cases
> > +	for `:- pragma export' involving foreign types on
> > +	the C back-end.
> > +</ul>
> 
> It's also needed by the MLDS->C back-end, for either --high-level-data,
> or for cases involving abstract equivalence types which are defined
> as "float".

Done.

> > @@ -104,17 +104,29 @@
> >  :- mode multi_map__values(in, out) is det.
> >  
> >  	% convert a multi_map to an association list
> > -:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K,list(V))).
> > +:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K, V)).
> >  :- mode multi_map__to_assoc_list(in, out) is det.
> 
> I don't think that this is worth breaking backwards compatibility for.
> The new predicate could be named e.g. multi_map__to_flat_assoc_list.
> If you think the old name is confusing, you could rename it and keep
> a version with the original name but use pragma obsolete to deprecate it.

See the separate change I posted and committed.

> > +++ tests/hard_coded/Mercury.options	28 Nov 2003 12:24:05 -0000
> > @@ -4,6 +4,7 @@
> >  MCFLAGS-constraint	=	--constraint-propagation --enable-termination
> >  MCFLAGS-constraint_order =	--constraint-propagation --enable-termination
> >  MCFLAGS-deforest_cc_bug =	--deforestation
> > +MCFLAGS-export_test2	=	--no-intermodule-optimization
> 
> Is that needed?  The test will normally run without intermodule optimization
> anyway.  Is there anything wrong with also testing it with intermodule
> optimization occaisionally?

OK.

> > +++ tests/invalid/missing_interface_import.err_exp	25 Nov 2003 15:48:55 -0000
> > @@ -1,9 +1,14 @@
> >  missing_interface_import.m:007: In definition of type `missing_interface_import.bar'/0:
> > -missing_interface_import.m:007:   error: undefined type `map'/2.
> > +missing_interface_import.m:007:   error: undefined type `map'/2
> > +missing_interface_import.m:007:   (the module  `map'
> > +missing_interface_import.m:007:   has not been imported in the interface).
> 
> s/module  `map'/module `map'/

Fixed.
 
> >  missing_interface_import.m:009: In definition of predicate `missing_interface_import.p'/1:
> >  missing_interface_import.m:009:   error: undefined type `std_util.univ'/0
> > -missing_interface_import.m:009:   (the module `std_util' has not been imported).
> > +missing_interface_import.m:009:   (the module  `std_util'
> > +missing_interface_import.m:009:   has not been imported in the interface).
> 
> Why is there a line wrap before the "has not been ..."?
> Is that deliberate, or accidental?

Fixed.

Simon.

reverted:
--- NEWS	28 Nov 2003 10:55:39 -0000
+++ NEWS	31 Oct 2003 03:27:13 -0000	1.320
@@ -55,11 +55,6 @@
 * exception.m now contains a predicate finally/6 which can be used to
   ensure that resources are released whether a called closure exits
   normally or throws an exception.
-* The behaviour of multi_map__to_assoc_list and multi_map.from_assoc_list
-  has changed to use assoc_lists where each key-value in the multi_map
-  has an entry in the assoc_list, rather than just and entry for each key.
-  The old behaviour is available using multi_map.to_multi_assoc_list
-  and multi_map.from_multi_assoc_list.
 
 Portability improvements:
 * Nothing yet.
@@ -149,12 +144,6 @@
 * exception.m now contains a predicate finally/6 which can be used to
   ensure that resources are released whether a called closure exits
   normally or throws an exception.
-
-* The behaviour of multi_map__to_assoc_list and multi_map.from_assoc_list
-  has changed to use assoc_lists where each key-value in the multi_map
-  has an entry in the assoc_list, rather than just and entry for each key.
-  The old behaviour is available using multi_map.to_multi_assoc_list
-  and multi_map.from_multi_assoc_list.
 
 * Several new functions have been added to the string module, namely
   elem/2, unsafe_elem/2, chomp/1, lstrip/1, lstrip/2, rstrip/1, rstrip/2,
diff -u compiler/hlds_out.m compiler/hlds_out.m
--- compiler/hlds_out.m
+++ compiler/hlds_out.m
@@ -3192,8 +3192,7 @@
 hlds_out__write_superclasses(Indent, SuperClassTable) -->
 	hlds_out__write_indent(Indent),
 	io__write_string("%-------- Super Classes --------\n"),
-	{ multi_map__to_multi_assoc_list(SuperClassTable,
-		SuperClassTableList) },
+	{ multi_map__to_assoc_list(SuperClassTable, SuperClassTableList) },
 	io__write_list(SuperClassTableList, "\n\n",
 		hlds_out__write_superclass(Indent)),
 	io__nl.
diff -u compiler/mercury_to_mercury.m compiler/mercury_to_mercury.m
--- compiler/mercury_to_mercury.m
+++ compiler/mercury_to_mercury.m
@@ -1756,12 +1756,10 @@
 :- pred mercury_output_begin_type_decl(is_solver_type, io__state, io__state).
 :- mode mercury_output_begin_type_decl(in, di, uo) is det.
 
-mercury_output_begin_type_decl(IsSolverType) -->
-	io__write_string(":- "),
-	( { IsSolverType = solver_type }, io__write_string("solver ")
-	; { IsSolverType = non_solver_type }
-	),
-	io__write_string("type ").
+mercury_output_begin_type_decl(solver_type) -->
+	io__write_string(":- solver type ").
+mercury_output_begin_type_decl(non_solver_type) -->
+	io__write_string(":- type ").
 
 :- pred mercury_output_equality_compare_preds(maybe(unify_compare)::in,
 		io__state::di, io__state::uo) is det.
diff -u compiler/module_qual.m compiler/module_qual.m
--- compiler/module_qual.m
+++ compiler/module_qual.m
@@ -396,6 +396,12 @@
 
 add_imports_2(Imports, !Info) :-
 	mq_info_get_import_status(!.Info, Status),
+
+	%
+	% Modules imported from the the private interface of ancestors of
+	% the current module are treated as if they were directly imported
+	% by the current module.
+	%
 	(
 		( Status = local 
 		; Status = exported
@@ -409,6 +415,10 @@
 		true
 	),
 
+	%
+	% We check that all modules imported in the interface are
+	% used in the interface.
+	%
 	(
 		Status = exported
 	->
@@ -421,6 +431,10 @@
 			true
 	),
 
+	%
+	% Only modules imported in the interface or in the private
+	% interface of ancestor modules may be used in the interface.
+	%
 	(
 		( Status = exported
 		; Status = imported(ancestor_private_interface)
@@ -589,12 +603,10 @@
 		type_defn(TVarSet, SymName, Params, TypeDefn0, C) - Context,
 		type_defn(TVarSet, SymName, Params, TypeDefn, C) - Context,
 		Info0, Info, yes) --> 
-	{ mq_info_get_types(Info0, Types0)  },
 	{ list__length(Params, Arity) },
 	{ mq_info_set_error_context(Info0,
 		type(SymName - Arity) - Context, Info1) },
-	qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info2),
-	{ mq_info_set_types(Info2, Types0, Info) }. 
+	qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info).
 
 module_qualify_item(inst_defn(A, SymName, Params, InstDefn0, C) - Context,
 		inst_defn(A, SymName, Params, InstDefn, C) - Context,
@@ -1318,21 +1330,17 @@
 	->
 		{ MatchingModules1 = [],
 			ModuleWord = "module ",
-			HasWord = "has"
+			HasWord = " has"
 		; MatchingModules1 = [_|_],
 			ModuleWord = "modules ",
-			HasWord = "have"
+			HasWord = " have"
 		},
 
 		io__write_string("\n"),
 		prog_out__write_context(Context),
 		io__write_string("  (the "),
 		io__write_string(ModuleWord),
-		io__write_string(" "),
 		prog_out__write_module_list(MatchingModules),
-		io__nl,
-		prog_out__write_context(Context),
-		io__write_string("  "),
 		io__write_string(HasWord),
 		io__write_string(" not been imported in the interface).\n")
 	;
@@ -1528,6 +1536,8 @@
 	set__init(InterfaceModules0),
 	get_implicit_dependencies(Items, Globals, ImportDeps, UseDeps),
 	set__list_to_set(ImportDeps `list__append` UseDeps, ImportedModules),
+
+	% Ancestor modules are visible without being explicitly imported.
 	set__insert_list(ImportedModules,
 		[ModuleName | get_ancestors(ModuleName)],
 		InterfaceVisibleModules),
diff -u compiler/modules.m compiler/modules.m
--- compiler/modules.m
+++ compiler/modules.m
@@ -524,8 +524,8 @@
 :- mode grab_unqual_imported_modules(in, in, in, in, out, out, di, uo) is det.
 
 	% process_module_private_interfaces(Ancestors,
-	%	IntStatusItem, ImpStatusItem, DirectImports0, DirectImports,
-	%	DirectUses0, DirectUses, Module0, Module):
+	%	IntStatusItem, ImpStatusItem, !DirectImports,
+	%	!DirectUses, !Module):
 	%
 	%  	Read the complete private interfaces for modules in Ancestors,
 	%	and append any imports/uses in the ancestors to the
@@ -1489,6 +1489,9 @@
 :- pred strip_unnecessary_impl_defns(item_list::in, item_list::out) is det.
 
 strip_unnecessary_impl_defns(Items0,
+	% strip_unnecessary_impl_defns_2 is cc_multi because of the
+	% call to std_util.unsorted_aggregate.  The order in which
+	% items are deleted from a multi_map does not matter.
 	promise_only_solution(strip_unnecessary_impl_defns_2(Items0))).
 
 :- pred strip_unnecessary_impl_defns_2(item_list::in,
@@ -1979,7 +1982,7 @@
 
 update_interface_create_file(Msg, OutputFileName,
 			TmpOutputFileName, Succeeded) -->
-	globals__io_lookup_bool_option(verbose_make, Verbose),
+	globals__io_lookup_bool_option(verbose, Verbose),
 	maybe_write_string(Verbose, "% `"),
 	maybe_write_string(Verbose, OutputFileName),
 	maybe_write_string(Verbose, "' has "),
@@ -6839,6 +6842,7 @@
 include_in_short_interface(module_defn(_, _)).
 include_in_short_interface(instance(_, _, _, _, _, _)).
 
+	% Could this item use items from imported modules.
 :- func item_needs_imports(item) = bool.
 
 item_needs_imports(clause(_, _, _, _, _)) = yes.
@@ -6874,6 +6878,11 @@
 include_in_int_file_implementation(type_defn(_, _, _, _, _)).
 include_in_int_file_implementation(module_defn(_, Defn)) :-
 	Defn \= external(_).
+
+	% `:- typeclass declarations' may be referred to
+	% by the constructors in type declarations.
+	% Since these constructors are abstractly exported,
+	% we won't need the local instance declarations. 
 include_in_int_file_implementation(typeclass(_, _, _, _, _)).
 
 :- pred make_abstract_defn(item, short_interface_kind, item).
diff -u compiler/prog_data.m compiler/prog_data.m
--- compiler/prog_data.m
+++ compiler/prog_data.m
@@ -56,15 +56,8 @@
 			cl_body			:: goal
 		)
 
-		% `:- type ...' or `:- type_impl':
+		% `:- type ...':
 		% a definition of a type, or a declaration of an abstract type.
-		% The compiler places `:- type_impl' declarations in `.int'
-		% and `.int2' files to propagate definitions of abstract
-		% foreign types and equivalence types which should not be
-		% visible to importing modules (and shouldn't be used when
-		% typechecking those modules), but which are necessary for
-		% code generation.  For examples the MS Common Language Runtime
-		% doesn't support equivalence types.
 	; 	type_defn(
 			td_tvarset		:: tvarset,
 			td_ctor_name		:: sym_name,
@@ -1237,7 +1230,10 @@
 		% This is used internally by the compiler,
 		% to identify items which originally
 		% came from the implementation section
-		% of an interface file.
+		% of an interface file; usually type
+		% declarations (especially equivalence types)
+		% which should be used in code generation
+		% but not in type checking.
 	;	opt_imported
 		% This is used internally by the compiler,
 		% to identify items which originally
@@ -1271,11 +1267,22 @@
 	--->	implementation
 	;	interface.
 
+	% An import_locn is used to describe the place where an item was
+	% imported from.
 :- type import_locn
-	--->	implementation
+	--->
+		% The item is from a module imported in the implementation.
+		implementation
+
+		% The item is from a module imported in the interface.
 	;	interface
+
+		% The item is from a module imported by an ancestor.
 	;	ancestor
-	;	ancestor_private_interface.
+
+		% The item is from the private interface of an ancestor module.
+	;	ancestor_private_interface
+	.
 
 :- type sym_list	
 	--->	sym(list(sym_specifier))
reverted:
--- compiler/recompilation.usage.m	26 Nov 2003 04:45:01 -0000
+++ compiler/recompilation.usage.m	24 Oct 2003 06:17:47 -0000	1.10
@@ -79,7 +79,6 @@
 %-----------------------------------------------------------------------------%
 :- implementation.
 
-:- import_module check_hlds.
 :- import_module check_hlds__type_util.
 :- import_module hlds__hlds_data.
 :- import_module hlds__hlds_out.
diff -u compiler/recompilation.version.m compiler/recompilation.version.m
--- compiler/recompilation.version.m
+++ compiler/recompilation.version.m
@@ -36,7 +36,6 @@
 %-----------------------------------------------------------------------------%
 :- implementation.
 
-:- import_module check_hlds.
 :- import_module check_hlds__mode_util.
 :- import_module check_hlds__type_util.
 :- import_module hlds__hlds_out.
diff -u compiler/notes/compiler_design.html compiler/notes/compiler_design.html
--- compiler/notes/compiler_design.html
+++ compiler/notes/compiler_design.html
@@ -701,6 +701,12 @@
 	is necessary for the IL back-end and in some cases
 	for `:- pragma export' involving foreign types on
 	the C back-end.
+
+	<p>
+
+	It's also needed by the MLDS->C back-end, for
+	--high-level-data, and for cases involving abstract
+	equivalence types which are defined as "float".
 </ul>
 
 <p>
reverted:
--- library/multi_map.m	24 Nov 2003 14:33:23 -0000
+++ library/multi_map.m	26 May 2003 09:00:30 -0000	1.10
@@ -104,29 +104,17 @@
 :- mode multi_map__values(in, out) is det.
 
 	% convert a multi_map to an association list
+:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K,list(V))).
-:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K, V)).
 :- mode multi_map__to_assoc_list(in, out) is det.
 
 	% convert an association list to a multi_map
+:- pred multi_map__from_assoc_list(assoc_list(K,list(V)), multi_map(K,V)).
-:- pred multi_map__from_assoc_list(assoc_list(K, V), multi_map(K,V)).
 :- mode multi_map__from_assoc_list(in, out) is det.
 
-	% convert a multi_map to an association list, with all the
-	% values for each key in one element of the association list.
-:- pred multi_map__to_multi_assoc_list(multi_map(K, V),
-		assoc_list(K, list(V))).
-:- mode multi_map__to_multi_assoc_list(in, out) is det.
-
-	% convert an association list with all the values for each
-	% key in one element of the list to a multi_map
-:- pred multi_map__from_multi_assoc_list(assoc_list(K, list(V)),
-		multi_map(K,V)).
-:- mode multi_map__from_multi_assoc_list(in, out) is det.
-
 	% convert a sorted association list to a multi_map
+:- pred multi_map__from_sorted_assoc_list(assoc_list(K, list(V)), 
+			multi_map(K, V)).
+:- mode multi_map__from_sorted_assoc_list(in, out) is det.
-:- pred multi_map__from_sorted_multi_assoc_list(assoc_list(K, list(V)), 
-		multi_map(K, V)).
-:- mode multi_map__from_sorted_multi_assoc_list(in, out) is det.
 
 	% delete a key and data from a multi_map
 	% if the key is not present, leave the multi_map unchanged
@@ -264,31 +252,15 @@
 	map__values(MultiMap, KeyList0),
 	list__condense(KeyList0, KeyList).
 
-multi_map__from_assoc_list(AList, MultiMap) :-
-	MultiMap = list__foldl(
-		(func(Key - Value, Map0) = Map  :-
-			multi_map__set(Map0, Key, Value, Map)
-		),
-		AList, map__init).
-
 multi_map__to_assoc_list(MultiMap, AList) :-
+	map__to_assoc_list(MultiMap, AList).
-	AList = list__reverse(map__foldl(
-		(func(Key, Values, AL) =
-			list__reverse(
-				list__map((func(Value) = Key - Value), Values)
-			) ++ AL
-		),
-		MultiMap, [])).
 
+multi_map__from_assoc_list(AList, MultiMap) :-
-multi_map__from_multi_assoc_list(AList, MultiMap) :-
 	map__from_assoc_list(AList, MultiMap).
 
+multi_map__from_sorted_assoc_list(AList, MultiMap) :-
-multi_map__from_sorted_multi_assoc_list(AList, MultiMap) :-
 	map__from_sorted_assoc_list(AList, MultiMap).
 
-multi_map__to_multi_assoc_list(MultiMap, AList) :-
-	map__to_assoc_list(MultiMap, AList).
-
 multi_map__delete(MultiMap0, Key, MultiMap) :-
 	map__delete(MultiMap0, Key, MultiMap).
 
@@ -334,8 +306,18 @@
 	% XXX inefficient
 
 multi_map__inverse_search(MultiMap, Value, Key) :-
+	map__to_assoc_list(MultiMap, AssocList),
+	multi_map__assoc_list_member(Value, AssocList, Key).
+
+:- pred multi_map__assoc_list_member(Value, assoc_list(Key, list(Value)), Key).
+:- mode multi_map__assoc_list_member(in, in, out) is nondet.
+multi_map__assoc_list_member(Value, [(AKey - AValues) | AList], Key) :-
+	(
+		list__member(Value, AValues),
+		Key = AKey
+	;
+		multi_map__assoc_list_member(Value, AList, Key)
+	).
-	map__member(MultiMap, Key, ValueList),
-	list__member(Value, ValueList).
 
 %-----------------------------------------------------------------------------%
 
@@ -368,10 +350,10 @@
 %-----------------------------------------------------------------------------%
 
 multi_map__merge(M0, M1, M) :-
+	multi_map__to_assoc_list(M0, ML0),
+	multi_map__to_assoc_list(M1, ML1),
-	multi_map__to_multi_assoc_list(M0, ML0),
-	multi_map__to_multi_assoc_list(M1, ML1),
 	multi_map__assoc_list_merge(ML0, ML1, ML),
+	multi_map__from_sorted_assoc_list(ML, M).
-	multi_map__from_sorted_multi_assoc_list(ML, M).
 
 :- pred multi_map__assoc_list_merge(assoc_list(K, list(V)), 
 		assoc_list(K, list(V)), assoc_list(K, list(V))).
reverted:
--- tests/hard_coded/Mercury.options	28 Nov 2003 12:24:05 -0000
+++ tests/hard_coded/Mercury.options	22 Jul 2003 07:04:26 -0000	1.7
@@ -4,7 +4,6 @@
 MCFLAGS-constraint	=	--constraint-propagation --enable-termination
 MCFLAGS-constraint_order =	--constraint-propagation --enable-termination
 MCFLAGS-deforest_cc_bug =	--deforestation
-MCFLAGS-export_test2	=	--no-intermodule-optimization
 MCFLAGS-lp		=	--intermodule-optimization -O3
 MCFLAGS-boyer		=	--infer-all
 MCFLAGS-float_consistency =	--optimize-constant-propagation
diff -u tests/hard_coded/export_test2.exp tests/invalid/missing_interface_import3.m
--- tests/hard_coded/export_test2.exp
+++ tests/invalid/missing_interface_import3.m
@@ -1 +1,4 @@
-42
+:- module missing_interface_import3.
+:- interface.
+
+:- type key == int.
diff -u tests/hard_coded/export_test2.m tests/invalid/missing_interface_import3.m
--- tests/hard_coded/export_test2.m
+++ tests/invalid/missing_interface_import3.m
@@ -1,50 +1,4 @@
-:- module export_test2.
-
+:- module missing_interface_import3.
 :- interface.
 
-:- import_module int, io.
-
-:- pred main(io__state::di, io__state::uo) is det.
-
-:- pred foo(io__output_stream::in, io__output_stream::out,
-		int::in, int::out) is det.
-
-:- pred bar(io__output_stream::in, io__output_stream::out,
-		int::in, int::out) is det.
-
-
-:- implementation.
-
-main -->
-	io__stdout_stream(Stream0),
-	{ bar(Stream0, Stream, 41, X) },
-	io__write(Stream, X),
-	io__write_char(Stream, '\n').
-
-foo(S, S, X, X+1).
-
-:- pragma foreign_decl("C",
-"#include ""mercury_library_types.h""
-
-/*
-** Make sure the foreign type definition of io__input_stream
-** is available here.  If it is not, the automatically generated
-** definition of foo() will be
-**	void foo(MR_Word, MR_Word *, MR_Integer, MR_Integer *);
-*/
-void foo(MercuryFilePtr, MercuryFilePtr *, MR_Integer, MR_Integer *);
-
-").
-
-
-:- pragma export(foo(in, out, in, out), "foo").
-
-:- pragma foreign_proc("C", bar(S::in, T::out, X::in, Y::out),
-		[may_call_mercury, promise_pure],
-"
-	foo(S, &T, X, &Y);
-").
-:- pragma foreign_proc("C#", bar(S::in, T::out, X::in, Y::out),
-		[may_call_mercury, promise_pure], "
-	export_test2.mercury_code.foo(S, ref T, X, ref Y);
-").
+:- type key == int.
diff -u tests/invalid/Mmakefile tests/invalid/Mmakefile
--- tests/invalid/Mmakefile
+++ tests/invalid/Mmakefile
@@ -21,6 +21,7 @@
 	ho_default_func_2.sub \
 	import_in_parent \
 	imported_mode \
+	missing_interface_import2 \
 	missing_parent_import \
 	partial_implied_mode \
 	sub_c \
@@ -87,7 +88,6 @@
 	method_impl \
 	missing_det_decls \
 	missing_interface_import \
-	missing_interface_import2 \
 	mode_inf \
 	modes_erroneous \
 	mostly_uniq1 \
diff -u tests/invalid/missing_interface_import2.err_exp tests/invalid/missing_interface_import3.m
--- tests/invalid/missing_interface_import2.err_exp
+++ tests/invalid/missing_interface_import3.m
@@ -1,10 +1,4 @@
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007:   error: undefined type `io.state'/0
-missing_interface_import2.m:007:   (the module  `io'
-missing_interface_import2.m:007:   has not been imported in the interface).
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007:   error: undefined type `io.state'/0
-missing_interface_import2.m:007:   (the module  `io'
-missing_interface_import2.m:007:   has not been imported in the interface).
-`missing_interface_import2.int' not written.
-For more information, try recompiling with `-E'.
+:- module missing_interface_import3.
+:- interface.
+
+:- type key == int.
diff -u tests/invalid/missing_interface_import2.err_exp2 tests/invalid/missing_interface_import3.m
--- tests/invalid/missing_interface_import2.err_exp2
+++ tests/invalid/missing_interface_import3.m
@@ -1,10 +1,4 @@
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007:   error: undefined type `io.state'/0
-missing_interface_import2.m:007:   (the module  `io'
-missing_interface_import2.m:007:   has not been imported in the interface).
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007:   error: undefined type `io.state'/0
-missing_interface_import2.m:007:   (the module  `io'
-missing_interface_import2.m:007:   has not been imported in the interface).
-`Mercury/ints/missing_interface_import2.int' not written.
-For more information, try recompiling with `-E'.
+:- module missing_interface_import3.
+:- interface.
+
+:- type key == int.
diff -u tests/invalid/missing_interface_import2.m tests/invalid/missing_interface_import3.m
--- tests/invalid/missing_interface_import2.m
+++ tests/invalid/missing_interface_import3.m
@@ -1,11 +1,4 @@
-:- module missing_interface_import2.
-
-:- import_module io.
-
+:- module missing_interface_import3.
 :- interface.
 
-:- pred main(io__state::di, io__state::uo) is det.
-
-main -->
-	io__write_string("ok\n").
-
+:- type key == int.
only in patch2:
--- compiler/recompilation.m	15 Mar 2003 03:09:08 -0000	1.7
+++ compiler/recompilation.m	30 Nov 2003 11:36:25 -0000
@@ -24,6 +24,7 @@
 
 :- interface.
 
+:- import_module check_hlds.
 :- import_module hlds.
 :- import_module libs.
 :- import_module parse_tree.
--------------------------------------------------------------------------
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