[m-rev.] diff: fix lookups of pred_id -1 after type errors

Simon Taylor stayl at cs.mu.OZ.AU
Sat Jul 14 03:36:01 AEST 2001


Estimated hours taken: 1

Fix a bug introduced in my change to improve the handling of pred_const
cons_ids in unification goals which caused lookups of pred_id -1
in modules containing type errors.

compiler/mercury_compile.m:
	Don't run purity checking if the type inference iteration
	limit was exceeded. For some programs
	(e.g. tests/invalid/type_inf_loop.m), this can
	cause aborts in the code in post_typecheck to 
	resolve overloading.

compiler/typecheck.m:
	Return whether the iteration limit was exceeded.

	Remove some duplicated documentation.

compiler/purity.m:
	Back out my earlier change which avoided resolving
	overloading if there type errors (that change caused
	the lookups of pred_id -1).

tests/invalid/purity/Mmakefile:
tests/invalid/purity/purity_type_error.{m,exp}:
	Test case

Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.208
diff -u -u -r1.208 mercury_compile.m
--- compiler/mercury_compile.m	2001/07/06 11:25:27	1.208
+++ compiler/mercury_compile.m	2001/07/13 09:25:23
@@ -1355,7 +1355,8 @@
 	    %
 	    % Next typecheck the clauses.
 	    %
-	    typecheck(HLDS2b, HLDS3, FoundTypeError),
+	    typecheck(HLDS2b, HLDS3, FoundTypeError,
+	    		ExceededTypeCheckIterationLimit),
 	    ( { FoundTypeError = yes } ->
 		maybe_write_string(Verbose,
 			"% Program contains type error(s).\n"),
@@ -1369,13 +1370,23 @@
 	    % We can't continue after an undefined inst/mode
 	    % error, since propagate_types_into_proc_modes
 	    % (in post_typecheck.m -- called by purity.m)
-	    % and mode analysis would get internal errors
+	    % and mode analysis would get internal errors.
 	    %
+	    % We can't continue if the type inference iteration
+	    % limit was exceeeded because the code to resolve
+	    % overloading in post_typecheck.m (called by purity.m)
+	    % could abort.
 	    ( { FoundUndefModeError = yes } ->
 		{ FoundError = yes },
 		{ HLDS = HLDS3 },
 		maybe_write_string(Verbose,
 	"% Program contains undefined inst or undefined mode error(s).\n"),
+		io__set_exit_status(1)
+	    ; { ExceededTypeCheckIterationLimit = yes } ->
+		% FoundTypeError will always be true here, so we've already
+		% printed a message about the program containing type errors.
+		{ FoundError = yes },
+		{ HLDS = HLDS3 },
 		io__set_exit_status(1)
 	    ;
 	        %
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.33
diff -u -u -r1.33 purity.m
--- compiler/purity.m	2001/07/10 10:45:30	1.33
+++ compiler/purity.m	2001/07/13 09:26:11
@@ -370,7 +370,7 @@
 			PostTypecheckError1 = PostTypecheckError0
 		},
 		puritycheck_pred(PredId, PredInfo1, PredInfo2, ModuleInfo0,
-				FoundTypeError, PurityErrsInThisPred),
+				PurityErrsInThisPred),
 		post_typecheck__finish_pred(ModuleInfo0, PredId, PredInfo2,
 				PredInfo),
 		{ NumErrors1 is NumErrors0 + UnboundTypeErrsInThisPred
@@ -414,12 +414,11 @@
 %  them, and in the translation from goal to hlds_goal, the attached purity is
 %  turned into the appropriate feature in the hlds_goal_info.)
 
-:- pred puritycheck_pred(pred_id, pred_info, pred_info, module_info, bool, int,
+:- pred puritycheck_pred(pred_id, pred_info, pred_info, module_info, int,
 		io__state, io__state).
-:- mode puritycheck_pred(in, in, out, in, in, out, di, uo) is det.
+:- mode puritycheck_pred(in, in, out, in, out, di, uo) is det.
 
-puritycheck_pred(PredId, PredInfo0, PredInfo, ModuleInfo,
-		FoundTypeError, NumErrors) -->
+puritycheck_pred(PredId, PredInfo0, PredInfo, ModuleInfo, NumErrors) -->
 	{ pred_info_get_purity(PredInfo0, DeclPurity) } ,
 	{ pred_info_get_promised_purity(PredInfo0, PromisedPurity) },
 	( { pred_info_get_goal_type(PredInfo0, pragmas) } ->
@@ -436,13 +435,7 @@
 		{ clauses_info_clauses(ClausesInfo0, Clauses0) },
 		{ clauses_info_vartypes(ClausesInfo0, VarTypes0) },
 		{ clauses_info_varset(ClausesInfo0, VarSet0) },
-
-		%
-		% Exceeding the type inference iteration limit can result
-		% in aborts in the code in post_typecheck.m to resolve
-		% overloading.
-		%
-		{ RunPostTypecheck = bool__not(FoundTypeError) },
+		{ RunPostTypecheck = yes },
 		{ PurityInfo0 = purity_info(ModuleInfo, RunPostTypecheck,
 			PredInfo0, VarTypes0, VarSet0, []) },
 		{ compute_purity(Clauses0, Clauses, ProcIds, pure, Purity,
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.303
diff -u -u -r1.303 typecheck.m
--- compiler/typecheck.m	2001/06/27 05:04:31	1.303
+++ compiler/typecheck.m	2001/07/13 17:06:18
@@ -105,26 +105,20 @@
 :- import_module hlds_module, hlds_pred, hlds_data, prog_data.
 :- import_module bool, io, list, map.
 
-:- pred typecheck(module_info, module_info, bool, io__state, io__state).
-:- mode typecheck(in, out, out, di, uo) is det.
+	% typecheck(Module0, Module, FoundError,
+	%		ExceededIterationLimit, IO0, IO) 
+	%
+	% Type-checks Module0 and annotates it with variable typings
+	% (returning the result in Module), printing out appropriate
+	% error messages.
+	% FoundError is set to `yes' if there are any errors and
+	% `no' otherwise.
+	% ExceededIterationLimit is set to `yes' if the type inference
+	% iteration limit was reached and `no' otherwise.
 
-/*
-	Formally, typecheck(Module0, Module, FoundError, IO0, IO) is
-	intended to be true iff Module is Module0 annotated with the
-	variable typings that result from the process of type-checking,
-	FoundError is `yes' if Module0 contains any type errors and `no'
-	otherwise, and IO is the io__state that results from IO0 after
-	printing out appropriate error messages for the type errors in
-	Module0, if any.
-
-	Informally, typecheck(Module0, Module, FoundError, IO0, IO) 
-	type-checks Module0 and annotates it with variable typings
-	(returning the result in Module), prints out appropriate error
-	messages, and sets FoundError to `yes' if it finds any errors
-	and `no' otherwise.
-*/
+:- pred typecheck(module_info, module_info, bool, bool, io__state, io__state).
+:- mode typecheck(in, out, out, out, di, uo) is det.
 
-
 	% Find a predicate which matches the given name and argument types.
 	% Abort if there is no matching pred.
 	% Abort if there are multiple matching preds.
@@ -168,14 +162,14 @@
 
 %-----------------------------------------------------------------------------%
 
-typecheck(Module0, Module, FoundError) -->
+typecheck(Module0, Module, FoundError, ExceededIterationLimit) -->
 	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, "% Type-checking clauses...\n"),
-	check_pred_types(Module0, Module, FoundError),
+	check_pred_types(Module0, Module, FoundError, ExceededIterationLimit),
 	maybe_report_stats(Statistics),
 
 	io__set_output_stream(OldStream, _).
@@ -184,32 +178,33 @@
 
 	% Type-check the code for all the predicates in a module.
 
-:- pred check_pred_types(module_info, module_info, bool,
+:- pred check_pred_types(module_info, module_info, bool, bool,
 		io__state, io__state).
-:- mode check_pred_types(in, out, out, di, uo) is det.
+:- mode check_pred_types(in, out, out, out, di, uo) is det.
 
-check_pred_types(Module0, Module, FoundError) -->
+check_pred_types(Module0, Module, FoundError, ExceededIterationLimit) -->
 	{ module_info_predids(Module0, PredIds) },
 	globals__io_lookup_int_option(type_inference_iteration_limit,
 		MaxIterations),
 	typecheck_to_fixpoint(MaxIterations, PredIds, Module0,
-		Module, FoundError),
+		Module, FoundError, ExceededIterationLimit),
 	write_inference_messages(PredIds, Module).
 
 	% Repeatedly typecheck the code for a group of predicates
 	% until a fixpoint is reached, or until some errors are detected.
 
 :- pred typecheck_to_fixpoint(int, list(pred_id), module_info, module_info, 
-		bool, io__state, io__state).
-:- mode typecheck_to_fixpoint(in, in, in, out, out, di, uo) is det.
+		bool, bool, io__state, io__state).
+:- mode typecheck_to_fixpoint(in, in, in, out, out, out, di, uo) is det.
 
 typecheck_to_fixpoint(NumIterations, PredIds, Module0, Module,
-		FoundError) -->
+		FoundError, ExceededIterationLimit) -->
 	typecheck_pred_types_2(PredIds, Module0, Module1,
 		no, FoundError1, no, Changed),
 	( { Changed = no ; FoundError1 = yes } ->
 		{ Module = Module1 },
-		{ FoundError = FoundError1 }
+		{ FoundError = FoundError1 },
+		{ ExceededIterationLimit = no }
 	;
 		globals__io_lookup_bool_option(debug_types, DebugTypes),
 		( { DebugTypes = yes } ->
@@ -220,11 +215,12 @@
 		{ NumIterations1 = NumIterations - 1 },
 		( { NumIterations1 > 0 } ->
 			typecheck_to_fixpoint(NumIterations1, PredIds, Module1,
-				Module, FoundError)
+				Module, FoundError, ExceededIterationLimit)
 		;
 			typecheck_report_max_iterations_exceeded,
 			{ Module = Module1 },
-			{ FoundError = yes }
+			{ FoundError = yes },
+			{ ExceededIterationLimit = yes }
 		)
 	).
 
Index: tests/invalid/purity/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/purity/Mmakefile,v
retrieving revision 1.1
diff -u -u -r1.1 Mmakefile
--- tests/invalid/purity/Mmakefile	2000/04/22 07:12:48	1.1
+++ tests/invalid/purity/Mmakefile	2001/07/13 16:30:55
@@ -15,7 +15,8 @@
 	impure_pred_t1.m \
 	impure_pred_t2.m \
 	purity.m \
-	purity_nonsense.m
+	purity_nonsense.m \
+	purity_type_error.m
 
 DEPS=		$(SOURCES:%.m=%.dep)
 DEPENDS=	$(SOURCES:%.m=%.depend)
Index: tests/invalid/purity/purity_type_error.err_exp
===================================================================
RCS file: purity_type_error.err_exp
diff -N purity_type_error.err_exp
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ purity_type_error.err_exp	Sat Jul 14 02:31:33 2001
@@ -0,0 +1,9 @@
+purity_type_error.m:018: In clause for predicate `purity_type_error:type_error/1':
+purity_type_error.m:018:   in argument 1 of clause head:
+purity_type_error.m:018:   type error in unification of variable `HeadVar__1'
+purity_type_error.m:018:   and constant `1.00000000000000'.
+purity_type_error.m:018:   variable `HeadVar__1' has type `int',
+purity_type_error.m:018:   constant `1.00000000000000' has type `float'.
+purity_type_error.m:007: In predicate `purity_type_error:warn/1':
+purity_type_error.m:007:   warning: declared `impure' but actually pure.
+For more information, try recompiling with `-E'.
Index: tests/invalid/purity/purity_type_error.m
===================================================================
RCS file: purity_type_error.m
diff -N purity_type_error.m
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ purity_type_error.m	Sat Jul 14 02:30:02 2001
@@ -0,0 +1,18 @@
+% Check that impurity errors are still reported correctly
+% if there are type errors in the module.
+:- module purity_type_error.
+
+:- interface.
+
+:- impure pred warn(list(int)::out) is det.
+
+:- pred type_error(int::out) is det.
+
+:- implementation.
+
+:- import_module list, string.
+
+warn(List) :-
+	append([1,2,3], [4,5,6], List).
+
+type_error(1.0).
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list