diff: avoid spurious warnings for unbound type vars

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Mar 6 00:08:53 AEDT 1999


The following diff fixes spurious errors and warnings that would result
in many cases.  Type inference stops as soon as any pass gets any type
errors, and so it may leave some type variables still not yet bound.
Checking for unbound type variables after that therefore results in 
spurious diagnostics that are just flow-on messages caused by the
earlier error.

--------------------

Avoid some spurious flow-on diagnostics.

compiler/mercury_compile.m:
	Pass down a boolean indicating whether we got any type errors
	to purity.m.

compiler/purity.m:
	Only call post_typecheck__check_type_bindings if we didn't get
	any type errors, because if we did get any type errors, then
	calling check_type_bindings may lead to a lot of spurious
	diagnostics.

tests/invalid/types.err_exp:
tests/invalid/errors2.err_exp:
	Update the expected error messages for these test cases to
	reflect the fact that we no longer issue warnings about unbound
	type variables in these cases.

Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.117
diff -u -r1.117 mercury_compile.m
--- mercury_compile.m	1998/12/06 23:43:45	1.117
+++ mercury_compile.m	1999/03/03 22:19:29
@@ -705,7 +705,8 @@
 	        %
 	        % Run purity checking
 	        %
-		mercury_compile__puritycheck(HLDS3, Verbose, Stats, HLDS4),
+		mercury_compile__puritycheck(FoundTypeError, HLDS3,
+			Verbose, Stats, HLDS4),
 		mercury_compile__maybe_dump_hlds(HLDS4, "04", "puritycheck"),
 
 	        %
@@ -1252,13 +1253,13 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-:- pred mercury_compile__puritycheck(module_info, bool, bool,
+:- pred mercury_compile__puritycheck(bool, module_info, bool, bool,
 				module_info, io__state, io__state).
-:- mode mercury_compile__puritycheck(in, in, in, out, di, uo) is det.
+:- mode mercury_compile__puritycheck(in, in, in, in, out, di, uo) is det.
 
-mercury_compile__puritycheck(HLDS0, Verbose, Stats, HLDS) -->
+mercury_compile__puritycheck(FoundTypeError, HLDS0, Verbose, Stats, HLDS) -->
 	{ module_info_num_errors(HLDS0, NumErrors0) },
-	puritycheck(HLDS0, HLDS),
+	puritycheck(FoundTypeError, HLDS0, HLDS),
 	{ module_info_num_errors(HLDS, NumErrors) },
 	( { NumErrors \= NumErrors0 } ->
 		maybe_write_string(Verbose,
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.12
diff -u -r1.12 purity.m
--- purity.m	1998/11/20 04:09:05	1.12
+++ purity.m	1999/03/04 00:14:05
@@ -80,7 +80,7 @@
 :- interface.
 
 :- import_module hlds_module, hlds_goal.
-:- import_module io.
+:- import_module io, bool.
 
 :- type purity		--->	pure
 			;	(semipure)
@@ -88,8 +88,11 @@
 
 
 %  Purity check a whole module.
-:- pred puritycheck(module_info, module_info, io__state, io__state).
-:- mode puritycheck(in, out, di, uo) is det.
+%  The first argument specifies whether there were any type
+%  errors (if so, we suppress some diagnostics in post_typecheck.m
+%  because they are usually spurious).
+:- pred puritycheck(bool, module_info, module_info, io__state, io__state).
+:- mode puritycheck(in, in, out, di, uo) is det.
 
 %  Sort of a "maximum" for impurity.
 :- pred worst_purity(purity, purity, purity).
@@ -146,14 +149,14 @@
 %				Public Predicates
 
 
-puritycheck(HLDS0, HLDS) -->
+puritycheck(FoundTypeError, HLDS0, HLDS) -->
 	globals__io_lookup_bool_option(statistics, Statistics),
 	globals__io_lookup_bool_option(verbose, Verbose),
 	io__stderr_stream(StdErr),
 	io__set_output_stream(StdErr, OldStream),
 
 	maybe_write_string(Verbose, "% Purity-checking clauses...\n"),
-	check_preds_purity(HLDS0, HLDS),
+	check_preds_purity(FoundTypeError, HLDS0, HLDS),
 	maybe_report_stats(Statistics),
 
 	io__set_output_stream(OldStream, _).
@@ -233,25 +236,27 @@
 %-----------------------------------------------------------------------------%
 %	 Purity-check the code for all the predicates in a module
 
-:- pred check_preds_purity(module_info, module_info, io__state, io__state).
-:- mode check_preds_purity(in, out, di, uo) is det.
+:- pred check_preds_purity(bool, module_info, module_info,
+			io__state, io__state).
+:- mode check_preds_purity(in, in, out, di, uo) is det.
 
-check_preds_purity(ModuleInfo0, ModuleInfo) -->
+check_preds_purity(FoundTypeError, ModuleInfo0, ModuleInfo) -->
 	{ module_info_predids(ModuleInfo0, PredIds) },
-	check_preds_purity_2(PredIds, ModuleInfo0, ModuleInfo1, 0, NumErrors),
+	check_preds_purity_2(PredIds, FoundTypeError, ModuleInfo0,
+		ModuleInfo1, 0, NumErrors),
 	{ module_info_num_errors(ModuleInfo1, Errs0) },
 	{ Errs is Errs0 + NumErrors },
 	{ module_info_set_num_errors(ModuleInfo1, Errs, ModuleInfo) }.
 
 
-:- pred check_preds_purity_2(list(pred_id), module_info, module_info,
+:- pred check_preds_purity_2(list(pred_id), bool, module_info, module_info,
 			int, int, io__state, io__state).
-:- mode check_preds_purity_2(in, in, out, in, out, di, uo) is det.
+:- mode check_preds_purity_2(in, in, in, out, in, out, di, uo) is det.
 
-check_preds_purity_2([], ModuleInfo, ModuleInfo,
+check_preds_purity_2([], _, ModuleInfo, ModuleInfo,
 		NumErrors, NumErrors) --> [].
-check_preds_purity_2([PredId | PredIds], ModuleInfo0, ModuleInfo,
-		NumErrors0, NumErrors) -->
+check_preds_purity_2([PredId | PredIds], FoundTypeError, ModuleInfo0,
+		ModuleInfo, NumErrors0, NumErrors) -->
 	{ module_info_preds(ModuleInfo0, Preds0) },
 	{ map__lookup(Preds0, PredId, PredInfo0) },
 	(	
@@ -264,9 +269,19 @@
 	;
 		write_pred_progress_message("% Purity-checking ", PredId,
 					    ModuleInfo0),
-		post_typecheck__check_type_bindings(PredId, PredInfo0,
-				PredInfo1, ModuleInfo0,
-				UnboundTypeErrsInThisPred),
+		%
+		% Only check the type bindings if we didn't get any
+		% type errors already; this avoids a lot of spurious
+		% diagnostics.
+		%
+		( { FoundTypeError = no } ->
+			post_typecheck__check_type_bindings(PredId, PredInfo0,
+					PredInfo1, ModuleInfo0,
+					UnboundTypeErrsInThisPred)
+		;
+			{ PredInfo1 = PredInfo0 },
+			{ UnboundTypeErrsInThisPred = 0 }
+		),
 		puritycheck_pred(PredId, PredInfo1, PredInfo2, ModuleInfo0,
 				PurityErrsInThisPred),
 		post_typecheck__finish_pred(ModuleInfo0, PredId, PredInfo2,
@@ -279,7 +294,7 @@
 	{ predicate_table_set_preds(PredTable0, Preds, PredTable) },
 	{ module_info_set_predicate_table(ModuleInfo0, PredTable,
 					  ModuleInfo1) },
-	check_preds_purity_2(PredIds, ModuleInfo1, ModuleInfo,
+	check_preds_purity_2(PredIds, FoundTypeError, ModuleInfo1, ModuleInfo,
 				  NumErrors1, NumErrors).
 
 	% Purity-check the code for single predicate, reporting any errors.
Index: tests/invalid/errors2.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/errors2.err_exp,v
retrieving revision 1.6
diff -u -r1.6 errors2.err_exp
--- errors2.err_exp	1998/10/30 04:38:44	1.6
+++ errors2.err_exp	1999/03/04 21:22:32
@@ -55,13 +55,6 @@
 errors2.m:078: In clause for predicate `errors2:type_error_8/0':
 errors2.m:078:   error: undefined predicate `from_char_list/2'.
 errors2.m:009: Inferred :- pred bind_type_param(int).
-errors2.m:016: In predicate `errors2:unresolved_polymorphism/0':
-errors2.m:016:   warning: unresolved polymorphism.
-errors2.m:016:   The variables with unbound types were:
-errors2.m:016:       V_2 :: TypeParam
-errors2.m:016:       Arg :: TypeParam
-errors2.m:016:   The unbound type variable(s) will be implicitly
-errors2.m:016:   bound to the builtin type `void'.
 errors2.m:019: In clause for `unresolved_polymorphism':
 errors2.m:019:   in argument 1 of call to predicate `errors2:bind_type_param/2':
 errors2.m:019:   mode error: variable `Arg' has instantiatedness `free',
Index: tests/invalid/types.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/types.err_exp,v
retrieving revision 1.5
diff -u -r1.5 types.err_exp
--- types.err_exp	1998/10/30 04:38:47	1.5
+++ types.err_exp	1999/03/04 21:22:40
@@ -22,12 +22,6 @@
 types.m:018:   error: undefined predicate `s/0'.
 types.m:020: In clause for predicate `types:a/1':
 types.m:020:   error: undefined predicate `b/1'.
-types.m:030: In predicate `types:foo/0':
-types.m:030:   warning: unresolved polymorphism.
-types.m:030:   The variable with an unbound type was:
-types.m:030:       V_1 :: BarTypeParam
-types.m:030:   The unbound type variable(s) will be implicitly
-types.m:030:   bound to the builtin type `void'.
 types.m:042: Error: no mode declaration for predicate `types:baz/1'.
 types.m:052: Error: no mode declaration for predicate `types:baz2/1'.
 For more information, try recompiling with `-E'.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list