For review: improve undefined pred/symbol error message

Thomas Charles CONWAY conway at cs.mu.OZ.AU
Tue Sep 22 11:46:08 AEST 1998


Hi

Could someone please review this change?
Since it only changes an error message (for the better ;-) we may
want to include it in the forthcoming release. Does it constitute
a `new feature', and therefore should it be postponed?

(See a separate message for the test case)
-- 
Thomas Conway <conway at cs.mu.oz.au>
Nail here [] for new monitor.  )O+


Keep track of which modules have been imported as 'local' or 'exported'
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 retreiving 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 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 01:09:05
@@ -222,9 +222,15 @@
 	( { module_defn_update_import_status(ModuleDefn, Status1) } ->
 		{ Status = Status1 },
 		{ Module = Module0 }
-	; { ModuleDefn = import(module(_)) } ->
+	; { ModuleDefn = import(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 = use(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