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

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


Fergus Henderson, you write:
> > There is no `import_status' value that indicates symbols
> > inherited from a parent module. How do you determine them?
> > Is the solution just to check to see if the given module
> > qualifier is a parent of any of the current module?
> 
> Yes, that would work (s/parent/ancestor/).
> 
> modules.m has a predicate get_ancestors/2.
> 

Okay. Try this, then.
-- 
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 imported (and isn't
	a parent of the current module) 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 05:55:55
@@ -159,7 +159,7 @@
 
 :- implementation.
 
-:- import_module hlds_goal, prog_util, type_util, code_util.
+:- import_module hlds_goal, prog_util, type_util, modules, code_util.
 :- import_module prog_data, prog_io, prog_io_util, prog_out, hlds_out.
 :- import_module mercury_to_mercury, mode_util, options, getopt, globals.
 :- import_module passes_aux, clause_to_proc, special_pred, inst_match.
@@ -4680,7 +4680,36 @@
 	;
 		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_name(ModuleInfo, ThisModule) },
+	{ module_info_get_imported_module_specifiers(ModuleInfo,
+		ImportedModules) },
+	(
+		{ \+ set__member(ModuleQualifier, ImportedModules) },
+		{ get_ancestors(ThisModule, ParentModules) },
+		{ \+ list__member(ModuleQualifier, ParentModules) }
+	->
+		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 +4900,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