[m-dev.] For review: improve undefined pred/symbol error message

Thomas Charles CONWAY conway at cs.mu.OZ.AU
Tue Sep 22 15:07:30 AEST 1998


Fergus Henderson, you write:
> Please post another diff.

Having read the stuff on include_module, it looks like this change
isn't affected by it, so here's a revised log message and diff.

-- 
Thomas Conway <conway at cs.mu.oz.au>
Nail here [] for new monitor.  )O+


Keep track of which modules have been imported directly by the current module
so that later in type checking, if an explicitly qualified name is undefined,
we can issue an error message that gives a hint if the module has not been
imported.

compiler/hlds_module.m:
	Add a pair of predicates for accumulating and retrieving the
	imported module specifiers.
	Add a field to module_sub_info to hold the set of imported
	`module_specifier's.

compiler/make_hlds.m:
	Add the module_specifier list to the set in the module_info if
	appropriate.

compiler/typecheck.m:
	When reporting undefined pred/symbol errors, if the symbol is
	explicitly qualified, but the module isn't directly imported
	then add a hint to that effect to the error message.

cvs diff: Diffing .
Index: hlds_module.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_module.m,v
retrieving revision 1.35
diff -u -r1.35 hlds_module.m
--- hlds_module.m	1998/07/20 10:00:49	1.35
+++ hlds_module.m	1998/09/22 00:11:36
@@ -170,6 +170,14 @@
 :- pred module_info_set_cell_count(module_info, int, module_info).
 :- mode module_info_set_cell_count(in, in, out) is det.
 
+:- pred module_add_imported_module_specifiers(list(module_specifier),
+		module_info, module_info).
+:- mode module_add_imported_module_specifiers(in, in, out) is det.
+
+:- pred module_info_get_imported_module_specifiers(module_info,
+		set(module_specifier)).
+:- mode module_info_get_imported_module_specifiers(in, out) is det.
+
 %-----------------------------------------------------------------------------%
 
 :- pred module_info_name(module_info, module_name).
@@ -401,6 +409,10 @@
 :- pred module_sub_get_model_non_pragma_count(module_sub_info, int).
 :- mode module_sub_get_model_non_pragma_count(in, out) is det.
 
+:- pred module_sub_get_imported_module_specifiers(module_sub_info,
+		set(module_specifier)).
+:- mode module_sub_get_imported_module_specifiers(in, out) is det.
+
 :- pred module_sub_set_c_header_info(module_sub_info, c_header_info,
 	module_sub_info).
 :- mode module_sub_set_c_header_info(in, in, out) is det.
@@ -443,6 +455,10 @@
 	module_sub_info).
 :- mode module_sub_set_model_non_pragma_count(in, in, out) is det.
 
+:- pred module_sub_set_imported_module_specifiers(module_sub_info,
+		set(module_specifier), module_sub_info).
+:- mode module_sub_set_imported_module_specifiers(in, in, out) is det.
+
 :- type module_info
 	--->	module(
 			module_sub_info,
@@ -486,8 +502,11 @@
 					% predicates in the current
 					% module which has been exported
 					% in .opt files.
-			int		% number of the structure types defined
+			int,		% number of the structure types defined
 					% so far for model_non pragma C codes
+			set(module_specifier)
+					% All the imported module specifiers
+					% (used during type checking).
 		).
 
 	% A predicate which creates an empty module
@@ -506,8 +525,9 @@
 	map__init(ClassTable),
 	map__init(InstanceTable),
 	map__init(SuperClassTable),
+	set__init(ModuleNames),
 	ModuleSubInfo = module_sub(Name, Globals, [], [], no, 0, 0, [], 
-		[], [], StratPreds, UnusedArgInfo, 0),
+		[], [], StratPreds, UnusedArgInfo, 0, ModuleNames),
 	ModuleInfo = module(ModuleSubInfo, PredicateTable, Requests,
 		UnifyPredMap, ContinuationInfo, Types, Insts, Modes, Ctors,
 		ClassTable, SuperClassTable, InstanceTable, 0).
@@ -537,8 +557,11 @@
 %					% predicates in the current
 %					% module which has been exported
 %					% in .opt files.
-% M			int		% number of the structure types defined
+% M			int,		% number of the structure types defined
 %					% so far for model_non pragma C codes
+% N			set(module_name)
+%					% All the imported module names
+%					% (used during type checking).
 %		).
 
 %-----------------------------------------------------------------------------%
@@ -546,91 +569,98 @@
 	% Various predicates which access the module_sub_info data structure.
 
 module_sub_get_name(MI0, A) :-
-	MI0 = module_sub(A, _, _, _, _, _, _, _, _, _, _, _, _).
+	MI0 = module_sub(A, _, _, _, _, _, _, _, _, _, _, _, _, _).
 
 module_sub_get_globals(MI0, B) :-
-	MI0 = module_sub(_, B, _, _, _, _, _, _, _, _, _, _, _).
+	MI0 = module_sub(_, B, _, _, _, _, _, _, _, _, _, _, _, _).
 
 module_sub_get_c_header_info(MI0, C) :-
-	MI0 = module_sub(_, _, C, _, _, _, _, _, _, _, _, _, _).
+	MI0 = module_sub(_, _, C, _, _, _, _, _, _, _, _, _, _, _).
 
 module_sub_get_c_body_info(MI0, D) :-
-	MI0 = module_sub(_, _, _, D, _, _, _, _, _, _, _, _, _).
+	MI0 = module_sub(_, _, _, D, _, _, _, _, _, _, _, _, _, _).
 
 module_sub_get_maybe_dependency_info(MI0, E) :-
-	MI0 = module_sub(_, _, _, _, E, _, _, _, _, _, _, _, _).
+	MI0 = module_sub(_, _, _, _, E, _, _, _, _, _, _, _, _, _).
 
 module_sub_get_num_errors(MI0, F) :-
-	MI0 = module_sub(_, _, _, _, _, F, _, _, _, _, _, _, _).
+	MI0 = module_sub(_, _, _, _, _, F, _, _, _, _, _, _, _, _).
 
 module_sub_get_lambda_count(MI0, G) :-
-	MI0 = module_sub(_, _, _, _, _, _, G, _, _, _, _, _, _).
+	MI0 = module_sub(_, _, _, _, _, _, G, _, _, _, _, _, _, _).
 
 module_sub_get_pragma_exported_procs(MI0, H) :-
-	MI0 = module_sub(_, _, _, _, _, _, _, H, _, _, _, _, _).
+	MI0 = module_sub(_, _, _, _, _, _, _, H, _, _, _, _, _, _).
 
 module_sub_get_base_gen_infos(MI0, I) :-
-	MI0 = module_sub(_, _, _, _, _, _, _, _, I, _, _, _, _).
+	MI0 = module_sub(_, _, _, _, _, _, _, _, I, _, _, _, _, _).
 
 module_sub_get_base_gen_layouts(MI0, J) :-
-	MI0 = module_sub(_, _, _, _, _, _, _, _, _, J, _, _, _).
+	MI0 = module_sub(_, _, _, _, _, _, _, _, _, J, _, _, _, _).
 
 module_sub_get_stratified_preds(MI0, K) :-
-	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, K, _, _).
+	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, K, _, _, _).
 
 module_sub_get_unused_arg_info(MI0, L) :-
-	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, _, L, _).
+	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, _, L, _, _).
 
 module_sub_get_model_non_pragma_count(MI0, M) :-
-	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, _, _, M).
+	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, _, _, M, _).
+
+module_sub_get_imported_module_specifiers(MI0, N) :-
+	MI0 = module_sub(_, _, _, _, _, _, _, _, _, _, _, _, _, N).
 
 %-----------------------------------------------------------------------------%
 
 	% Various predicates which modify the module_sub_info data structure.
 
 module_sub_set_c_header_info(MI0, C, MI) :-
-	MI0 = module_sub(A, B, _, D, E, F, G, H, I, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, _, D, E, F, G, H, I, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_c_body_info(MI0, D, MI) :-
-	MI0 = module_sub(A, B, C, _, E, F, G, H, I, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, _, E, F, G, H, I, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_maybe_dependency_info(MI0, E, MI) :-
-	MI0 = module_sub(A, B, C, D, _, F, G, H, I, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, _, F, G, H, I, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_num_errors(MI0, F, MI) :-
-	MI0 = module_sub(A, B, C, D, E, _, G, H, I, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, _, G, H, I, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_lambda_count(MI0, G, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, _, H, I, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, _, H, I, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_pragma_exported_procs(MI0, H, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, G, _, I, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, G, _, I, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_base_gen_infos(MI0, I, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, G, H, _, J, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, G, H, _, J, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_base_gen_layouts(MI0, J, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, G, H, I, _, K, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, G, H, I, _, K, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_stratified_preds(MI0, K, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, _, L, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, _, L, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_unused_arg_info(MI0, L, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, K, _, M),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, K, _, M, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 module_sub_set_model_non_pragma_count(MI0, M, MI) :-
-	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, _),
-	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M).
+	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, _, N),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
+
+module_sub_set_imported_module_specifiers(MI0, N, MI) :-
+	MI0 = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, _),
+	MI  = module_sub(A, B, C, D, E, F, G, H, I, J, K, L, M, N).
 
 %-----------------------------------------------------------------------------%
 
@@ -810,6 +840,10 @@
 	module_info_get_sub_info(MI0, MS0),
 	module_sub_get_model_non_pragma_count(MS0, M).
 
+module_info_get_imported_module_specifiers(MI0, S) :-
+	module_info_get_sub_info(MI0, MS0),
+	module_sub_get_imported_module_specifiers(MS0, S).
+
 %-----------------------------------------------------------------------------%
 
 	% Various predicates which modify the module_sub_info data structure
@@ -868,6 +902,13 @@
 module_info_set_model_non_pragma_count(MI0, M, MI) :-
 	module_info_get_sub_info(MI0, MS0),
 	module_sub_set_model_non_pragma_count(MS0, M, MS),
+	module_info_set_sub_info(MI0, MS, MI).
+
+module_add_imported_module_specifiers(Ss, MI0, MI) :-
+	module_info_get_sub_info(MI0, MS0),
+	module_sub_get_imported_module_specifiers(MS0, SpecSet0),
+	set__insert_list(SpecSet0, Ss, SpecSet),
+	module_sub_set_imported_module_specifiers(MS0, SpecSet, MS),
 	module_info_set_sub_info(MI0, MS, MI).
 
 %-----------------------------------------------------------------------------%
Index: make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.272
diff -u -r1.272 make_hlds.m
--- make_hlds.m	1998/09/15 07:30:50	1.272
+++ make_hlds.m	1998/09/22 04:45:03
@@ -222,12 +222,24 @@
 	( { module_defn_update_import_status(ModuleDefn, Status1) } ->
 		{ Status = Status1 },
 		{ Module = Module0 }
-	; { ModuleDefn = import(module(_)) } ->
+	; { ModuleDefn = import(module(Specifiers)) } ->
 		{ Status = Status0 },
-		{ Module = Module0 }
-	; { ModuleDefn = use(module(_)) } ->
+		{ Status = item_status(IStat, _) },
+		( { IStat = local ; IStat = exported } ->
+			{ module_add_imported_module_specifiers(Specifiers,
+				Module0, Module) }
+		;
+			{ Module = Module0 }
+		)
+	; { ModuleDefn = use(module(Specifiers)) } ->
 		{ Status = Status0 },
-		{ Module = Module0 }
+		{ Status = item_status(IStat, _) },
+		( { IStat = local ; IStat = exported } ->
+			{ module_add_imported_module_specifiers(Specifiers,
+				Module0, Module) }
+		;
+			{ Module = Module0 }
+		)
 	; { ModuleDefn = include_module(_) } ->
 		{ Status = Status0 },
 		{ Module = Module0 }
Index: typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/typecheck.m,v
retrieving revision 1.246
diff -u -r1.246 typecheck.m
--- typecheck.m	1998/09/18 02:20:43	1.246
+++ typecheck.m	1998/09/22 01:34:50
@@ -4680,7 +4680,33 @@
 	;
 		io__write_string("  error: undefined predicate `"),
 		hlds_out__write_pred_call_id(PredCallId),
-		io__write_string("'.\n")
+		io__write_string("'"),
+		( { PredName = qualified(ModQual, _) } ->
+			maybe_report_missing_import(TypeCheckInfo, ModQual)
+		;
+			io__write_string(".\n")
+		)
+	).
+
+:- pred maybe_report_missing_import(typecheck_info, module_specifier,
+		io__state, io__state).
+:- mode maybe_report_missing_import(typecheck_info_no_io, in, di, uo) is det.
+
+maybe_report_missing_import(TypeCheckInfo, ModuleQualifier) -->
+	{ typecheck_info_get_module_info(TypeCheckInfo, ModuleInfo) },
+	{ module_info_get_imported_module_specifiers(ModuleInfo,
+		ImportedModules) },
+	(
+		{ \+ set__member(ModuleQualifier, ImportedModules) }
+	->
+		io__write_string("\n"),
+		{ typecheck_info_get_context(TypeCheckInfo, Context) },
+		prog_out__write_context(Context),
+		io__write_string("  (the module `"),
+		mercury_output_bracketed_sym_name(ModuleQualifier),
+		io__write_string("' has not been imported).\n")
+	;
+		io__write_string(".\n")
 	).
 
 :- pred report_error_func_instead_of_pred(typecheck_info, pred_call_id,
@@ -4871,7 +4897,16 @@
 			{ strip_builtin_qualifier_from_cons_id(Functor, 
 				Functor1) },
 			hlds_out__write_cons_id(Functor1),
-			io__write_string("'.\n")
+			io__write_string("'"),
+			(
+				{ Functor = cons(Constructor, _) },
+				{ Constructor = qualified(ModQual, _) }
+			->
+				maybe_report_missing_import(TypeCheckInfo,
+					ModQual)
+			;
+				io__write_string(".\n")
+			)
 		)
 	).
 
cvs diff: Diffing notes



More information about the developers mailing list