[m-dev.] diff: use_module

Simon TAYLOR stayl at students.cs.mu.oz.au
Sat Jun 28 16:37:28 AEST 1997


Fergus wrote:
> Question: does the code handle the following test case correctly,
> when compiling with intermodule optimization?
> 
> 	:- module foo.
> 	:- interface.
> 	:- pred p is det.
> 	:- implementation.
> 	:- import_module list.
> 	p :-
> 		list__merge_sort([1], _).
> 
> That should be an error, since `list__merge_sort' is not exported
> from `list'.
> But I'm a bit worried that your removal of `opt_decl' might mean
> that the compiler will accept this code, rather than
> reporting an error.

This is not a problem because the mmake dependencies in the `.d' file
ensure that the `.opt' file is produced before attempting to compile to C.
This means that the module must pass typechecking without any items from
`.opt' files. We need to do that anyway to ensure that the type-correctness 
of the module does not depend on type equivalences from `.opt' files.


[Reporting errors for :- use_module and :- import_module on the same module]
> For example, it could make sense to use `use_module' in the
> interface, and `import_module' in the implementation.

Since that is not implemented, I'll leave it as a warning.

> If both are specified, you should just treat it as equivalent
> to `import_module'.

OK.

> I think this is still necessary.  What if a module has both
> foo/1 and foo/2, where foo/1 is exported but foo/2 is not,
> but a declaration for foo/2 is put in the .opt file?

Same as for the predicate case above.

Here's the updated section of the diff:


Estimated hours taken: 14 

Implemented a :- use_module directive. This is the same as 
:- import_module, except all uses of the imported items
must be explicitly module qualified.

:- use_module is implemented by ensuring that unqualified versions
of items only get added to the HLDS symbol tables if they were imported
using import_module.

Indirectly imported items (from `.int2' files) and items declared in `.opt'
files are treated as if they were imported with use_module, since all uses
of them should be module qualified. 

compiler/module_qual.m
	Keep two sets of type, mode and inst ids, those which can
	be used without qualifiers and those which can't.

	Renamed some predicates which no longer have unique names since
	'__' became a synonym for ':'.

	Made mq_info_set_module_used check whether the current item is in
	the interface, rather than relying on its caller to do the check.

	Removed init_mq_info_module, since make_hlds.m now uses the 
	mq_info built during the module qualification pass.

compiler/prog_data.m
	Added a pseudo-declaration `used', same as `imported' except uses of
	the following items must be module qualified.

	Added a type need_qualifier to describe whether uses of an item
	need to be module qualified.

compiler/make_hlds.m
	Keep with the import_status whether current item was imported
	using a :- use_module directive.

	Use the mq_info structure passed in instead of building a new one.

	Ensure unqualified versions of constructors only get added to the
	cons_table if they can be used without qualification.

compiler/hlds_module.m
	Added an extra argument to predicate_table_insert of type 
	need_qualifier.

	Only add predicates to the name and name-arity indices if they
	can be used without qualifiers.

	Changed the structure of the module-name-arity index, so that 
	lookups can be made without an arity, such as when type-checking 
	module qualified higher-order predicate constants. This does not 
	change the interface to the module_name_arity index.

	Factored out some common code in predicate_table_insert which
	applies to both predicates and functions.

compiler/hlds_pred.m
	Removed the opt_decl import_status. It isn't needed any more
	since all uses of items declared in .opt files must now be 
	module qualified.

	Added some documentation about when the clauses_info is valid.

compiler/intermod.m
	Ensure that predicate and function calls in the `.opt' file are 
	module qualified. Use use_module instead of import_module in 
	`.opt' files.

compiler/modules.m
	Handle use_module directives. 

	Report a warning if both use_module and import_module declarations
	exist for the same module.

compiler/mercury_compile.m
	Collect inter-module optimization information before module 
	qualification, since it can't cause conflicts any more. This means
	that the mq_info structure built in module_qual.m can be reused in
	make_hlds.m, instead of building a new one.

compiler/prog_out.m
	Add a predicate prog_out__write_module_list, which was moved
	here from module_qual.m.

compiler/typecheck.m
	Removed code to check that predicates declared in `.opt' files
	were being used appropriately, since this is now handled by 
	use_module.

compiler/*.m
	Added missing imports, mostly for prog_data and term.

NEWS
compiler/notes/todo.html
doc/reference_manual.texi
	Document `:- use_module'.	

tests/valid/intermod_lambda_test.m
tests/valid/intermod_lambda_test2.m
tests/invalid/errors.m
tests/invalid/errors2.m
	Test cases.


Index: hlds_module.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_module.m,v
retrieving revision 1.21
diff -u -r1.21 hlds_module.m
--- hlds_module.m	1997/05/27 03:06:25	1.21
+++ hlds_module.m	1997/06/28 04:53:53
@@ -26,9 +26,9 @@
 
 :- implementation.
 
-:- import_module hlds_data, hlds_out, prog_data, prog_util.
-:- import_module require, int, string, list, map, set, std_util.
+:- import_module hlds_data, hlds_out, llds, prog_data, prog_util.
 :- import_module typecheck.
+:- import_module bool, require, int, string, list, map, set, std_util.
 
 %-----------------------------------------------------------------------------%
 
@@ -967,10 +967,18 @@
 				sym_name, arity, list(pred_id)) is semidet.
 :- mode predicate_table_search_pf_sym_arity(in, in, in, in, out) is semidet.
 
-	% Insert a new pred_info structure into the predicate_table
-	% and assign it a new pred_id. You should check beforehand
-	% that the pred doesn't already occur in the table.
+	% predicate_table_insert(PredTable0, PredInfo, NeedQual, PredId,
+	% 		PredTable).
+	% 
+	% Insert PredInfo into PredTable0 and assign it a new pred_id.
+	% You should check beforehand that the pred doesn't already 
+	% occur in the table. 
+:- pred predicate_table_insert(predicate_table, pred_info, need_qualifier, 
+				pred_id, predicate_table).
+:- mode predicate_table_insert(in, in, in, out, out) is det.
 
+	% Equivalent to predicate_table_insert(PredTable0, PredInfo, 
+	%	yes, PredId, PredTable). 
 :- pred predicate_table_insert(predicate_table, pred_info, pred_id,
 				predicate_table).
 :- mode predicate_table_insert(in, in, out, out) is det.
@@ -1023,8 +1031,11 @@
 :- type name_arity_index == map(name_arity, list(pred_id)).
 :- type name_arity ---> string / arity.
 
-:- type module_name_arity_index == map(module_name_arity, list(pred_id)).
-:- type module_name_arity ---> module_name_arity(module_name, string, arity).
+	% First search on module and name, then search on arity. The two 
+	% levels are needed because typecheck.m needs to be able to search
+	% on module and name only for higher-order terms.
+:- type module_name_arity_index == map(pair(module_name, string), 
+					map(arity, list(pred_id))).
 
 predicate_table_init(PredicateTable) :-
 	PredicateTable = predicate_table(Preds, NextPredId, PredIds,
@@ -1085,9 +1096,8 @@
 	predicate_table_search_name(PredicateTable, Name, PredIdList).
 predicate_table_search_sym(PredicateTable, qualified(Module, Name),
 		PredIdList) :-
-	predicate_table_search_name(PredicateTable, Name, PredIdList0),
-	predicate_table_get_preds(PredicateTable, PredTable),
-	find_preds_matching_module(PredIdList0, Module, PredTable, PredIdList),
+	predicate_table_search_module_name(PredicateTable, 
+		Module, Name, PredIdList),
 	PredIdList \= [].
 
 :- predicate_table_search_pred_sym(_, X, _) when X. % NU-Prolog indexing.
@@ -1097,9 +1107,8 @@
 	predicate_table_search_pred_name(PredicateTable, Name, PredIdList).
 predicate_table_search_pred_sym(PredicateTable, qualified(Module, Name),
 		PredIdList) :-
-	predicate_table_search_pred_name(PredicateTable, Name, PredIdList0),
-	predicate_table_get_preds(PredicateTable, PredTable),
-	find_preds_matching_module(PredIdList0, Module, PredTable, PredIdList),
+	predicate_table_search_pred_module_name(PredicateTable, 
+		Module, Name, PredIdList),
 	PredIdList \= [].
 
 :- predicate_table_search_func_sym(_, X, _) when X. % NU-Prolog indexing.
@@ -1109,30 +1118,13 @@
 	predicate_table_search_func_name(PredicateTable, Name, PredIdList).
 predicate_table_search_func_sym(PredicateTable, qualified(Module, Name),
 		PredIdList) :-
-	predicate_table_search_func_name(PredicateTable, Name, PredIdList0),
-	predicate_table_get_preds(PredicateTable, PredTable),
-	find_preds_matching_module(PredIdList0, Module, PredTable, PredIdList),
+	predicate_table_search_func_module_name(PredicateTable, Module,
+		Name, PredIdList),
 	PredIdList \= [].
 
 	% Given a list of predicates, and a module name, find all the
 	% predicates which came from that module.
 
-:- pred find_preds_matching_module(list(pred_id), module_name, pred_table,
-		list(pred_id)).
-:- mode find_preds_matching_module(in, in, in, out) is det.
-
-find_preds_matching_module([], _, _, []).
-find_preds_matching_module([PredId | PredIds0], Module, PredTable, PredIds) :-
-	(
-		map__search(PredTable, PredId, PredInfo),
-		pred_info_module(PredInfo, Module)
-	->
-		PredIds = [PredId | PredIds1]
-	;
-		PredIds = PredIds1
-	),
-	find_preds_matching_module(PredIds0, Module, PredTable, PredIds1).
-
 %-----------------------------------------------------------------------------%
 
 :- predicate_table_search_sym_arity(_, X, _, _) when X. % NU-Prolog indexing.
@@ -1200,6 +1192,54 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred predicate_table_search_module_name(predicate_table, module_name, 
+		string, list(pred_id)).
+:- mode predicate_table_search_module_name(in, in, in, out) is semidet.
+
+predicate_table_search_module_name(PredicateTable, Module, Name, PredIds) :-
+	(
+		predicate_table_search_pred_module_name(PredicateTable, 
+			Module, Name, PredPredIds0)
+	->
+		PredPredIds = PredPredIds0
+	;
+		PredPredIds = []
+	),
+	(
+		predicate_table_search_func_module_name(PredicateTable, 
+			Module, Name, FuncPredIds0)
+	->
+		FuncPredIds = FuncPredIds0
+	;
+		FuncPredIds = []
+	),
+	list__append(FuncPredIds, PredPredIds, PredIds),
+	PredIds \= [].
+
+:- pred predicate_table_search_pred_module_name(predicate_table, module_name,
+		string, list(pred_id)).
+:- mode predicate_table_search_pred_module_name(in, in, in, out) is semidet.
+
+predicate_table_search_pred_module_name(PredicateTable, 
+		Module, PredName, PredIds) :-
+	PredicateTable = predicate_table(_,_,_,_,_, Pred_MNA_Index, _,_,_),
+	map__search(Pred_MNA_Index, Module - PredName, Arities),
+	map__values(Arities, PredIdLists),
+	list__condense(PredIdLists, PredIds).
+
+:- pred predicate_table_search_func_module_name(predicate_table, module_name,
+		string, list(pred_id)).
+:- mode predicate_table_search_func_module_name(in, in, in, out) is semidet.
+
+predicate_table_search_func_module_name(PredicateTable, 
+		Module, FuncName, PredIds) :-
+	PredicateTable = predicate_table(_,_,_,_,_,_,_,_, Func_MNA_Index),
+	map__search(Func_MNA_Index, Module - FuncName, Arities),
+	map__values(Arities, PredIdLists),
+	list__condense(PredIdLists, PredIds).
+
+%-----------------------------------------------------------------------------%
+
 predicate_table_search_name_arity(PredicateTable, Name, Arity, PredIds) :-
 	(
 		predicate_table_search_pred_name_arity(PredicateTable,
@@ -1258,14 +1298,14 @@
 predicate_table_search_pred_m_n_a(PredicateTable, Module, PredName, Arity,
 		PredIds) :-
 	PredicateTable = predicate_table(_, _, _, _, _, P_MNA_Index, _, _, _),
-	MNA = module_name_arity(Module, PredName, Arity),
-	map__search(P_MNA_Index, MNA, PredIds).
+	map__search(P_MNA_Index, Module - PredName, ArityIndex),
+	map__search(ArityIndex, Arity, PredIds).
 
 predicate_table_search_func_m_n_a(PredicateTable, Module, FuncName, Arity,
 		PredIds) :-
 	PredicateTable = predicate_table(_, _, _, _, _, _, _, _, F_MNA_Index),
-	MNA = module_name_arity(Module, FuncName, Arity),
-	map__search(F_MNA_Index, MNA, PredIds).
+	map__search(F_MNA_Index, Module - FuncName, ArityIndex),
+	map__search(ArityIndex, Arity, PredIds).
 
 %-----------------------------------------------------------------------------%
 
@@ -1307,6 +1347,11 @@
 %-----------------------------------------------------------------------------%
 
 predicate_table_insert(PredicateTable0, PredInfo, PredId, PredicateTable) :-
+	predicate_table_insert(PredicateTable0, PredInfo, must_be_qualified,
+		PredId, PredicateTable).
+
+predicate_table_insert(PredicateTable0, PredInfo, NeedQual,
+		PredId, PredicateTable) :-
 	PredicateTable0 = predicate_table(Preds0, NextPredId0, PredIds0,
 				Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
 				Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
@@ -1323,41 +1368,10 @@
 	pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
 	( 
 		PredOrFunc = predicate,
-
-			% insert the pred_id into the pred name index
-		( map__search(Pred_N_Index0, Name, N_PredIdList0) ->
-			N_PredIdList = [PredId | N_PredIdList0],
-			map__det_update(Pred_N_Index0, Name, N_PredIdList,
-				Pred_N_Index)
-		;
-			N_PredIdList = [PredId],
-			map__det_insert(Pred_N_Index0, Name, N_PredIdList,
-				Pred_N_Index)
-		),
-
-			% insert it into the pred name/arity index
-		NA = Name / Arity,
-		( map__search(Pred_NA_Index0, NA, NA_PredIdList0) ->
-			NA_PredIdList = [PredId | NA_PredIdList0],
-			map__det_update(Pred_NA_Index0, NA, NA_PredIdList,	
-				Pred_NA_Index)
-		;
-			NA_PredIdList = [PredId],
-			map__det_insert(Pred_NA_Index0, NA, NA_PredIdList,	
-				Pred_NA_Index)
-		),
-
-			% insert it into the pred module:name/arity index
-		MNA = module_name_arity(Module, Name, Arity),
-		( map__search(Pred_MNA_Index0, MNA, MNA_PredIdList0) ->
-			MNA_PredIdList = [PredId | MNA_PredIdList0],
-			map__det_update(Pred_MNA_Index0, MNA, MNA_PredIdList,
-				Pred_MNA_Index)
-		;
-			MNA_PredIdList = [PredId],
-			map__det_insert(Pred_MNA_Index0, MNA, MNA_PredIdList,
-				Pred_MNA_Index)
-		),
+		predicate_table_do_insert(Module, Name, Arity, NeedQual,
+			PredId, Pred_N_Index0, Pred_N_Index, 
+			Pred_NA_Index0, Pred_NA_Index,
+			Pred_MNA_Index0, Pred_MNA_Index),
 
 		Func_N_Index = Func_N_Index0,
 		Func_NA_Index = Func_NA_Index0,
@@ -1365,41 +1379,12 @@
 	;
 		PredOrFunc = function,
 
-			% insert the pred_id into the func name index
-		( map__search(Func_N_Index0, Name, N_PredIdList0) ->
-			N_PredIdList = [PredId | N_PredIdList0],
-			map__det_update(Func_N_Index0, Name, N_PredIdList,
-				Func_N_Index)
-		;
-			N_PredIdList = [PredId],
-			map__det_insert(Func_N_Index0, Name, N_PredIdList,
-				Func_N_Index)
-		),
-
-			% insert it into the func name/arity index
 		FuncArity is Arity - 1,
-		NA = Name / FuncArity,
-		( map__search(Func_NA_Index0, NA, NA_PredIdList0) ->
-			NA_PredIdList = [PredId | NA_PredIdList0],
-			map__det_update(Func_NA_Index0, NA, NA_PredIdList,
-				Func_NA_Index)
-		;
-			NA_PredIdList = [PredId],
-			map__det_insert(Func_NA_Index0, NA, NA_PredIdList,
-				Func_NA_Index)
-		),
 
-			% insert it into the func module:name/arity index
-		MNA = module_name_arity(Module, Name, FuncArity),
-		( map__search(Func_MNA_Index0, MNA, MNA_PredIdList0) ->
-			MNA_PredIdList = [PredId | MNA_PredIdList0],
-			map__det_update(Func_MNA_Index0, MNA, MNA_PredIdList,
-				Func_MNA_Index)
-		;
-			MNA_PredIdList = [PredId],
-			map__det_insert(Func_MNA_Index0, MNA, MNA_PredIdList,
-				Func_MNA_Index)
-		),
+		predicate_table_do_insert(Module, Name, FuncArity, NeedQual,
+			PredId, Func_N_Index0, Func_N_Index, 
+			Func_NA_Index0, Func_NA_Index,
+			Func_MNA_Index0, Func_MNA_Index),
 
 		Pred_N_Index = Pred_N_Index0,
 		Pred_NA_Index = Pred_NA_Index0,
@@ -1416,6 +1401,63 @@
 				Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
 				Func_N_Index, Func_NA_Index, Func_MNA_Index).
 
+:- pred predicate_table_do_insert(module_name, string, arity, need_qualifier,
+	pred_id, name_index, name_index, name_arity_index, name_arity_index,
+	module_name_arity_index, module_name_arity_index).
+:- mode predicate_table_do_insert(in, in, in, in, in, 
+	in, out, in, out, in, out) is det.
+
+predicate_table_do_insert(Module, Name, Arity, NeedQual, PredId, 
+		N_Index0, N_Index, NA_Index0, NA_Index, 
+		MNA_Index0, MNA_Index) :-
+	( NeedQual = may_be_unqualified ->
+			% insert the pred_id into the name index
+		( map__search(N_Index0, Name, N_PredIdList0) ->
+			N_PredIdList = [PredId | N_PredIdList0],
+			map__det_update(N_Index0, Name,
+				N_PredIdList, N_Index)
+		;
+			N_PredIdList = [PredId],
+			map__det_insert(N_Index0, Name, 
+				N_PredIdList, N_Index)
+		),
+
+			% insert it into the name/arity index
+		NA = Name / Arity,
+		( map__search(NA_Index0, NA, NA_PredIdList0) ->
+			NA_PredIdList = [PredId | NA_PredIdList0],
+			map__det_update(NA_Index0, NA,
+				NA_PredIdList, NA_Index)
+		;
+			NA_PredIdList = [PredId],
+			map__det_insert(NA_Index0, NA,
+				NA_PredIdList,	NA_Index)
+		)
+	;
+		N_Index = N_Index0,
+		NA_Index = NA_Index0
+	),
+
+		% insert it into the module:name/arity index
+	( map__search(MNA_Index0, Module - Name, MN_Arities0) ->
+		( map__search(MN_Arities0, Arity, MNA_PredIdList0) ->
+			map__det_update(MN_Arities0, Arity, 
+				[PredId | MNA_PredIdList0], MN_Arities)
+		;
+			map__det_insert(MN_Arities0, Arity, 
+				[PredId], MN_Arities)
+		),
+		map__det_update(MNA_Index0, Module - Name, MN_Arities,
+			MNA_Index)
+	;
+		map__init(MN_Arities0),
+		map__det_insert(MN_Arities0, Arity, 
+			[PredId], MN_Arities),
+		map__det_insert(MNA_Index0, Module - Name, MN_Arities,
+			MNA_Index)
+	).
+
+%-----------------------------------------------------------------------------%
 
 get_pred_id_and_proc_id(SymName, PredOrFunc, TVarSet, ArgTypes, ModuleInfo,
 			PredId, ProcId) :-
Index: make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.233
diff -u -r1.233 make_hlds.m
--- make_hlds.m	1997/06/27 04:01:31	1.233
+++ make_hlds.m	1997/06/28 05:18:18
@@ -23,18 +23,19 @@
 :- interface.
 
 :- import_module prog_data, hlds_module, hlds_pred, hlds_goal, hlds_data.
-:- import_module equiv_type.
+:- import_module equiv_type, module_qual.
 
 :- import_module io, std_util.
 
-% parse_tree_to_hlds(ParseTree, EqvMap, HLDS, UndefTypes, UndefModes):
-%	Given EqvMap, converts ParseTree to HLDS.
+% parse_tree_to_hlds(ParseTree, MQInfo, EqvMap, HLDS, UndefTypes, UndefModes):
+%	Given MQInfo (returned by module_qual.m) and EqvMap (returned by
+%	equiv_type.m), converts ParseTree to HLDS.
 %	Any errors found are recorded in the HLDS num_errors field.
 %	Returns UndefTypes = yes if undefined types found.
 %	Returns UndefModes = yes if undefined modes found.
-:- pred parse_tree_to_hlds(program, eqv_map, module_info, bool, bool,
+:- pred parse_tree_to_hlds(program, mq_info, eqv_map, module_info, bool, bool,
 			io__state, io__state).
-:- mode parse_tree_to_hlds(in, in, out, out, out, di, uo) is det.
+:- mode parse_tree_to_hlds(in, in, in, out, out, out, di, uo) is det.
 
 :- pred create_atomic_unification(var, unify_rhs, term__context,
 			unify_main_context, unify_sub_contexts, hlds_goal).
@@ -65,19 +66,20 @@
 :- import_module string, char, int, set, bintree, list, map, require.
 :- import_module bool, getopt, assoc_list, term, term_io, varset.
 
-parse_tree_to_hlds(module(Name, Items), EqvMap, Module, UndefTypes, UndefModes)
-		-->
+parse_tree_to_hlds(module(Name, Items), MQInfo0, EqvMap, Module, 
+		UndefTypes, UndefModes) -->
 	globals__io_get_globals(Globals),
 	{ module_info_init(Name, Globals, Module0) },
-	add_item_list_decls_pass_1(Items, local, Module0, Module1),
+	add_item_list_decls_pass_1(Items,
+		item_status(local, may_be_unqualified), Module0, Module1),
 	globals__io_lookup_bool_option(statistics, Statistics),
 	maybe_report_stats(Statistics),
-	add_item_list_decls_pass_2(Items, local, Module1, Module2),
+	add_item_list_decls_pass_2(Items,
+		item_status(local, may_be_unqualified), Module1, Module2),
 	maybe_report_stats(Statistics),
 		% balance the binary trees
 	{ module_info_optimize(Module2, Module3) },
 	maybe_report_stats(Statistics),
-	{ init_mq_info_module(Module3, MQInfo0) },
 	{ init_qual_info(MQInfo0, EqvMap, Info0) },
 	add_item_list_clauses(Items, local, Module3, Module4,
 				Info0, Info),
@@ -94,11 +96,18 @@
 
 %-----------------------------------------------------------------------------%
 
+	% When adding an item to the HLDS we need to know both its 
+	% import_status and whether uses of it must be module qualified.
+:- type item_status
+	---> item_status(import_status, need_qualifier).
+
+%-----------------------------------------------------------------------------%
+
 	% pass 1:
 	% Add the declarations one by one to the module,
 	% except for type definitions and pragmas.
 
-:- pred add_item_list_decls_pass_1(item_list, import_status,
+:- pred add_item_list_decls_pass_1(item_list, item_status,
 				module_info, module_info,
 				io__state, io__state).
 :- mode add_item_list_decls_pass_1(in, in, in, out, di, uo) is det.
@@ -127,7 +136,7 @@
 	% have processed all the mode declarations, since otherwise we
 	% can't be sure that there isn't a mode declaration for the function.
 
-:- pred add_item_list_decls_pass_2(item_list, import_status,
+:- pred add_item_list_decls_pass_2(item_list, item_status,
 		module_info, module_info, io__state, io__state).
 :- mode add_item_list_decls_pass_2(in, in, in, out, di, uo) is det.
 
@@ -156,8 +165,8 @@
 
 	% dispatch on the different types of items
 
-:- pred add_item_decl_pass_1(item, term__context, import_status, module_info,
-			import_status, module_info, io__state, io__state).
+:- pred add_item_decl_pass_1(item, term__context, item_status,
+		module_info, item_status, module_info, io__state, io__state).
 :- mode add_item_decl_pass_1(in, in, in, in, out, out, di, uo) is det.
 
 	% skip clauses
@@ -210,6 +219,9 @@
 	; { ModuleDefn = import(module(_)) } ->
 		{ Status = Status0 },
 		{ Module = Module0 }
+	; { ModuleDefn = use(module(_)) } ->
+		{ Status = Status0 },
+		{ Module = Module0 }
 	; { ModuleDefn = external(External) } ->
 		( { External = name_arity(Name, Arity) } ->
 			{ Status = Status0 },
@@ -240,8 +252,8 @@
 
 	% dispatch on the different types of items
 
-:- pred add_item_decl_pass_2(item, term__context, import_status, module_info,
-			import_status, module_info,
+:- pred add_item_decl_pass_2(item, term__context, item_status,
+			module_info, item_status, module_info,
 			io__state, io__state).
 :- mode add_item_decl_pass_2(in, in, in, in, out, out, di, uo) is det.
 
@@ -339,7 +351,8 @@
 			% This can only appear in .opt files.
 		{ Pragma = unused_args(PredOrFunc, SymName,
 				Arity, ProcId, UnusedArgs) },
-		( { Status \= opt_imported } ->
+		{ Status = item_status(ImportStatus, _) },
+		( { ImportStatus \= opt_imported } ->
 			prog_out__write_context(Context),
 			io__write_string("Error: unknown pragma unused_args.\n"),
 			{ module_info_incr_errors(Module0, Module) }
@@ -408,20 +421,27 @@
 %------------------------------------------------------------------------------
 
 	% If a module_defn updates the import_status, return the new
-	% status, otherwise fail.
+	% status and whether uses of the following items must be module 
+	% qualified, otherwise fail.
 :- pred module_defn_update_import_status(module_defn::in,
-				import_status::out) is semidet.
+		item_status::out) is semidet.
 
-module_defn_update_import_status(interface, exported).
-module_defn_update_import_status(implementation, local).
-module_defn_update_import_status(imported, imported).
-module_defn_update_import_status(opt_imported, opt_imported).
+module_defn_update_import_status(interface,
+		item_status(exported, may_be_unqualified)).
+module_defn_update_import_status(implementation,
+		item_status(local, 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, 
+		item_status(opt_imported, must_be_qualified)).
 
 %-----------------------------------------------------------------------------%
 
 	% dispatch on the different types of items
 
-:- pred add_item_clause(item, import_status, import_status, term__context,
+:- pred add_item_clause(item, import_status, import_status, term__context, 
 	module_info, module_info, qual_info, qual_info, io__state, io__state).
 :- mode add_item_clause(in, in, out, in, in, out, in, out, di, uo) is det.
 
@@ -448,10 +468,15 @@
 add_item_clause(func_mode(_, _, _, _, _, _), Status, Status, _,
 				Module, Module, Info, Info) --> [].
 add_item_clause(module_defn(_, Defn), Status0, Status, _,
-		Module, Module, Info, Info) --> 
-	{ module_defn_update_import_status(Defn, Status1) ->
+		Module, Module, Info0, Info) --> 
+	{ module_defn_update_import_status(Defn, ItemStatus1) ->
+		ItemStatus1 = item_status(Status1, NeedQual),
+		qual_info_get_mq_info(Info0, MQInfo0),
+		mq_info_set_need_qual_flag(MQInfo0, NeedQual, MQInfo),
+		qual_info_set_mq_info(Info0, MQInfo, Info),
 		Status = Status1
 	;
+		Info = Info0,
 		Status = Status0
 	}.
 add_item_clause(pragma(Pragma), Status, Status, Context,
@@ -592,11 +617,12 @@
 %-----------------------------------------------------------------------------%
 
 :- pred module_add_inst_defn(module_info, varset, inst_defn, condition,
-		term__context, import_status, module_info, io__state, io__state).
+		term__context, item_status, 
+		module_info, io__state, io__state).
 :- mode module_add_inst_defn(in, in, in, in, in, in, out, di, uo) is det.
 
 module_add_inst_defn(Module0, VarSet, InstDefn, Cond,
-			Context, Status, Module) -->
+		Context, item_status(Status, _NeedQual), Module) -->
 	{ module_info_insts(Module0, InstTable0) },
 	{ inst_table_get_user_insts(InstTable0, Insts0) },
 	insts_add(Insts0, VarSet, InstDefn, Cond, Context, Status, Insts),
@@ -640,11 +666,11 @@
 %-----------------------------------------------------------------------------%
 
 :- pred module_add_mode_defn(module_info, varset, mode_defn, condition,
-	term__context, import_status, module_info, io__state, io__state).
+		term__context, item_status, module_info, io__state, io__state).
 :- mode module_add_mode_defn(in, in, in, in, in, in, out, di, uo) is det.
 
 module_add_mode_defn(Module0, VarSet, ModeDefn, Cond,
-		Context, Status, Module) -->
+		Context, item_status(Status, _NeedQual), Module) -->
 	{ module_info_modes(Module0, Modes0) },
 	modes_add(Modes0, VarSet, ModeDefn, Cond, Context, Status, Modes),
 	{ module_info_set_modes(Module0, Modes, Module) }.
@@ -691,11 +717,11 @@
 	% t which defines t as an abstract_type.
 
 :- pred module_add_type_defn(module_info, tvarset, type_defn, condition,
-	term__context, import_status, module_info, io__state, io__state).
+		term__context, item_status, module_info, io__state, io__state).
 :- mode module_add_type_defn(in, in, in, in, in, in, out, di, uo) is det.
 
-module_add_type_defn(Module0, TVarSet, TypeDefn, _Cond, Context, Status0,
-		Module) -->
+module_add_type_defn(Module0, TVarSet, TypeDefn, _Cond, Context,
+		item_status(Status0, NeedQual), Module) -->
 	{ module_info_types(Module0, Types0) },
 	globals__io_get_globals(Globals),
 	{ convert_type_defn(TypeDefn, Globals, Name, Args, Body) },
@@ -765,7 +791,8 @@
 			{ Body = du_type(ConsList, _, _) }
 		->
 			{ module_info_ctors(Module0, Ctors0) },
-			ctors_add(ConsList, TypeId, Context, Ctors0, Ctors),
+			ctors_add(ConsList, TypeId, NeedQual, 
+				Context, Ctors0, Ctors),
 			{ module_info_set_ctors(Module0, Ctors, Module1) }
 		;
 			{ Module1 = Module0 }
@@ -887,12 +914,12 @@
 convert_type_defn(eqv_type(Name, Args, Body), _, Name, Args, eqv_type(Body)).
 convert_type_defn(abstract_type(Name, Args), _, Name, Args, abstract_type).
 
-:- pred ctors_add(list(constructor), type_id, term__context, cons_table,
-			cons_table, io__state, io__state).
-:- mode ctors_add(in, in, in, in, out, di, uo) is det.
+:- pred ctors_add(list(constructor), type_id, need_qualifier, term__context, 
+			cons_table, cons_table, io__state, io__state).
+:- mode ctors_add(in, in, in, in, in, out, di, uo) is det.
 
-ctors_add([], _TypeId, _Context, Ctors, Ctors) --> [].
-ctors_add([Name - Args | Rest], TypeId, Context, Ctors0, Ctors) -->
+ctors_add([], _TypeId, _NeedQual, _Context, Ctors, Ctors) --> [].
+ctors_add([Name - Args | Rest], TypeId, NeedQual, Context, Ctors0, Ctors) -->
 	{ make_cons_id(Name, Args, TypeId, QualifiedConsId) },
 	{ assoc_list__values(Args, Types) },
 	{ ConsDefn = hlds_cons_defn(Types, TypeId, Context) },
@@ -923,7 +950,10 @@
 		{ QualifiedConsDefns = [ConsDefn | QualifiedConsDefns1] }	
 	),
 	{ map__set(Ctors0, QualifiedConsId, QualifiedConsDefns, Ctors1) },
-	{ QualifiedConsId = cons(qualified(_, ConsName), Arity) ->
+	{
+		QualifiedConsId = cons(qualified(_, ConsName), Arity),
+		NeedQual = may_be_unqualified
+	->
 		% Add an unqualified version of the cons_id to the cons_table.
 		UnqualifiedConsId = cons(unqualified(ConsName), Arity),
 		(
@@ -939,29 +969,28 @@
 	;
 		Ctors2 = Ctors1
 	},
-	ctors_add(Rest, TypeId, Context, Ctors2, Ctors).
+	ctors_add(Rest, TypeId, NeedQual, Context, Ctors2, Ctors).
 
 %---------------------------------------------------------------------------%
 
 :- pred module_add_pred(module_info, varset, sym_name, list(type_and_mode),
-		maybe(determinism), condition, term__context, import_status,
-		module_info,
-		io__state, io__state).
+		maybe(determinism), condition, term__context, 
+		item_status, module_info, io__state, io__state).
 :- mode module_add_pred(in, in, in, in, in, in, in, in, out, di, uo) is det.
 
 module_add_pred(Module0, VarSet, PredName, TypesAndModes, MaybeDet, Cond,
-		Context, Status, Module) -->
+		Context, item_status(Status, NeedQual), Module) -->
 	% Only preds with opt_imported clauses are tagged as opt_imported, so
 	% that the compiler doesn't look for clauses for other preds read in
 	% from optimization interfaces.
 	{ Status = opt_imported ->
-		DeclStatus = opt_decl 
+		DeclStatus = imported
 	;
 		DeclStatus = Status
 	},
 	{ split_types_and_modes(TypesAndModes, Types, MaybeModes) },
 	add_new_pred(Module0, VarSet, PredName, Types, Cond, Context,
-		DeclStatus, predicate, Module1),
+		DeclStatus, NeedQual, predicate, Module1),
 	(
 		{ MaybeModes = yes(Modes) }
 	->
@@ -973,12 +1002,12 @@
 
 :- pred module_add_func(module_info, varset, sym_name, list(type_and_mode),
 		type_and_mode, maybe(determinism), condition, term__context,
-		import_status, module_info,
-		io__state, io__state).
+		item_status, module_info, io__state, io__state).
 :- mode module_add_func(in, in, in, in, in, in, in, in, in, out, di, uo) is det.
 
 module_add_func(Module0, VarSet, FuncName, TypesAndModes, RetTypeAndMode,
-		MaybeDet, Cond, Context, Status, Module) -->
+		MaybeDet, Cond, Context,
+		item_status(Status, NeedQual), Module) -->
 	% 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 ->
@@ -990,7 +1019,7 @@
 	{ split_type_and_mode(RetTypeAndMode, RetType, MaybeRetMode) },
 	{ list__append(Types, [RetType], Types1) },
 	add_new_pred(Module0, VarSet, FuncName, Types1, Cond, Context,
-		DeclStatus, function, Module1),
+		DeclStatus, NeedQual, function, Module1),
 	(
 		{ MaybeModes = yes(Modes) },
 		{ MaybeRetMode = yes(RetMode) }
@@ -1002,17 +1031,17 @@
 		{ Module = Module1 }
 	).
 
-:- pred add_new_pred(module_info, tvarset, sym_name, list(type),
-		condition, term__context, import_status, pred_or_func,
+:- pred add_new_pred(module_info, tvarset, sym_name, list(type), condition, 
+		term__context, import_status, need_qualifier, pred_or_func,
 		module_info, io__state, io__state).
-:- mode add_new_pred(in, in, in, in, in, in, in, in, out, di, uo) is det.
+:- mode add_new_pred(in, in, in, in, in, in, in, in, in, out, di, uo) is det.
 
 % NB.  Predicates are also added in polymorphism.m, which converts
 % lambda expressions into separate predicates, so any changes may need
 % to be reflected there too.
 
-add_new_pred(Module0, TVarSet, PredName, Types, Cond, Context, Status,
-		PredOrFunc, Module) -->
+add_new_pred(Module0, TVarSet, PredName, Types, Cond, Context, 
+		Status, NeedQual, PredOrFunc, Module) -->
 	{ module_info_name(Module0, ModuleName) },
 	{ list__length(Types, Arity) },
 	(
@@ -1034,7 +1063,7 @@
 				PredOrFunc, MNameOfPred, PName, Arity,
 				[OrigPred|_]) }
 		->
-			( { Status \= opt_decl } ->
+			( { Status \= opt_imported } ->
 				{ module_info_incr_errors(Module1, Module) },
 				{ module_info_pred_info(Module, OrigPred,
 					OrigPredInfo) },
@@ -1050,7 +1079,7 @@
 			)
 		;
 			{ predicate_table_insert(PredicateTable0, PredInfo0, 
-					PredId, PredicateTable1) },
+				NeedQual, PredId, PredicateTable1) },
 			( 
 				{ code_util__predinfo_is_builtin(PredInfo0) }
 			->
@@ -1213,8 +1242,8 @@
 		ArgLives, yes(Det), Context, PredInfo, _),
 
 	module_info_get_predicate_table(Module0, PredicateTable0),
-	predicate_table_insert(PredicateTable0, PredInfo, PredId,
-		PredicateTable),
+	predicate_table_insert(PredicateTable0, PredInfo, may_be_unqualified, 
+		PredId, PredicateTable),
 	module_info_set_predicate_table(Module0, PredicateTable,
 		Module1),
 	module_info_get_special_pred_map(Module1, SpecialPredMap0),
@@ -1361,8 +1390,8 @@
 		\+ predicate_table_search_pf_sym_arity(PredicateTable0,
 			PredOrFunc, PredName, Arity, _)
 	->
-		predicate_table_insert(PredicateTable0, PredInfo, PredId,
-			PredicateTable)
+		predicate_table_insert(PredicateTable0, PredInfo, 
+			may_be_unqualified, PredId, PredicateTable)
 	;	
 		error("preds_add_implicit")
 	).
@@ -2764,7 +2793,7 @@
 	    }
 	->
 		{ qual_info_get_mq_info(Info0, MQInfo0) },
-		module_qual__qualify_mode_list(Modes1, Modes, Context,
+		module_qual__qualify_lambda_mode_list(Modes1, Modes, Context,
 						MQInfo0, MQInfo1),
 		{ qual_info_set_mq_info(Info0, MQInfo1, Info1) },
 		{ Det = Det1 },
@@ -2795,7 +2824,7 @@
 	    }
 	->
 		{ qual_info_get_mq_info(Info0, MQInfo0) },
-		module_qual__qualify_mode_list(Modes1, Modes, Context,
+		module_qual__qualify_lambda_mode_list(Modes1, Modes, Context,
 						MQInfo0, MQInfo1),
 		{ qual_info_set_mq_info(Info0, MQInfo1, Info1) },
 		{ Det = Det1 },
@@ -2930,7 +2959,8 @@
 	{ Info0 = qual_info(EqvMap, TVarSet0, TVarRenaming0, Index0,
 				VarTypes0, PredId, MQInfo0) },
 
-	module_qual__qualify_type(Type0, Type1, Context, MQInfo0, MQInfo),
+	module_qual__qualify_type_qualification(Type0, Type1, 
+		Context, MQInfo0, MQInfo),
 	{
 	% Find any new type variables introduced by this type, and
 	% add them to the var-name index and the variable renaming.
@@ -3083,7 +3113,8 @@
 :- pred init_qual_info(mq_info, eqv_map, qual_info).
 :- mode init_qual_info(in, in, out) is det.
 
-init_qual_info(MQInfo, EqvMap, QualInfo) :-
+init_qual_info(MQInfo0, EqvMap, QualInfo) :-
+	mq_info_set_need_qual_flag(MQInfo0, may_be_unqualified, MQInfo),
 	varset__init(TVarSet),
 	map__init(Renaming),
 	map__init(Index),
Index: modules.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modules.m,v
retrieving revision 1.34
diff -u -r1.34 modules.m
--- modules.m	1997/06/03 07:00:46	1.34
+++ modules.m	1997/06/28 06:12:57
@@ -107,12 +107,14 @@
 :- pred generate_dependencies(string, io__state, io__state).
 :- mode generate_dependencies(in, di, uo) is det.
 
-	% Given a module (well, a list of items),
-	% determine all the modules that it depends upon
-	% (both interface dependencies and also implementation dependencies).
-
-:- pred get_dependencies(item_list, list(string)).
-:- mode get_dependencies(in, out) is det.
+	% get_dependencies(Items, ImportDeps, UseDeps).
+	%	Get the list of modules that a list of items depends on.
+	%	ImportDeps is the list of modules imported using
+	% 	`:- import_module', UseDeps is the list of modules imported
+	%	using `:- use_module'.
+	%
+:- pred get_dependencies(item_list, list(string), list(string)).
+:- mode get_dependencies(in, out, out) is det.
 
 	% Do the importing of the interface files of imported modules.
 
@@ -155,30 +157,42 @@
 	{ get_interface(Items0, yes, InterfaceItems0) },
 	{ term__context_init(Context) },
 	{ varset__init(Varset) },
-	{ get_dependencies(InterfaceItems0, InterfaceDeps) },
+	{ get_dependencies(InterfaceItems0, 
+		InterfaceImportDeps, InterfaceUseDeps) },
 	{ list__append(InterfaceItems0,
 			[module_defn(Varset, imported) - Context],
-			InterfaceItems0a) },
-	{ Module0 = module_imports(ModuleName, [], [], InterfaceItems0a, no) },
+			InterfaceItems1) },
+	{ Module1 = module_imports(ModuleName, [], [], InterfaceItems1, no) },
 		% Get the .int3s that the current .int depends on.
-	process_module_short_interfaces(["mercury_builtin" | InterfaceDeps],
-					".int3", Module0, Module),
-	{ Module = module_imports(_, _, _, InterfaceItems1, Error) },
+	process_module_short_interfaces(
+			["mercury_builtin" | InterfaceImportDeps],
+			".int3", Module1, Module2),
+	{ Module2 = module_imports(_, Direct2, Indirect2,
+			InterfaceItems2, Error2) },
+	{ list__append(InterfaceItems2,
+			[module_defn(Varset, used) - Context],
+			InterfaceItems3) },
+	{ Module3 = module_imports(ModuleName, Direct2, Indirect2,
+			InterfaceItems3, Error2) },
+	process_module_short_interfaces(InterfaceUseDeps,
+			".int3", Module3, Module4),
+
+	{ Module4 = module_imports(_, _, _, InterfaceItems4, Error) },
 	( { Error = yes } ->
 		io__write_strings(["Error reading short interface files.\n",
 				ModuleName, ".int and ",
 				ModuleName, ".int2 not written.\n"])
 	;
 			% Qualify all items.
-		module_qual__module_qualify_items(InterfaceItems1,
-				InterfaceItems2, ModuleName, yes, _, _, _),
+		module_qual__module_qualify_items(InterfaceItems4,
+				InterfaceItems5, ModuleName, yes, _, _, _, _),
 		io__get_exit_status(Status),
 		( { Status \= 0 } ->
 			io__write_strings([ModuleName, ".int not written.\n"])
 		;
-			{ strip_imported_items(InterfaceItems2, [],
-							InterfaceItems3) },
-			check_for_clauses_in_interface(InterfaceItems3,
+			{ strip_imported_items(InterfaceItems5, [],
+							InterfaceItems6) },
+			check_for_clauses_in_interface(InterfaceItems6,
 							InterfaceItems),
 			check_for_no_exports(InterfaceItems, ModuleName),
 			write_interface_file(ModuleName, ".int",
@@ -198,7 +212,7 @@
 	check_for_clauses_in_interface(InterfaceItems0, InterfaceItems),
 	{ get_short_interface(InterfaceItems, ShortInterfaceItems0) },
 	module_qual__module_qualify_items(ShortInterfaceItems0,
-			ShortInterfaceItems, ModuleName, no, _, _, _),
+			ShortInterfaceItems, ModuleName, no, _, _, _, _),
 	write_interface_file(ModuleName, ".int3", ShortInterfaceItems),
 	touch_interface_datestamp(ModuleName, ".date3").
 
@@ -209,9 +223,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) ->
 		list__reverse(Items0, Items)
 	;
 		strip_imported_items(Rest, [Item - Context | Items0], Items)
@@ -364,20 +378,72 @@
 %-----------------------------------------------------------------------------%
 
 grab_imported_modules(ModuleName, Items0, Module, FactDeps, Error) -->
-	{ get_dependencies(Items0, ImportedModules) },
+	{ get_dependencies(Items0, ImportedModules, UsedModules0) },
+
+	{ set__list_to_set(ImportedModules, ImportedSet) },
+	{ set__list_to_set(UsedModules0, UsedSet) },
+
+	{ set__intersect(ImportedSet, UsedSet, BothSet) },
+
+	% Report errors for modules imported using both :- use_module
+	% and :- import_module. Remove the import_module declaration.
+	{ string__append(ModuleName, ".m", FileName) },
+	{ term__context_init(FileName, 0, Context) },
+	( { set__empty(BothSet) } ->
+		{ UsedModules = UsedModules0 }
+	;
+		prog_out__write_context(Context),
+		io__write_string("Warning:"),
+		{ set__to_sorted_list(BothSet, BothList) },
+		( { BothList = [_] } ->
+			io__write_string(" module "),
+			prog_out__write_module_list(BothList),
+			io__write_string(" is ")
+		;
+			io__write_string(" modules "),
+			prog_out__write_module_list(BothList),
+			io__write_string(" are ")
+		),
+		io__write_string("imported using both\n"),
+		prog_out__write_context(Context),
+		io__write_string("  `:- import_module' and `:- use_module' declarations.\n"),
+
+		% Treat the modules with both types of import as if they 
+		% were imported using :- import_module.
+		{ list__delete_elems(UsedModules0, BothList,
+			UsedModules) },
+		globals__io_lookup_bool_option(halt_at_warn, Halt),
+		( { Halt = yes } ->
+			io__set_exit_status(1)
+		;
+			[]
+		)
+	),
+
 	{ get_fact_table_dependencies(Items0, FactDeps) },
 
-		% we add a pseudo-declaration `:- imported' at the end
-		% of the item list, so that make_hlds knows which items
-		% are imported and which are defined in the main module
+		% 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.
 	{ varset__init(VarSet) },
-	{ term__context_init(ModuleName, 0, Context) },
 	{ list__append(Items0,
 		[module_defn(VarSet, imported) - Context], Items1) },
 	{ dir__basename(ModuleName, BaseModuleName) },
-	{ Module0 = module_imports(BaseModuleName, [], [], Items1, no) },
+	{ Module1 = module_imports(BaseModuleName, [], [], Items1, no) },
+
 	process_module_interfaces(["mercury_builtin" | ImportedModules], 
-		[], Module0, Module),
+		[], Module1, Module2),
+	{ Module2 = module_imports(_, Direct2, Indirect2, Items2, Error2) },
+
+		% we add a pseudo-declarations `:- used' at the end
+		% of the item list. Uses of the items with declarations 
+		% following this must be module qualified.
+	{ list__append(Items2,
+		[module_defn(VarSet, used) - Context], Items3) },
+	{ Module3 = module_imports(BaseModuleName, Direct2, Indirect2, 
+		Items3, Error2) },
+	process_module_interfaces(UsedModules, [], Module3, Module),
+
 	{ Module = module_imports(_, _, _, _, Error) }.
 
 %-----------------------------------------------------------------------------%
@@ -1091,9 +1157,13 @@
 	;
 		{ Items = Items0 }
 	),
-	{ get_dependencies(Items, ImplementationDeps0) },
+	{ get_dependencies(Items, ImplImportDeps, ImplUseDeps) },
+	{ list__append(ImplImportDeps, ImplUseDeps, ImplementationDeps0) },
 	{ get_interface(Items, no, InterfaceItems) },
-	{ get_dependencies(InterfaceItems, InterfaceDeps0) },
+	{ get_dependencies(InterfaceItems, InterfaceImportDeps,
+		InterfaceUseDeps) },
+	{ list__append(InterfaceImportDeps, InterfaceUseDeps, 
+		InterfaceDeps0) },
 	{ InterfaceDeps = ["mercury_builtin" | InterfaceDeps0] },
 	{ ImplementationDeps = ["mercury_builtin" | ImplementationDeps0] },
 	{ get_fact_table_dependencies(Items, FactTableDeps) }.
@@ -1214,7 +1284,7 @@
 		globals__io_lookup_bool_option(statistics, Statistics),
 		maybe_report_stats(Statistics),
 
-		{ get_dependencies(Items1, IndirectImports1) },
+		{ get_dependencies(Items1, IndirectImports1, IndirectUses1) },
 		( { Error1 = fatal } ->
 			{ DirectImports1 = DirectImports0 }
 		;
@@ -1222,10 +1292,12 @@
 		),
 		{ list__append(IndirectImports0, IndirectImports1,
 			IndirectImports2) },
+		{ list__append(IndirectImports2, IndirectUses1,
+			IndirectImports3) },
 		{ list__append(Items0, Items1, Items2) },
 		{ Module1 = module_imports(ModuleName, DirectImports1, 
 					OldIndirectImports, Items2, Error2) },
-		process_module_interfaces(Imports, IndirectImports2,
+		process_module_interfaces(Imports, IndirectImports3,
 				Module1, Module)
 	).
 
@@ -1236,7 +1308,21 @@
 :- mode process_module_short_interfaces(in, in, out, di, uo) is det.
 
 process_module_short_interfaces(Imports, Module0, Module) -->
-	process_module_short_interfaces(Imports, ".int2", Module0, Module).
+	{ Module0 = module_imports(ModuleName, DirectImports0,
+		IndirectImports0, Items0, Error0) },
+
+		% 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.
+	{ varset__init(Varset) },
+	{ term__context_init(Context) },
+	{ list__append(Items0, [module_defn(Varset, used) - Context], 
+		Items1) },
+
+	{ Module1 = module_imports(ModuleName, DirectImports0,
+		IndirectImports0, Items1, Error0) },
+
+	process_module_short_interfaces(Imports, ".int2", Module1, Module).
 
 
 :- pred process_module_short_interfaces(list(string), string, 
@@ -1277,7 +1363,7 @@
 		globals__io_lookup_bool_option(statistics, Statistics),
 		maybe_report_stats(Statistics),
 
-		{ get_dependencies(Items1, Imports1) },
+		{ get_dependencies(Items1, Imports1, _Uses1) },
 		{ list__append(Imports, Imports1, Imports2) },
 		{ list__append(Items0, Items1, Items2) },
 		{ IndirectImports1 = [Import | IndirectImports0] },
@@ -1288,22 +1374,31 @@
 
 %-----------------------------------------------------------------------------%
 
-get_dependencies(Items, Deps) :-
-	get_dependencies_2(Items, [], Deps).
+get_dependencies(Items, ImportDeps, UseDeps) :-
+	get_dependencies_2(Items, [], ImportDeps, [], UseDeps).
 
-:- pred get_dependencies_2(item_list, list(string), list(string)).
-:- mode get_dependencies_2(in, in, out) is det.
+:- pred get_dependencies_2(item_list, list(string), list(string), 
+		list(string), list(string)).
+:- mode get_dependencies_2(in, in, out, in, out) is det.
 
-get_dependencies_2([], Deps, Deps).
-get_dependencies_2([Item - _Context | Items], Deps0, Deps) :-
+get_dependencies_2([], ImportDeps, ImportDeps, UseDeps, UseDeps).
+get_dependencies_2([Item - _Context | Items], ImportDeps0, ImportDeps,
+		UseDeps0, UseDeps) :-
 	( 
 		Item = module_defn(_VarSet, import(module(Modules)))
 	->
-		list__append(Deps0, Modules, Deps1)
+		list__append(ImportDeps0, Modules, ImportDeps1),
+		UseDeps1 = UseDeps0
 	;
-		Deps1 = Deps0
+		Item = module_defn(_VarSet, use(module(Modules)))
+	->
+		list__append(UseDeps0, Modules, UseDeps1),
+		ImportDeps1 = ImportDeps0
+	;
+		ImportDeps1 = ImportDeps0,
+		UseDeps1 = UseDeps0
 	),
-	get_dependencies_2(Items, Deps1, Deps).
+	get_dependencies_2(Items, ImportDeps1, ImportDeps, UseDeps1, UseDeps).
 
 %-----------------------------------------------------------------------------%
 	% get the fact table dependencies for a module
@@ -1351,16 +1446,22 @@
 	( Item = module_defn(_, interface) ->
 		Items1 = Items0,
 		InInterface1 = yes
-	; Item = module_defn(_, imported) ->
+	; 
+		Item = module_defn(_, Defn),
+		( Defn = imported
+		; Defn = used
+		)
+	->
 		% module_qual.m needs the :- imported declaration.
-		( IncludeImported = yes ->
-			InInterface1 = yes,
+		( IncludeImported = yes, InInterface0 = yes ->
 			Items1 = [Item - Context | Items0]
 		;
-			InInterface1 = no,
 			Items1 = Items0
-		)
-	; Item = module_defn(_, implementation) ->
+		),
+		InInterface1 = InInterface0
+	;
+		Item = module_defn(_, implementation) 
+	->
 		Items1 = Items0,
 		InInterface1 = no
 	;
@@ -1409,6 +1510,10 @@
 			Items, Imports, NeedsImports) :-
 	ItemAndContext = Item0 - Context,
 	( Item0 = module_defn(_, import(_)) ->
+		Items1 = Items0,
+		Imports1 = [ItemAndContext | Imports0],
+		NeedsImports1 = NeedsImports0
+	; Item0 = module_defn(_, use(_)) ->
 		Items1 = Items0,
 		Imports1 = [ItemAndContext | Imports0],
 		NeedsImports1 = NeedsImports0
Index: module_qual.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/module_qual.m,v
retrieving revision 1.18
diff -u -r1.18 module_qual.m
--- module_qual.m	1997/06/27 04:01:35	1.18
+++ module_qual.m	1997/06/28 05:00:31
@@ -32,28 +32,33 @@
 	% ReportUndefErrors should be no when module qualifying the
 	% short interface.
 :- pred module_qual__module_qualify_items(item_list, item_list,
-		string, bool, int, bool, bool, io__state, io__state).
+		string, bool, mq_info, int, bool, bool, io__state, io__state).
 :- mode module_qual__module_qualify_items(in, out, in, in,
-		out, out, out, di, uo) is det.
+		out, out, out, out, di, uo) is det.
 
 	% This is called from make_hlds.m to qualify the mode of a lambda
 	% expression.
-:- pred module_qual__qualify_mode_list(list(mode), list(mode),
+:- pred module_qual__qualify_lambda_mode_list(list(mode), list(mode),
 		term__context, mq_info, mq_info,
 		io__state, io__state) is det.
-:- mode module_qual__qualify_mode_list(in, out, in, in, out, di, uo) is det.
+:- mode module_qual__qualify_lambda_mode_list(in, out, 
+		in, in, out, di, uo) is det.
 
-:- pred module_qual__qualify_type(type, type, term__context,
+	% This is called from make_hlds.m to qualify an 
+	% explicit type qualification.
+:- pred module_qual__qualify_type_qualification(type, type, term__context,
 		mq_info, mq_info, io__state, io__state).
-:- mode module_qual__qualify_type(in, out, in, in, out, di, uo) is det.
+:- mode module_qual__qualify_type_qualification(in, out, in, in,
+		out, di, uo) is det.
 
 :- type mq_info.
 
-:- pred init_mq_info_module(module_info::in, mq_info::out) is det.
-
 :- pred mq_info_get_num_errors(mq_info::in, int::out) is det.
 :- pred mq_info_get_type_error_flag(mq_info::in, bool::out) is det.
 :- pred mq_info_get_mode_error_flag(mq_info::in, bool::out) is det.
+:- pred mq_info_set_need_qual_flag(mq_info::in, 
+		need_qualifier::in, mq_info::out) is det.
+:- pred mq_info_get_need_qual_flag(mq_info::in, need_qualifier::out) is det.
 
 %-----------------------------------------------------------------------------%
 :- implementation.
@@ -63,7 +68,7 @@
 :- import_module int, list, map, require, set, std_util, string, term, varset.
 
 module_qual__module_qualify_items(Items0, Items, ModuleName, ReportErrors,
-			NumErrors, UndefTypes, UndefModes) -->
+			Info, NumErrors, UndefTypes, UndefModes) -->
 	{ init_mq_info(ReportErrors, Info0) },
 	{ collect_mq_info(Items0, Info0, Info1) },
 	do_module_qualify_items(Items0, Items, Info1, Info),
@@ -78,11 +83,11 @@
 	),
 	{ mq_info_get_num_errors(Info, NumErrors) }.
 
-module_qual__qualify_mode_list(Modes0, Modes, Context, Info0, Info) -->
+module_qual__qualify_lambda_mode_list(Modes0, Modes, Context, Info0, Info) -->
 	{ mq_info_set_error_context(Info0, lambda_expr - Context, Info1) },
 	qualify_mode_list(Modes0, Modes, Info1, Info).
 
-module_qual__qualify_type(Type0, Type, Context, Info0, Info) -->
+module_qual__qualify_type_qualification(Type0, Type, Context, Info0, Info) -->
 	{ mq_info_set_error_context(Info0, type_qual - Context, Info1) },
 	qualify_type(Type0, Type, Info1, Info).
 
@@ -100,7 +105,8 @@
 			bool,	% are there any undefined insts or modes.
 			bool, 	% do we want to report errors.
 			error_context,	% context of the current item.
-			unit	% junk slot
+			need_qualifier	% must uses of the current item be 
+				% explicitly module qualified.
 	).
 		
 	% Pass over the item list collecting all defined type, mode and
@@ -144,7 +150,8 @@
 	),
 	list__length(Params, Arity),
 	mq_info_get_types(Info0, Types0),
-	id_set_insert(SymName - Arity, Types0, Types),
+	mq_info_get_need_qual_flag(Info0, NeedQualifier),
+	id_set_insert(NeedQualifier, SymName - Arity, Types0, Types),
 	mq_info_set_types(Info0, Types, Info).
 
 :- pred add_inst_defn(inst_defn::in, mq_info::in, mq_info::out) is det.
@@ -155,7 +162,8 @@
 	),
 	list__length(Params, Arity),
 	mq_info_get_insts(Info0, Insts0),
-	id_set_insert(SymName - Arity, Insts0, Insts),
+	mq_info_get_need_qual_flag(Info0, NeedQualifier),
+	id_set_insert(NeedQualifier, SymName - Arity, Insts0, Insts),
 	mq_info_set_insts(Info0, Insts, Info).
 
 :- pred add_mode_defn(mode_defn::in, mq_info::in, mq_info::out) is det.
@@ -163,7 +171,8 @@
 add_mode_defn(eqv_mode(SymName, Params, _), Info0, Info) :-
 	list__length(Params, Arity),
 	mq_info_get_modes(Info0, Modes0),
-	id_set_insert(SymName - Arity, Modes0, Modes),
+	mq_info_get_need_qual_flag(Info0, NeedQualifier),
+	id_set_insert(NeedQualifier, SymName - Arity, Modes0, Modes),
 	mq_info_set_modes(Info0, Modes, Info).
 
 	% Update import status.
@@ -176,24 +185,31 @@
 process_module_defn(implementation, Info0, Info) :-
 	mq_info_set_import_status(Info0, local, Info).
 process_module_defn(imported, Info0, Info) :-
-	mq_info_set_import_status(Info0, imported, Info).
+	mq_info_set_import_status(Info0, imported, Info1),
+	mq_info_set_need_qual_flag(Info1, may_be_unqualified, Info).
+process_module_defn(used, Info0, Info) :-
+	mq_info_set_import_status(Info0, imported, Info1),
+	mq_info_set_need_qual_flag(Info1, must_be_qualified, Info).
 process_module_defn(opt_imported, Info0, Info) :-
-	mq_info_set_import_status(Info0, opt_imported, Info).
+	mq_info_set_import_status(Info0, opt_imported, Info1),
+	mq_info_set_need_qual_flag(Info1, must_be_qualified, Info).
 process_module_defn(external(_), Info, Info).
 process_module_defn(end_module(_), Info, Info).
 process_module_defn(export(_), Info, Info).
 process_module_defn(import(Imports), Info0, Info) :-
+	add_interface_imports(Imports, Info0, Info).
+process_module_defn(use(Imports), Info0, Info) :-
+	add_interface_imports(Imports, Info0, Info).
+
+:- pred add_interface_imports(sym_list::in,
+		mq_info::in, mq_info::out) is det.
+
+add_interface_imports(Imports, Info0, Info) :-
 	( Imports = module(ImportedModules) ->
-		( mq_info_get_import_status(Info0, exported) ->
-			mq_info_add_interface_modules(Info0,
-						ImportedModules, Info)
-		;
-			Info = Info0
-		)
+		mq_info_add_interface_modules(Info0, ImportedModules, Info)
 	;
 		Info = Info0
 	).
-process_module_defn(use(_), Info, Info).	% not implemented 
 
 %------------------------------------------------------------------------------
 
@@ -285,15 +301,14 @@
 :- pred update_import_status(module_defn::in, mq_info::in, mq_info::out,
 							bool::out) is det.
 
-update_import_status(opt_imported, Info0, Info, no) :-
-	mq_info_set_import_status(Info0, opt_imported, Info).
+update_import_status(opt_imported, Info, Info, no).
 update_import_status(module(_), Info, Info, yes).
 update_import_status(interface, Info0, Info, yes) :-
 	mq_info_set_import_status(Info0, exported, Info).
 update_import_status(implementation, Info0, Info, yes) :-
 	mq_info_set_import_status(Info0, local, Info).
-update_import_status(imported, Info0, Info, no) :-
-	mq_info_set_import_status(Info0, imported, Info).
+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).
@@ -606,11 +621,7 @@
 		{ Id0 = qualified(Module, Name) - Arity },
 		{ Id = Id0 },
 		( { id_set_search_m_n_a(Ids, Module, Name, Arity) } ->
-			( { mq_info_get_import_status(Info0, exported) } ->
-				{ mq_info_set_module_used(Info0, Module, Info) }
-			;
-				{ Info = Info0 }
-			)
+			{ mq_info_set_module_used(Info0, Module, Info) }
 		;
 			( { mq_info_get_report_error_flag(Info0, yes) } ->
 				{ mq_info_get_error_context(Info0,
@@ -647,12 +658,7 @@
 		; { Modules = [Module] } ->
 			% A unique match for this ID.
 			{ Id = qualified(Module, IdName) - Arity },
-			( { mq_info_get_import_status(Info0, exported) } ->
-				{ mq_info_set_module_used(Info0, Module,
-								Info) }
-			;
-				{ Info = Info0 }
-			)
+			{ mq_info_set_module_used(Info0, Module, Info) }
 		;
 			% There are multiple matches.
 			{ Id = Id0 },
@@ -734,7 +740,7 @@
 	io__write_string("  The possible matches are in modules\n"),
 	prog_out__write_context(Context),
 	io__write_string("  "),
-	write_module_list(Modules),
+	prog_out__write_module_list(Modules),
 	io__write_string(".\n"),
 	globals__io_lookup_bool_option(verbose_errors, Verbose),
 	( { Verbose = yes } ->
@@ -814,7 +820,7 @@
 		;
 			io__write_string("modules ")
 		),
-		write_module_list(UnusedImports),
+		prog_out__write_module_list(UnusedImports),
 		io__write_string("\n"),
 		prog_out__write_context(Context),
 		{ is_or_are(UnusedImports, IsOrAre) },
@@ -833,19 +839,6 @@
 is_or_are([_], "is").
 is_or_are([_, _ | _], "are").
 
-:- pred write_module_list(list(module_name)::in, io__state::di,
-					io__state::uo) is det.
-
-write_module_list([Import1, Import2, Import3 | Imports]) --> 
-	io__write_strings(["`", Import1, "', "]),
-	write_module_list([Import2, Import3 | Imports]).
-write_module_list([Import1, Import2]) -->
-	io__write_strings(["`", Import1, "' and `", Import2 ,"'"]).
-write_module_list([Import]) -->
-	io__write_strings(["`", Import, "'"]).
-write_module_list([]) -->
-	{ error("module_qual:write_module_list") }.
-
 	% Output an error message about an ill-formed type.
 :- pred report_invalid_type(term, error_context, io__state, io__state).
 :- mode report_invalid_type(in, in, di, uo) is det.
@@ -905,22 +898,8 @@
 	ErrorContext = type(unqualified("") - 0) - Context,
 	set__init(InterfaceModules0),
 	id_set_init(Empty),
-	Info0 = mq_info(Empty, Empty, Empty, InterfaceModules0,
-			local, 0, no, no, ReportErrors, ErrorContext, unit).
-
-init_mq_info_module(ModuleInfo, Info0) :-
-	module_info_typeids(ModuleInfo, TypeIds),
-	id_set_init(Empty),
-	list__foldl(id_set_insert, TypeIds, Empty, Types),
-	module_info_instids(ModuleInfo, InstIds),
-	list__foldl(id_set_insert, InstIds, Empty, Insts),
-	module_info_modeids(ModuleInfo, ModeIds),
-	list__foldl(id_set_insert, ModeIds, Empty, Modes),
-	term__context_init(Context),
-	ErrorContext = type(unqualified("") - 0) - Context,
-	set__init(InterfaceModules0),
-	Info0 = mq_info(Types, Insts, Modes, InterfaceModules0,
-		local, 0, no, no, yes, ErrorContext, unit).
+	Info0 = mq_info(Empty, Empty, Empty, InterfaceModules0, local, 0,
+		no, no, ReportErrors, ErrorContext, may_be_unqualified).
 
 :- pred mq_info_get_types(mq_info::in, type_id_set::out) is det.
 :- pred mq_info_get_insts(mq_info::in, inst_id_set::out) is det.
@@ -933,7 +912,6 @@
 % :- pred mq_info_get_mode_error_flag(mq_info::in, bool::out) is det.
 :- pred mq_info_get_report_error_flag(mq_info::in, bool::out) is det.
 :- pred mq_info_get_error_context(mq_info::in, error_context::out) is det.
-:- pred mq_info_get_junk(mq_info::in, unit::out) is det.
 
 mq_info_get_types(mq_info(Types, _,_,_,_,_,_,_,_,_,_), Types).
 mq_info_get_insts(mq_info(_, Insts, _,_,_,_,_,_,_,_,_), Insts).
@@ -946,18 +924,19 @@
 						ModeError).
 mq_info_get_report_error_flag(mq_info(_,_,_,_,_,_,_,_, Report,_,_), Report).
 mq_info_get_error_context(mq_info(_,_,_,_,_,_,_,_,_, Context,_), Context).
-mq_info_get_junk(mq_info(_,_,_,_,_,_,_,_,_,_,Junk), Junk).
+mq_info_get_need_qual_flag(mq_info(_,_,_,_,_,_,_,_,_,_,UseModule), UseModule).
 
 :- pred mq_info_set_types(mq_info::in, type_id_set::in, mq_info::out) is det.
 :- pred mq_info_set_insts(mq_info::in, inst_id_set::in, mq_info::out) is det.
 :- pred mq_info_set_modes(mq_info::in, mode_id_set::in, mq_info::out) is det.
+:- pred mq_info_set_interface_modules(mq_info::in, set(module_name)::in,
+						mq_info::out) is det.
 :- pred mq_info_set_import_status(mq_info::in, import_status::in,
 						mq_info::out) is det.
 :- pred mq_info_set_type_error_flag(mq_info::in, mq_info::out) is det.
 :- pred mq_info_set_mode_error_flag(mq_info::in, mq_info::out) is det.
 :- pred mq_info_set_error_context(mq_info::in, error_context::in,
 						mq_info::out) is det.
-:- pred mq_info_set_junk(mq_info::in, unit::in, mq_info::out) is det.
 
 mq_info_set_types(mq_info(_, B,C,D,E,F,G,H,I,J,K), Types,
 		mq_info(Types, B,C,D,E,F,G,H,I,J,K)).
@@ -965,6 +944,8 @@
 		mq_info(A, Insts, C,D,E,F,G,H,I,J,K)).
 mq_info_set_modes(mq_info(A,B,_,D,E,F,G,H,I,J,K), Modes,
 		mq_info(A,B, Modes, D,E,F,G,H,I,J,K)).
+mq_info_set_interface_modules(mq_info(A,B,C,_,E,F,G,H,I,J,K), Modules,
+		mq_info(A,B,C, Modules, E,F,G,H,I,J,K)).
 mq_info_set_import_status(mq_info(A,B,C,D,_,F,G,H,I,J,K), Status,
 		mq_info(A,B,C,D, Status, F,G,H,I,J,K)).
 mq_info_set_type_error_flag(mq_info(A,B,C,D,E,F, _, H,I,J,K),
@@ -973,8 +954,8 @@
 		mq_info(A,B,C,D,E,F,G, yes, I,J,K)).
 mq_info_set_error_context(mq_info(A,B,C,D,E,F,G,H,I,_,K), Context,
 		mq_info(A,B,C,D,E,F,G,H,I, Context,K)).
-mq_info_set_junk(mq_info(A,B,C,D,E,F,G,H,I,J,_), Junk,
-		mq_info(A,B,C,D,E,F,G,H,I,J, Junk)).
+mq_info_set_need_qual_flag(mq_info(A,B,C,D,E,F,G,H,I,J,_), Flag,
+		mq_info(A,B,C,D,E,F,G,H,I,J, Flag)).
 
 :- pred mq_info_incr_errors(mq_info::in, mq_info::out) is det.
 
@@ -991,24 +972,44 @@
 mq_info_set_error_flag(Info0, inst_id, Info) :-
 	mq_info_set_mode_error_flag(Info0, Info).
 
+	% If the current item is in the interface, remove its module 
+	% name from the list of modules not used in the interface.
 :- pred mq_info_set_module_used(mq_info::in, module_name::in,
 						mq_info::out) is det.
+
+mq_info_set_module_used(Info0, Module, Info) :-
+	( mq_info_get_import_status(Info0, exported) ->
+		mq_info_get_interface_modules(Info0, Modules0),
+		set__delete(Modules0, Module, Modules),
+		mq_info_set_interface_modules(Info0, Modules, Info)
+	;
+		Info = Info0
+	).
+
+	% Add to the list of modules imported in the interface.
 :- pred mq_info_add_interface_modules(mq_info::in, list(module_name)::in,
 						mq_info::out) is det.
 
-mq_info_set_module_used(mq_info(A,B,C,Modules0,E,F,G,H,I,J,K), Module,
-		mq_info(A,B,C, Modules, E,F,G,H,I,J,K)) :-
-	set__delete(Modules0, Module, Modules).
-mq_info_add_interface_modules(mq_info(A,B,C,Modules0, E,F,G,H,I,J,K),
-		NewModules, mq_info(A,B,C, Modules, E,F,G,H,I,J,K)) :-
-	set__insert_list(Modules0, NewModules, Modules).
+mq_info_add_interface_modules(Info0, NewModules, Info) :-
+	( mq_info_get_import_status(Info0, exported) ->
+		mq_info_get_interface_modules(Info0, Modules0),
+		set__insert_list(Modules0, NewModules, Modules),
+		mq_info_set_interface_modules(Info0, Modules, Info)
+	;
+		Info = Info0
+	).
 
 %----------------------------------------------------------------------------%
 % Define a type for representing sets of ids during module qualification
 % to allow efficient retrieval of all the modules which define an id
 % with a certain name and arity.
 
-:- type id_set == map(pair(string, arity), set(module_name)).
+% The first set of module_names can be used without module qualifiers,
+% items from the second set can only be used with module qualifiers.
+% Items from modules imported with a :- use_module declaration and from `.opt'
+% files should go into the second set.
+:- type id_set == map(pair(string, arity), pair(set(module_name))).
+
 :- type type_id_set == id_set.
 :- type mode_id_set == id_set.
 :- type inst_id_set == id_set.
@@ -1020,25 +1021,36 @@
 
 	% Insert an id into an id_set, aborting with an error if the
 	% id is not module qualified.
-:- pred id_set_insert(id::in, id_set::in, id_set::out) is det.
+:- pred id_set_insert(need_qualifier::in, id::in, 
+		id_set::in, id_set::out) is det.
 
-id_set_insert(unqualified(_) - _, _, _) :-
+id_set_insert(_, unqualified(_) - _, _, _) :-
 	error("module_qual:id_set_insert - unqualified id").
-id_set_insert(qualified(Module, Name) - Arity, IdSet0, IdSet) :-
-	( map__search(IdSet0, Name - Arity, Modules0) ->
-		Modules1 = Modules0 
+id_set_insert(NeedQualifier, qualified(Module, Name) - Arity, IdSet0, IdSet) :-
+	( map__search(IdSet0, Name - Arity, ImportModules0 - UseModules0) ->
+		ImportModules1 = ImportModules0,
+		UseModules1 = UseModules0
+	;
+		set__init(ImportModules1),
+		set__init(UseModules1)
+	),
+	(
+		NeedQualifier = must_be_qualified,
+		set__insert(UseModules1, Module, UseModules),
+		ImportModules = ImportModules1
 	;
-		set__init(Modules1)
+		NeedQualifier = may_be_unqualified,
+		set__insert(ImportModules1, Module, ImportModules),
+		UseModules = UseModules1
 	),
-	set__insert(Modules1, Module, Modules),
-	map__set(IdSet0, Name - Arity, Modules, IdSet).
+	map__set(IdSet0, Name - Arity, ImportModules - UseModules, IdSet).
 
 :- pred id_set_search_name_arity(id_set::in, string::in, int::in,
 				list(module_name)::out) is det.
 
 id_set_search_name_arity(IdSet0, Name, Arity, Modules) :-
-	( map__search(IdSet0, Name - Arity, ModuleSet) ->
-		set__to_sorted_list(ModuleSet, Modules)
+	( map__search(IdSet0, Name - Arity, ImportModules - _) ->
+		set__to_sorted_list(ImportModules, Modules)
 	;
 		Modules = []
 	).
@@ -1047,7 +1059,11 @@
 			 	string::in, int::in) is semidet.
 
 id_set_search_m_n_a(IdSet0, Module, Name, Arity) :-
-	map__search(IdSet0, Name - Arity, ModuleSet),
-	set__member(Module, ModuleSet).
+	map__search(IdSet0, Name - Arity, ImportModules - UseModules),
+	( 
+		set__member(Module, ImportModules)
+	;
+		set__member(Module, UseModules)
+	).
 
 %----------------------------------------------------------------------------%
Index: prog_data.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_data.m,v
retrieving revision 1.19
diff -u -r1.19 prog_data.m
--- prog_data.m	1997/06/27 04:01:36	1.19
+++ prog_data.m	1997/06/28 04:50:33
@@ -18,8 +18,8 @@
 
 :- interface.
 
-:- import_module hlds_pred.
-:- import_module list, varset, term, std_util.
+:- import_module hlds_data, hlds_pred.
+:- import_module bool, list, map, varset, term, std_util.
 
 %-----------------------------------------------------------------------------%
 
@@ -356,12 +356,17 @@
 			;	imported
 				% this is used internally by the compiler,
 				% to identify declarations which originally
-				% came from some other module
+				% came from some other module.
+			;	used
+				% 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.
 			;	external(sym_name_specifier)
+			;	opt_imported
 				% this is used internally by the compiler,
 				% to identify items which originally
 				% came from a .opt file
-			;	opt_imported
 			;	end_module(module_name)
 			;	export(sym_list)
 			;	import(sym_list)
@@ -408,5 +413,11 @@
 :- type module_specifier ==	string.
 :- type module_name 	== 	string.
 :- type arity		==	int.
+
+	% Describes whether an item can be used without an 
+	% explicit module qualifier.
+:- type need_qualifier
+	--->	must_be_qualified
+	;	may_be_unqualified.
 
 %-----------------------------------------------------------------------------%

Index: reference_manual.texi
===================================================================
RCS file: /home/staff/zs/imp/mercury/doc/reference_manual.texi,v
retrieving revision 1.52
diff -u -r1.52 reference_manual.texi
--- reference_manual.texi	1997/06/27 04:02:12	1.52
+++ reference_manual.texi	1997/06/28 05:25:54
@@ -340,6 +340,7 @@
 :- interface
 :- implementation
 :- import_module
+:- use_module
 :- external
 :- end_module
 @end example
@@ -2263,20 +2264,21 @@
 @c ===> no
 
 If a module wishes to make use of entities exported by other modules,
-then it must explicitly import those modules
-using one or more @code{import_module} declarations.
-These declarations may occur
-either in the interface or the implementation section.
-If the imported entities are used in the interface section,
-then the corresponding @code{import_module} declaration must
-also be in the interface section.  If the imported entities are only
-used in the implementation section, the @code{import_module}
-declaration should be in the implementation section.
+then it must explicitly import those modules using one or more 
+ at code{import_module} or @code{use_module} declarations.
+These declarations may occur either in the interface or the implementation 
+section. If the imported entities are used in the interface section,
+then the corresponding @code{import_module} or @code{use_module}
+declaration must also be in the interface section. If the imported 
+entities are only used in the implementation section, the 
+ at code{import_module} or @code{use_module} declaration should be in 
+the implementation section.
 
 Declarations, predicate calls, types, modes and insts
 can be explicitly module qualified using the `:' operator,
 i.e. @code{module:name}. This is useful both for readability and
-for resolving name conflicts.
+for resolving name conflicts. Uses of entities imported using 
+ at code{use_module} declarations @emph{must} be explicitly module qualified.
 
 Certain optimizations require information or source code for predicates
 defined in other modules to be as effective as possible. At the moment,
@@ -2766,11 +2768,7 @@
 with name @var{Name} and arity @var{Arity} should be inlined.
 
 The current Mercury implementation is smart enough to inline many
-simple predicates even without this hint.  However, in the current
-Mercury implementation, cross-module inlining is not yet supported, so
-if a predicate for which there is an @samp{inline} pragma is called
-from a module other than the one it is defined in, the compiler will
-ignore the hint.
+simple predicates even without this hint.
 
 @node Preventing Inlining
 @section Preventing Inlining



More information about the developers mailing list