[m-dev.] for review: constrain interface assertions to using interface symbols

Peter Ross petdr at cs.mu.OZ.AU
Thu Nov 11 12:42:47 AEDT 1999


Hi,

This is for Fergus to review.
I assume that this counts as a bug fix and can go in despite the feature
freeze.


===================================================================


Estimated hours taken: 24

Assertion declarations in the interface must not contain any symbols from
modules imported only in the implementation.  This constraint requires
that each imported symbol be annotated with whether it is imported from
the interface or implementation.

compiler/prog_data.m:
    Update the pseudo declaration `:- imported' to include which section
    (either implementation or interface) the items following it where
    imported from.

compiler/modules.m:
    Add a new version of get_dependencies, which divides the modules up
    into those imported in the interface and implementation.
    Use the new version of get_dependencies to place the new form of
    `:- imported' declarations at the start of items from different
    sections.
    
compiler/hlds_pred.m:
    Add a new field to the imported data constructor in the type
    import_status, which records in which section the symbol was
    imported in.

compiler/make_hlds.m:
    Modify module_defn_update_import_status so that it now records from
    which section a symbol is imported.

compiler/module_qual.m:
    Any unqualified symbol in an assertion might come from *any*
    of the imported modules, so turn off the warning about modules which
    are imported in the interface but not used.

compiler/accumulator.m:
    Use where a symbol is imported from when deciding whether an
    assertion in the interface is valid.

compiler/dead_proc_elim.m:
compiler/higher_order.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/unused_args.m:
    Updates to use the new form of the data constructor imported.


Index: assertion.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/assertion.m,v
retrieving revision 1.3
diff -u -r1.3 assertion.m
--- assertion.m	1999/10/25 03:48:37	1.3
+++ assertion.m	1999/11/11 01:01:53
@@ -480,8 +480,9 @@
 is_defined_in_implementation_section(abstract_exported, yes).
 is_defined_in_implementation_section(exported_to_submodules, yes).
 is_defined_in_implementation_section(local, yes).
-is_defined_in_implementation_section(imported, yes).
+is_defined_in_implementation_section(imported(implementation), yes).
 
+is_defined_in_implementation_section(imported(interface), no).
 is_defined_in_implementation_section(opt_imported, no).
 is_defined_in_implementation_section(abstract_imported, no).
 is_defined_in_implementation_section(pseudo_imported, no).
Index: dead_proc_elim.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.50
diff -u -r1.50 dead_proc_elim.m
--- dead_proc_elim.m	1999/10/25 03:48:41	1.50
+++ dead_proc_elim.m	1999/10/26 06:53:38
@@ -569,7 +569,8 @@
 			)),
 		list__foldl(DestroyGoal, ProcIds, ProcTable0, ProcTable),
 		pred_info_set_procedures(PredInfo0, ProcTable, PredInfo1),
-		pred_info_set_import_status(PredInfo1, imported, PredInfo),
+		pred_info_set_import_status(PredInfo1, imported(interface),
+				PredInfo),
 		map__det_update(PredTable0, PredId, PredInfo, PredTable),
 		globals__io_lookup_bool_option(very_verbose, VeryVerbose,
 			State0, State1),
Index: higher_order.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/higher_order.m,v
retrieving revision 1.58
diff -u -r1.58 higher_order.m
--- higher_order.m	1999/10/25 03:48:51	1.58
+++ higher_order.m	1999/10/26 07:18:39
@@ -1091,7 +1091,7 @@
 			% If we don't have clauses for the callee, we can't
 			% specialize any higher-order arguments. We may be
 			% able to do user guided type specialization.
-			CalleeStatus \= imported,
+			CalleeStatus \= imported(_),
 			type_is_higher_order(CalleeArgType, _, _, _)
 		;
 			true
Index: hlds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_out.m,v
retrieving revision 1.229
diff -u -r1.229 hlds_out.m
--- hlds_out.m	1999/11/09 01:07:05	1.229
+++ hlds_out.m	1999/11/10 04:26:32
@@ -2207,8 +2207,10 @@
 	io__write_string("abstract_exported").
 hlds_out__write_import_status(pseudo_exported) -->
 	io__write_string("pseudo_exported").
-hlds_out__write_import_status(imported) -->
-	io__write_string("imported").
+hlds_out__write_import_status(imported(interface)) -->
+	io__write_string("imported in the interface").
+hlds_out__write_import_status(imported(implementation)) -->
+	io__write_string("imported in the implementation").
 hlds_out__write_import_status(abstract_imported) -->
 	io__write_string("abstract_imported").
 hlds_out__write_import_status(opt_imported) -->
Index: hlds_pred.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_pred.m,v
retrieving revision 1.66
diff -u -r1.66 hlds_pred.m
--- hlds_pred.m	1999/10/15 03:44:49	1.66
+++ hlds_pred.m	1999/10/27 04:48:20
@@ -231,7 +231,8 @@
 	% Only types can have status abstract_exported or abstract_imported.
 
 :- type import_status
-	--->	imported	% defined in the interface of some other module
+	--->	imported(section)
+				% defined in the interface of some other module
 				% or `external' (in some other language)
 	;	opt_imported	% defined in the optimization 
 				% interface of another module
@@ -704,7 +705,7 @@
 
 invalid_proc_id(-1).
 
-status_is_exported(imported,			no).
+status_is_exported(imported(_),			no).
 status_is_exported(abstract_imported,		no).
 status_is_exported(pseudo_imported,		no).
 status_is_exported(opt_imported,		no).
@@ -718,7 +719,7 @@
 	status_defined_in_this_module(Status, InThisModule),
 	bool__not(InThisModule, Imported).
 
-status_defined_in_this_module(imported,			no).
+status_defined_in_this_module(imported(_),		no).
 status_defined_in_this_module(abstract_imported,	no).
 status_defined_in_this_module(pseudo_imported,		no).
 status_defined_in_this_module(opt_imported,		no).
@@ -862,7 +863,7 @@
 
 pred_info_non_imported_procids(PredInfo, ProcIds) :-
 	pred_info_import_status(PredInfo, ImportStatus),
-	( ImportStatus = imported ->
+	( ImportStatus = imported(_) ->
 		ProcIds = []
 	; ImportStatus = pseudo_imported ->
 		pred_info_procids(PredInfo, ProcIds0),
@@ -943,7 +944,7 @@
 				_, _, _, _, _, _, _, _, _).
 
 pred_info_is_imported(PredInfo) :-
-	pred_info_import_status(PredInfo, imported).
+	pred_info_import_status(PredInfo, imported(_)).
 
 pred_info_is_pseudo_imported(PredInfo) :-
 	pred_info_import_status(PredInfo, ImportStatus),
@@ -974,8 +975,8 @@
 pred_info_mark_as_external(PredInfo0, PredInfo) :-
 	PredInfo0 = predicate(A, B, C, D, E, F, G, H, I, _, K, L, M, N, O, P,
 		Q, R, S, T, U, V),
-	PredInfo  = predicate(A, B, C, D, E, F, G, H, I, imported, K, L, M, 
-		N, O, P, Q, R, S, T, U, V).
+	PredInfo  = predicate(A, B, C, D, E, F, G, H, I, imported(interface),
+		K, L, M, N, O, P, Q, R, S, T, U, V).
 
 pred_info_set_import_status(PredInfo0, Status, PredInfo) :-
 	PredInfo0 = predicate(A, B, C, D, E, F, G, H, I, _, K, L, M, N, O, P,
Index: intermod.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/intermod.m,v
retrieving revision 1.73
diff -u -r1.73 intermod.m
--- intermod.m	1999/11/09 01:07:04	1.73
+++ intermod.m	1999/11/10 04:26:33
@@ -655,7 +655,7 @@
 		{ set__insert(PredDecls0, PredId, PredDecls) },
 		intermod_info_set_pred_decls(PredDecls)
 	;
-		{ Status = imported
+		{ Status = imported(_)
 		; Status = opt_imported
 		}
 	->
@@ -880,7 +880,7 @@
 			{ set__insert(ModesToExport0, ModeId,
 							ModesToExport) },
 			intermod_info_set_modes(ModesToExport) 
-		; { Status = imported } ->
+		; { Status = imported(_) } ->
 			(
 				{ Name = qualified(Module, _) },
 				intermod_info_get_modules(Modules0),
@@ -924,7 +924,7 @@
 			{ set__insert(InstsToExport0, InstId,
 							InstsToExport) },
 			intermod_info_set_insts(InstsToExport)
-		; { Status = imported } ->
+		; { Status = imported(_) } ->
 			( { Name = qualified(Module, _) } ->
 				intermod_info_get_modules(Modules0),
 				{ set__insert(Modules0, Module, Modules) },
Index: make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.312
diff -u -r1.312 make_hlds.m
--- make_hlds.m	1999/10/29 07:17:57	1.312
+++ make_hlds.m	1999/11/10 04:26:34
@@ -562,11 +562,11 @@
 		item_status(local, may_be_unqualified)).
 module_defn_update_import_status(private_interface,
 		item_status(exported_to_submodules, may_be_unqualified)).
-module_defn_update_import_status(imported, 
-		item_status(imported, may_be_unqualified)).
-module_defn_update_import_status(used, 
-		item_status(imported, must_be_qualified)).
-module_defn_update_import_status(opt_imported, 
+module_defn_update_import_status(imported(Section),
+		item_status(imported(Section), may_be_unqualified)).
+module_defn_update_import_status(used(Section),
+		item_status(imported(Section), must_be_qualified)).
+module_defn_update_import_status(opt_imported,
 		item_status(opt_imported, must_be_qualified)).
 
 %-----------------------------------------------------------------------------%
@@ -581,7 +581,7 @@
 
 maybe_enable_aditi_compilation(Status, Context, Module0, Module) -->
 	{ Status = item_status(ItemStatus, _) },
-	( { ItemStatus \= imported } ->
+	( { ItemStatus \= imported(_) } ->
 		globals__io_lookup_bool_option(aditi, Aditi),
 		( { Aditi = no } ->
 			prog_out__write_context(Context),
@@ -1863,7 +1863,7 @@
 make_status_abstract(Status, AbstractStatus) :-
 	( Status = exported ->
 		AbstractStatus = abstract_exported
-	; Status = imported ->
+	; Status = imported(_) ->
 		AbstractStatus = abstract_imported
 	;
 		AbstractStatus = Status
@@ -1882,7 +1882,7 @@
 :- pred combine_status_2(import_status, import_status, import_status).
 :- mode combine_status_2(in, in, out) is semidet.
 
-combine_status_2(imported, Status2, Status) :-
+combine_status_2(imported(_), Status2, Status) :-
 	combine_status_imported(Status2, Status).
 combine_status_2(local, Status2, Status) :-
 	combine_status_local(Status2, Status).
@@ -1897,17 +1897,17 @@
 :- pred combine_status_imported(import_status, import_status).
 :- mode combine_status_imported(in, out) is semidet.
 
-combine_status_imported(imported,	imported).
-combine_status_imported(local,		imported).
-combine_status_imported(exported,	exported).
-combine_status_imported(opt_imported,	opt_imported).
-combine_status_imported(abstract_imported, imported).
-combine_status_imported(abstract_exported, abstract_exported).
+combine_status_imported(imported(Section),	imported(Section)).
+combine_status_imported(local,			imported(implementation)).
+combine_status_imported(exported,		exported).
+combine_status_imported(opt_imported,		opt_imported).
+combine_status_imported(abstract_imported,	imported(interface)).
+combine_status_imported(abstract_exported,	abstract_exported).
 
 :- pred combine_status_local(import_status, import_status).
 :- mode combine_status_local(in, out) is semidet.
 
-combine_status_local(imported,		local).
+combine_status_local(imported(_),	local).
 combine_status_local(local,		local).
 combine_status_local(exported,		exported).
 combine_status_local(opt_imported,	local).
@@ -1928,8 +1928,8 @@
 :- mode combine_status_abstract_imported(in, out) is det.
 
 combine_status_abstract_imported(Status2, Status) :-
-	( Status2 = imported ->
-		Status = imported
+	( Status2 = imported(Section) ->
+		Status = imported(Section)
 	;
 		Status = abstract_imported
 	).
@@ -2056,7 +2056,7 @@
 	% that the compiler doesn't look for clauses for other preds read in
 	% from optimization interfaces.
 	{ Status = opt_imported ->
-		DeclStatus = imported
+		DeclStatus = imported(interface)
 	;
 		DeclStatus = Status
 	},
@@ -2099,7 +2099,7 @@
 	% Only funcs with opt_imported clauses are tagged as opt_imported, so
 	% that the compiler doesn't look for clauses for other preds.
 	{ Status = opt_imported ->
-		DeclStatus = imported
+		DeclStatus = imported(interface)
 	;
 		DeclStatus = Status
 	},
@@ -2577,7 +2577,7 @@
 	map__lookup(Preds0, PredId, PredInfo0),
 	% if the type was imported, then the special preds for that
 	% type should be imported too
-	( (Status = imported ; Status = pseudo_imported) ->
+	( (Status = imported(_) ; Status = pseudo_imported) ->
 		pred_info_set_import_status(PredInfo0, Status, PredInfo1)
 	;
 		PredInfo1 = PredInfo0
@@ -2648,7 +2648,7 @@
 
 adjust_special_pred_status(Status0, SpecialPredId, Status) :-
 	( ( Status0 = opt_imported ; Status0 = abstract_imported ) ->
-		Status1 = imported
+		Status1 = imported(interface)
 	; Status0 = abstract_exported ->
 		Status1 = exported
 	;
@@ -2658,7 +2658,7 @@
 	% unification predicates are special - they are 
 	% "pseudo"-imported/exported (only mode 0 is imported/exported).
 	( SpecialPredId = unify ->
-		( Status1 = imported ->
+		( Status1 = imported(_) ->
 			Status = pseudo_imported
 		; Status1 = exported ->
 			Status = pseudo_exported
Index: module_qual.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/module_qual.m,v
retrieving revision 1.51
diff -u -r1.51 module_qual.m
--- module_qual.m	1999/10/04 04:04:43	1.51
+++ module_qual.m	1999/11/10 23:36:34
@@ -198,7 +198,18 @@
 collect_mq_info_2(pred_mode(_,_,_,_,_), Info, Info).
 collect_mq_info_2(func_mode(_,_,_,_,_,_), Info, Info).
 collect_mq_info_2(pragma(_), Info, Info).
-collect_mq_info_2(assertion(_, _), Info, Info).
+collect_mq_info_2(assertion(_, _), Info0, Info) :-
+	% Any unqualified symbol in the assertion might come from *any*
+	% of the imported modules.
+	% There's no way for us to tell which ones.
+	% So we conservatively assume that it uses all of them.
+	% XXX a better solution would be to only make this assumption if
+	% the assertion contains an unqualified symbol, however since
+	% the structure isn't in superhomogenous form yet processing the
+	% goal is complicated.
+	set__init(UnusedInterfaceModules),
+	mq_info_set_unused_interface_modules(Info0, UnusedInterfaceModules,
+		Info).
 collect_mq_info_2(nothing, Info, Info).
 collect_mq_info_2(typeclass(_, Name, Vars, _, _), Info0, Info) :-
 	add_typeclass_defn(Name, Vars, Info0, Info).
@@ -277,10 +288,10 @@
 	mq_info_set_import_status(Info0, not_exported, Info).
 process_module_defn(implementation, Info0, Info) :-
 	mq_info_set_import_status(Info0, not_exported, Info).
-process_module_defn(imported, Info0, Info) :-
+process_module_defn(imported(_), Info0, Info) :-
 	mq_info_set_import_status(Info0, not_exported, Info1),
 	mq_info_set_need_qual_flag(Info1, may_be_unqualified, Info).
-process_module_defn(used, Info0, Info) :-
+process_module_defn(used(_), Info0, Info) :-
 	mq_info_set_import_status(Info0, not_exported, Info1),
 	mq_info_set_need_qual_flag(Info1, must_be_qualified, Info).
 process_module_defn(opt_imported, Info0, Info) :-
@@ -452,8 +463,8 @@
 	mq_info_set_import_status(Info0, not_exported, Info).
 update_import_status(private_interface, Info0, Info, yes) :-
 	mq_info_set_import_status(Info0, not_exported, Info).
-update_import_status(imported, Info, Info, no).
-update_import_status(used, Info, Info, no).
+update_import_status(imported(_), Info, Info, no).
+update_import_status(used(_), Info, Info, no).
 update_import_status(external(_), Info, Info, yes).
 update_import_status(end_module(_), Info, Info, yes).
 update_import_status(export(_), Info, Info, yes).
Index: modules.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modules.m,v
retrieving revision 1.110
diff -u -r1.110 modules.m
--- modules.m	1999/10/21 14:36:31	1.110
+++ modules.m	1999/11/11 00:09:48
@@ -347,7 +347,8 @@
 	%	(unless they've already been read in) and any
 	%	modules that those modules import (transitively),
 	%	from files with filename extension Ext.
-	%	Put them all in a `:- used.' section.
+	%	Put them all in a `:- used.' section, where the section
+	%	is assumed to be in the interface.
 	%
 :- pred process_module_indirect_imports(list(module_name), string,
 		module_imports, module_imports, io__state, io__state).
@@ -783,9 +784,9 @@
 strip_imported_items([], Items0, Items) :-
 	list__reverse(Items0, Items). 
 strip_imported_items([Item - Context | Rest], Items0, Items) :-
-	( Item = module_defn(_, imported) ->
+	( Item = module_defn(_, imported(_)) ->
 		list__reverse(Items0, Items)
-	; Item = module_defn(_, used) ->
+	; Item = module_defn(_, used(_)) ->
 		list__reverse(Items0, Items)
 	;
 		strip_imported_items(Rest, [Item - Context | Items0], Items)
@@ -1059,14 +1060,21 @@
 		% Find out which modules this one depends on
 		%
 	{ get_ancestors(ModuleName, AncestorModules) },
-	{ get_dependencies(Items0, ImportedModules0, UsedModules0) },
+	{ get_dependencies(Items0, IntImportedModules0, IntUsedModules0,
+			ImpImportedModules0, ImpUsedModules0) },
 
+	{ list__append(IntImportedModules0, ImpImportedModules0,
+			ImportedModules0) },
+	{ list__append(IntUsedModules0, ImpUsedModules0, UsedModules0) },
+
 	warn_if_import_self_or_ancestor(ModuleName, AncestorModules,
 		ImportedModules0, UsedModules0),
 
 	warn_if_duplicate_use_import_decls(ModuleName,
-		ImportedModules0, ImportedModules1,
-		UsedModules0, UsedModules1),
+			IntImportedModules0, IntImportedModules1, 
+			IntUsedModules0, IntUsedModules1, 
+			ImpImportedModules0, ImpImportedModules, 
+			ImpUsedModules0, ImpUsedModules),
 
 	{ get_fact_table_dependencies(Items0, FactDeps) },
 	{ get_interface(Items0, no, InterfaceItems) },
@@ -1094,32 +1102,45 @@
 		% We add a pseudo-declarations `:- imported' at the end
 		% of the item list. Uses of the items with declarations 
 		% following this do not need module qualifiers.
-	{ append_pseudo_decl(Module1, imported, Module2) },
+	{ append_pseudo_decl(Module1, imported(interface), Module2) },
 
 		% Add `builtin' and `private_builtin' to the
 		% list of imported modules
-	{ add_implicit_imports(ImportedModules1, UsedModules1,
-			ImportedModules2, UsedModules2) },
+	{ add_implicit_imports(IntImportedModules1, IntUsedModules1,
+			IntImportedModules2, IntUsedModules2) },
 
 		% Process the ancestor modules
 	process_module_private_interfaces(AncestorModules,
-		ImportedModules2, ImportedModules, UsedModules2, UsedModules,
+		IntImportedModules2, IntImportedModules,
+		IntUsedModules2, IntUsedModules,
 		Module2, Module3),
 
 		% Process the modules imported using `import_module'.
-	{ IndirectImports0 = [] },
-	process_module_long_interfaces(ImportedModules, ".int",
-		IndirectImports0, IndirectImports1, Module3, Module4),
+	{ IntIndirectImports0 = [] },
+	process_module_long_interfaces(IntImportedModules, ".int",
+		IntIndirectImports0, IntIndirectImports1, Module3, Module3a),
+
+	{ append_pseudo_decl(Module3a, imported(implementation), Module3b) },
+
+	{ ImpIndirectImports0 = [] },
+	process_module_long_interfaces(ImpImportedModules, ".int",
+		ImpIndirectImports0, ImpIndirectImports1, Module3b, Module4),
 
 		% Process the modules imported using `use_module' 
 		% and the short interfaces for indirectly imported
 		% modules. The short interfaces are treated as if
 		% they are imported using `use_module'.
-	{ append_pseudo_decl(Module4, used, Module5) },
-	process_module_long_interfaces(UsedModules, ".int",
-		IndirectImports1, IndirectImports, Module5, Module6),
-	process_module_short_interfaces_transitively(IndirectImports, ".int2",
-		Module6, Module),
+	{ append_pseudo_decl(Module4, used(interface), Module5) },
+	process_module_long_interfaces(IntUsedModules, ".int",
+		IntIndirectImports1, IntIndirectImports, Module5, Module6),
+	process_module_short_interfaces_transitively(IntIndirectImports,
+		".int2", Module6, Module7),
+
+	{ append_pseudo_decl(Module7, used(implementation), Module8) },
+	process_module_long_interfaces(ImpUsedModules, ".int",
+		ImpIndirectImports1, ImpIndirectImports, Module8, Module9),
+	process_module_short_interfaces_transitively(ImpIndirectImports,
+		".int2", Module9, Module),
 
 	{ module_imports_get_error(Module, Error) }.
 
@@ -1133,7 +1154,8 @@
 		% Find out which modules this one depends on
 		%
 	{ get_ancestors(ModuleName, ParentDeps) },
-	{ get_dependencies(Items0, ImportDeps0, UseDeps0) },
+	{ get_dependencies(Items0, IntImportDeps0, IntUseDeps0,
+			ImpImportDeps0, ImpUseDeps0) },
 
 		%
 		% Construct the initial module import structure,
@@ -1141,10 +1163,11 @@
 		%
 	{ init_module_imports(SourceFileName, ModuleName, Items0, [], [],
 		Module0) },
-	{ append_pseudo_decl(Module0, imported, Module1) },
+	{ append_pseudo_decl(Module0, imported(interface), Module1) },
 
 		% Add `builtin' and `private_builtin' to the imported modules.
-	{ add_implicit_imports(ImportDeps0, UseDeps0, ImportDeps1, UseDeps1) },
+	{ add_implicit_imports(IntImportDeps0, IntUseDeps0,
+			IntImportDeps1, IntUseDeps1) },
 
 		%
 		% Get the .int3s and .int0s that the current module depends on.
@@ -1152,23 +1175,39 @@
 
 		% first the .int0s for parent modules
 	process_module_private_interfaces(ParentDeps,
-			ImportDeps1, ImportDeps, UseDeps1, UseDeps,
+			IntImportDeps1, IntImportDeps, IntUseDeps1, IntUseDeps,
 			Module1, Module2),
 
 		% then the .int3s for `:- import'-ed modules
-	process_module_long_interfaces(ImportDeps, ".int3",
-			[], IndirectImportDeps0, Module2, Module3),
+	process_module_long_interfaces(IntImportDeps, ".int3",
+			[], IntIndirectImportDeps0, Module2, Module2a),
+
+	{ append_pseudo_decl(Module2a, imported(implementation), Module2b) },
+
+	process_module_private_interfaces(ParentDeps,
+			ImpImportDeps0, ImpImportDeps, ImpUseDeps0, ImpUseDeps,
+			Module2b, Module2c),
+
+	process_module_long_interfaces(ImpImportDeps, ".int3",
+			[], ImpIndirectImportDeps0, Module2c, Module3),
 
 		% then (after a `:- used' decl)
 		% the .int3s for `:- use'-ed modules
 		% and indirectly imported modules
-	{ append_pseudo_decl(Module3, used, Module4) },
-	process_module_long_interfaces(UseDeps, ".int3",
-			IndirectImportDeps0, IndirectImportDeps,
+	{ append_pseudo_decl(Module3, used(interface), Module4) },
+	process_module_long_interfaces(IntUseDeps, ".int3",
+			IntIndirectImportDeps0, IntIndirectImportDeps,
 			Module4, Module5),
 	process_module_short_interfaces_transitively(
-			IndirectImportDeps, ".int3", Module5, Module),
+			IntIndirectImportDeps, ".int3", Module5, Module6),
 
+	{ append_pseudo_decl(Module6, used(implementation), Module7) },
+	process_module_long_interfaces(ImpUseDeps, ".int3",
+			ImpIndirectImportDeps0, ImpIndirectImportDeps,
+			Module7, Module8),
+	process_module_short_interfaces_transitively(
+			ImpIndirectImportDeps, ".int3", Module8, Module),
+
 	{ module_imports_get_error(Module, Error) }.
 
 %-----------------------------------------------------------------------------%
@@ -1311,6 +1350,38 @@
 
 :- pred warn_if_duplicate_use_import_decls(module_name, list(module_name),
 		list(module_name), list(module_name), list(module_name), 
+		list(module_name), list(module_name), list(module_name), 
+		list(module_name), io__state, io__state).
+:- mode warn_if_duplicate_use_import_decls(in, in, out, in, out, in, out,
+		in, out, di, uo) is det.
+
+% This predicate ensures that all every import_module declaration is
+% checked against every use_module declaration.
+% warn_if_duplicate_use_import_decls/7 is called to generate the actual
+% warnings.
+
+warn_if_duplicate_use_import_decls(ModuleName,
+		IntImportedModules0, IntImportedModules, 
+		IntUsedModules0, IntUsedModules, 
+		ImpImportedModules0, ImpImportedModules, 
+		ImpUsedModules0, ImpUsedModules) -->
+
+	warn_if_duplicate_use_import_decls(ModuleName,
+		IntImportedModules0, IntImportedModules1,
+		IntUsedModules0, IntUsedModules1),
+	warn_if_duplicate_use_import_decls(ModuleName,
+		IntImportedModules1, IntImportedModules,
+		ImpUsedModules0, ImpUsedModules1),
+
+	warn_if_duplicate_use_import_decls(ModuleName,
+		ImpImportedModules0, ImpImportedModules1,
+		IntUsedModules1, IntUsedModules),
+	warn_if_duplicate_use_import_decls(ModuleName,
+		ImpImportedModules1, ImpImportedModules,
+		ImpUsedModules1, ImpUsedModules).
+
+:- pred warn_if_duplicate_use_import_decls(module_name, list(module_name),
+		list(module_name), list(module_name), list(module_name), 
 		io__state, io__state).
 :- mode warn_if_duplicate_use_import_decls(in, in, out, in, out, di, uo) is det.
 
@@ -3424,7 +3495,7 @@
 		% Treat indirectly imported items as if they were imported 
 		% using `:- use_module', since all uses of them in the `.int'
 		% files must be module qualified.
-	{ append_pseudo_decl(Module0, used, Module1) },
+	{ append_pseudo_decl(Module0, used(interface), Module1) },
 	process_module_short_interfaces_transitively(IndirectImports,
 		Ext, Module1, Module).
 
@@ -3563,30 +3634,126 @@
 %-----------------------------------------------------------------------------%
 
 get_dependencies(Items, ImportDeps, UseDeps) :-
-	get_dependencies_2(Items, [], ImportDeps, [], UseDeps).
+	get_dependencies_implementation(Items, [], [] , [], [],
+			IntImportDeps, IntUseDeps, ImpImportDeps, ImpUseDeps),
+	list__append(IntImportDeps, ImpImportDeps, ImportDeps),
+	list__append(IntUseDeps, ImpUseDeps, UseDeps).
 
-:- pred get_dependencies_2(item_list, list(module_name), list(module_name), 
-		list(module_name), list(module_name)).
-:- mode get_dependencies_2(in, in, out, in, out) is det.
-
-get_dependencies_2([], ImportDeps, ImportDeps, UseDeps, UseDeps).
-get_dependencies_2([Item - _Context | Items], ImportDeps0, ImportDeps,
-		UseDeps0, UseDeps) :-
+	% get_dependencies(Items, IntImportDeps, IntUseDeps,
+	% 		ImpImportDeps, ImpUseDeps).
+	%	Get the list of modules that a list of items depends on.
+	%	IntImportDeps is the list of modules imported using `:-
+	%	import_module' in the interface, and ImpImportDeps those
+	%	modules imported in the implementation. IntUseDeps is the
+	%	list of modules imported using `:- use_module' in the
+	%	interface, and ImpUseDeps those modules imported in the
+	%	implementation.
+	%	N.B. Typically you also need to consider the module's
+	%	parent modules (see get_ancestors/2) and possibly
+	%	also the module's child modules (see get_children/2).
+	%	N.B This predicate assumes that any declaration between
+	%	the `:- module' and the first `:- interface' or
+	%	`:- implementation' are in the implementation.
+	%
+:- pred get_dependencies(item_list::in,
+		list(module_name)::out, list(module_name)::out,
+		list(module_name)::out, list(module_name)::out) is det.
+
+get_dependencies(Items, IntImportDeps, IntUseDeps, ImpImportDeps, ImpUseDeps) :-
+	get_dependencies_implementation(Items, [], [] , [], [],
+			IntImportDeps, IntUseDeps, ImpImportDeps, ImpUseDeps).
+
+:- pred get_dependencies_implementation(item_list::in, list(module_name)::in,
+		list(module_name)::in, list(module_name)::in,
+		list(module_name)::in, list(module_name)::out,
+		list(module_name)::out, list(module_name)::out,
+		list(module_name)::out) is det.
+
+get_dependencies_implementation([], IntImportDeps, IntUseDeps,
+		ImpImportDeps, ImpUseDeps, IntImportDeps, IntUseDeps,
+		ImpImportDeps, ImpUseDeps).
+get_dependencies_implementation([Item - _Context | Items],
+		IntImportDeps0, IntUseDeps0,
+		ImpImportDeps0, ImpUseDeps0,
+		IntImportDeps, IntUseDeps,
+		ImpImportDeps, ImpUseDeps) :-
 	( 
-		Item = module_defn(_VarSet, import(module(Modules)))
+		
+		Item = module_defn(_VarSet, interface)
 	->
-		list__append(ImportDeps0, Modules, ImportDeps1),
-		UseDeps1 = UseDeps0
+		get_dependencies_interface(Items,
+				IntImportDeps0, IntUseDeps0,
+				ImpImportDeps0, ImpUseDeps0,
+				IntImportDeps, IntUseDeps,
+				ImpImportDeps, ImpUseDeps)
 	;
-		Item = module_defn(_VarSet, use(module(Modules)))
+		(
+		
+			Item = module_defn(_VarSet, import(module(Modules)))
+		->
+			list__append(ImpImportDeps0, Modules, ImpImportDeps1),
+			ImpUseDeps1 = ImpUseDeps0
+		;
+			Item = module_defn(_VarSet, use(module(Modules)))
+		->
+			list__append(ImpUseDeps0, Modules, ImpUseDeps1),
+			ImpImportDeps1 = ImpImportDeps0
+		;
+			ImpImportDeps1 = ImpImportDeps0,
+			ImpUseDeps1 = ImpUseDeps0
+		),
+		get_dependencies_implementation(Items,
+				IntImportDeps0, IntUseDeps0,
+				ImpImportDeps1, ImpUseDeps1,
+				IntImportDeps, IntUseDeps,
+				ImpImportDeps, ImpUseDeps)
+	).
+
+:- pred get_dependencies_interface(item_list::in, list(module_name)::in,
+		list(module_name)::in, list(module_name)::in,
+		list(module_name)::in, list(module_name)::out,
+		list(module_name)::out, list(module_name)::out,
+		list(module_name)::out) is det.
+
+get_dependencies_interface([], IntImportDeps, IntUseDeps,
+		ImpImportDeps, ImpUseDeps, IntImportDeps, IntUseDeps,
+		ImpImportDeps, ImpUseDeps).
+get_dependencies_interface([Item - _Context | Items],
+		IntImportDeps0, IntUseDeps0,
+		ImpImportDeps0, ImpUseDeps0,
+		IntImportDeps, IntUseDeps,
+		ImpImportDeps, ImpUseDeps) :-
+	( 
+		
+		Item = module_defn(_VarSet, implementation)
 	->
-		list__append(UseDeps0, Modules, UseDeps1),
-		ImportDeps1 = ImportDeps0
+		get_dependencies_implementation(Items,
+				IntImportDeps0, IntUseDeps0,
+				ImpImportDeps0, ImpUseDeps0,
+				IntImportDeps, IntUseDeps,
+				ImpImportDeps, ImpUseDeps)
 	;
-		ImportDeps1 = ImportDeps0,
-		UseDeps1 = UseDeps0
-	),
-	get_dependencies_2(Items, ImportDeps1, ImportDeps, UseDeps1, UseDeps).
+		(
+		
+			Item = module_defn(_VarSet, import(module(Modules)))
+		->
+			list__append(IntImportDeps0, Modules, IntImportDeps1),
+			IntUseDeps1 = IntUseDeps0
+		;
+			Item = module_defn(_VarSet, use(module(Modules)))
+		->
+			list__append(IntUseDeps0, Modules, IntUseDeps1),
+			IntImportDeps1 = IntImportDeps0
+		;
+			IntImportDeps1 = IntImportDeps0,
+			IntUseDeps1 = IntUseDeps0
+		),
+		get_dependencies_interface(Items,
+				IntImportDeps1, IntUseDeps1,
+				ImpImportDeps0, ImpUseDeps0,
+				IntImportDeps, IntUseDeps,
+				ImpImportDeps, ImpUseDeps)
+	).
 
 %-----------------------------------------------------------------------------%
 
@@ -3803,8 +3970,8 @@
 		InInterface1 = yes
 	; 
 		Item = module_defn(_, Defn),
-		( Defn = imported
-		; Defn = used
+		( Defn = imported(_)
+		; Defn = used(_)
 		)
 	->
 		% module_qual.m needs the :- imported declaration.
Index: prog_data.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_data.m,v
retrieving revision 1.49
diff -u -r1.49 prog_data.m
--- prog_data.m	1999/08/25 06:33:57	1.49
+++ prog_data.m	1999/10/27 04:44:44
@@ -784,19 +784,21 @@
 		% such items need to be exported to the
 		% sub-modules.
 
-	;	imported
+	;	imported(section)
 		% This is used internally by the compiler,
 		% to identify declarations which originally
 		% came from some other module imported with 
-		% a `:- import_module' declaration.
-	;	used
+		% a `:- import_module' declaration, and which
+		% section the module was imported.
+	;	used(section)
 		% This is used internally by the compiler,
 		% to identify declarations which originally
 		% came from some other module and for which
 		% all uses must be module qualified. This
 		% applies to items from modules imported using
 		% `:- use_module', and items from `.opt'
-		% and `.int2' files.
+		% and `.int2' files. It also records from which
+		% section the module was imported.
 	;	opt_imported
 		% This is used internally by the compiler,
 		% to identify items which originally
@@ -809,6 +811,10 @@
 	;	use(sym_list)
 
 	;	include_module(list(module_name)).
+
+:- type section
+	--->	implementation
+	;	interface.
 
 :- type sym_list	
 	--->	sym(list(sym_specifier))
Index: unused_args.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unused_args.m,v
retrieving revision 1.61
diff -u -r1.61 unused_args.m
--- unused_args.m	1999/10/25 03:49:52	1.61
+++ unused_args.m	1999/10/26 07:12:07
@@ -1029,7 +1029,7 @@
 	module_info_pred_proc_info(ModuleInfo0,
 		PredId, ProcId, PredInfo0, ProcInfo0),
 	make_new_pred_info(ModuleInfo0, PredInfo0, UnusedArgs,
-		"__ua", imported, OptProc, NewPredInfo0),
+		"__ua", imported(interface), OptProc, NewPredInfo0),
 	pred_info_procedures(NewPredInfo0, NewProcs0),
 	next_mode_id(NewProcs0, no, NewProcId),
 

----
 +----------------------------------------------------------------------+
 | Peter Ross      M Sci/Eng Melbourne Uni                              |
 | petdr at cs.mu.oz.au  WWW: www.cs.mu.oz.au/~petdr/ ph: +61 3 9344 9158  |
 +----------------------------------------------------------------------+
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list