[m-rev.] for review: fix singleton variable warning problem

Simon Taylor stayl at cs.mu.OZ.AU
Sat Jun 1 23:35:52 AEST 2002


On 01-Jun-2002, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > One possible solution, then, might be to change the way we handle
> > foreign_proc clauses, so that we do introduce "HeadVar__N" variables
> > and the corresponding unifications for those.  I don't know if that
> > would be a good idea, or if it might result in other problems...
> 
> Adding unifications could cause spurious unique mode errors due to
> the addition of aliasing that the current mode checker is incapable
> of tracking. Howver, it should be possible to specify the HeadVar__N
> variables as the arguments of the foreign code goal directly.
> 
> The diff below has the same effect as Pete's change, but it also
> simplifies the code. This isn't well tested.

I've committed the following diff.

Simon.


Estimated hours taken: 0.5 (+4 by petdr)
Branches: main

compiler/make_hlds.m:
	Fix spurious "`_Var' occurs more than once" warnings for
	underscore variables in `:- pragma foreign_proc' declarations
	for predicates which also have Mercury clauses.

tests/invalid/Mmakefile:
tests/invalid/foreign_singleton.m:
tests/invalid/foreign_singleton.err_exp:
tests/valid/Mmakefile:
tests/valid/foreign_underscore_var.m:
	Test cases.

Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.411
diff -u -u -r1.411 make_hlds.m
--- compiler/make_hlds.m	9 May 2002 16:30:55 -0000	1.411
+++ compiler/make_hlds.m	1 Jun 2002 10:38:17 -0000
@@ -5500,7 +5500,7 @@
 clauses_info_add_pragma_foreign_proc(ClausesInfo0, Purity, Attributes0, PredId,
 		ProcId, PVarSet, PVars, OrigArgTypes, PragmaImpl0, Context,
 		PredOrFunc, PredName, Arity, ClausesInfo, ModuleInfo0,
-		ModuleInfo, Info0, Info) -->
+		ModuleInfo, Info, Info) -->
 
 	{ ClausesInfo0 = clauses_info(VarSet0, VarTypes, TVarNameMap,
 		VarTypes1, HeadVars, ClauseList, TI_VarMap, TCI_VarMap,
@@ -5618,7 +5618,6 @@
 	( { MultipleArgs = [_ | _] } ->
 		{ ClausesInfo = ClausesInfo0 },
 		{ ModuleInfo = ModuleInfo1 },
-		{ Info = Info0 },
 		prog_out__write_context(Context),
 		io__write_string(
 			"In `:- pragma foreign_proc' declaration for "),
@@ -5644,12 +5643,7 @@
 		io__write_string("  in the argument list.\n"),
 		io__set_exit_status(1)
 	;
-		% merge the varsets of the proc and the new pragma_c_code
 		{
-		varset__merge_subst(VarSet0, PVarSet, VarSet1, Subst),
-		map__apply_to_list(Args0, Subst, TermArgs),
-		term__term_list_to_var_list(TermArgs, Args),
-
 			% build the pragma_c_code
 		goal_info_init(GoalInfo0),
 		goal_info_set_context(GoalInfo0, Context, GoalInfo1),
@@ -5657,22 +5651,12 @@
 		% this foreign code is inlined
 		add_goal_info_purity_feature(GoalInfo1, Purity, GoalInfo),
 		HldsGoal0 = foreign_proc(Attributes, PredId, 
-			ProcId, Args, ArgInfo, OrigArgTypes, PragmaImpl)
-			- GoalInfo
-		}, 
-			% Apply unifications with the head args.
-			% Since the set of head vars and the set vars in the
-			% pragma foreign code are disjoint, the
-			% unifications can be implemented as
-			% substitutions, and they will be.
-		insert_arg_unifications(HeadVars, TermArgs, Context,
-			head(PredOrFunc, Arity), yes, HldsGoal0, VarSet1,
-			HldsGoal1, VarSet2, transform_info(ModuleInfo1, Info0),
-				transform_info(ModuleInfo, Info)),
-		{
+			ProcId, HeadVars, ArgInfo, OrigArgTypes, PragmaImpl)
+			- GoalInfo,
+		ModuleInfo = ModuleInfo1,
 		map__init(EmptyVarTypes),
 		implicitly_quantify_clause_body(HeadVars,
-			HldsGoal1, VarSet2, EmptyVarTypes,
+			HldsGoal0, VarSet0, EmptyVarTypes,
 			HldsGoal, VarSet, _, _Warnings),
 		NewClause = clause([ProcId], HldsGoal,
 			foreign_language(NewLang), Context),
@@ -5726,7 +5710,7 @@
 	;
 		{ ArgContext = head(PredOrFunc, Arity) },
 		insert_arg_unifications(HeadVars, Args, Context, ArgContext,
-			no, Goal1, VarSet1, Goal2, VarSet2, Info1, Info2)
+			Goal1, VarSet1, Goal2, VarSet2, Info1, Info2)
 	),
 	{ VarTypes2 = Info2 ^ qual_info ^ vartypes },
 	{ implicitly_quantify_clause_body(HeadVars, Goal2, VarSet2, VarTypes2,
@@ -5937,7 +5921,7 @@
 		{ record_called_pred_or_func(predicate, Name, Arity,
 			Info0, Info1) },
 		insert_arg_unifications(HeadVars, Args,
-			Context, call(CallId), no,
+			Context, call(CallId),
 			Goal0, VarSet1, Goal, VarSet, Info1, Info)
 	).
 
@@ -6493,7 +6477,7 @@
 			{ record_called_pred_or_func(PredOrFunc, SymName, 
 				InsertArity, Info0, Info1) },
 			insert_arg_unifications(AllArgs, AllArgTerms,
-				Context, call(CallId), no,
+				Context, call(CallId),
 				Goal0, VarSet3, Goal, VarSet, Info1, Info)
 		;
 			{ invalid_goal(UpdateStr, Args0, GoalInfo,
@@ -6596,7 +6580,7 @@
 			PredGoal0, VarSet3, Info0, Info1),
 		{ ArgContext = head(PredOrFunc, PredArity) },
 		insert_arg_unifications(HeadArgs, HeadArgs1, Context,
-			ArgContext, no, PredGoal0, VarSet3, PredGoal1, VarSet4,
+			ArgContext, PredGoal0, VarSet3, PredGoal1, VarSet4,
 			Info1, Info2),
 
 		% Quantification will reduce this down to
@@ -6668,7 +6652,7 @@
 		insert_arg_unifications(AllArgs,
 			[term__variable(LambdaVar), AditiState0Term,
 				AditiStateTerm],
-			Context, CallId, no, UpdateConj, VarSet7, UpdateGoal,
+			Context, CallId, UpdateConj, VarSet7, UpdateGoal,
 			VarSet, Info4, Info)
 	;
 		%
@@ -6709,7 +6693,7 @@
 		{ record_called_pred_or_func(PredOrFunc, SymName, Arity,
 			Info0, Info1) },
 		insert_arg_unifications(OtherArgs, OtherArgs0, Context, CallId,
-			no, Call, VarSet1, UpdateGoal, VarSet, Info1, Info)
+			Call, VarSet1, UpdateGoal, VarSet, Info1, Info)
 	;
 		{ invalid_goal(Descr, Args0, GoalInfo,
 			UpdateGoal, VarSet0, VarSet) },
@@ -6917,17 +6901,7 @@
 	% that each unification gets reduced to superhomogeneous form.
 	% It also gets passed a `arg_context', which indicates
 	% where the terms came from.
-
 	% We never insert unifications of the form X = X.
-	% If ForPragmaC is yes, we process unifications of the form
-	% X = Y by substituting the var expected by the outside environment
-	% (the head variable) for the variable inside the goal (which was
-	% created just for the pragma_c_code goal), while giving the headvar
-	% the name of the just eliminated variable. The result will be
-	% a proc_info in which the head variables have meaningful names
-	% and the body goal is just a pragma C code. Without this special
-	% treatment, the body goal will be a conjunction, which would
-	% complicate the handling of code generation for nondet pragma C codes.
 
 :- type arg_context
 	--->	
@@ -6945,13 +6919,13 @@
 		).
 
 :- pred insert_arg_unifications(list(prog_var), list(prog_term),
-		prog_context, arg_context, bool, hlds_goal, prog_varset,
+		prog_context, arg_context, hlds_goal, prog_varset,
 		hlds_goal, prog_varset, transform_info, transform_info,
 		io__state, io__state).
-:- mode insert_arg_unifications(in, in, in, in, in, in, in, out,
+:- mode insert_arg_unifications(in, in, in, in, in, in, out,
 		out, in, out, di, uo) is det.
 
-insert_arg_unifications(HeadVars, Args, Context, ArgContext, ForPragmaC,
+insert_arg_unifications(HeadVars, Args, Context, ArgContext,
 		Goal0, VarSet0, Goal, VarSet, Info0, Info) -->
 	( { HeadVars = [] } ->
 		{ Goal = Goal0 },
@@ -6961,40 +6935,40 @@
 		{ Goal0 = _ - GoalInfo0 },
 		{ goal_to_conj_list(Goal0, List0) },
 		insert_arg_unifications_2(HeadVars, Args, Context, ArgContext,
-			ForPragmaC, 0, List0, VarSet0, List, VarSet,
+			0, List0, VarSet0, List, VarSet,
 			Info0, Info),
 		{ goal_info_set_context(GoalInfo0, Context, GoalInfo) },
 		{ conj_list_to_goal(List, GoalInfo, Goal) }
 	).
 
 :- pred insert_arg_unifications_2(list(prog_var), list(prog_term),
-		prog_context, arg_context, bool, int, list(hlds_goal),
+		prog_context, arg_context, int, list(hlds_goal),
 		prog_varset, list(hlds_goal), prog_varset,
 		transform_info, transform_info, io__state, io__state).
-:- mode insert_arg_unifications_2(in, in, in, in, in, in, in, in,
+:- mode insert_arg_unifications_2(in, in, in, in, in, in, in,
 		out, out, in, out, di, uo) is det.
 
-insert_arg_unifications_2([], [_|_], _, _, _, _, _, _, _, _, _, _) -->
+insert_arg_unifications_2([], [_|_], _,  _, _, _, _, _, _, _, _) -->
 	{ error("insert_arg_unifications_2: length mismatch") }.
-insert_arg_unifications_2([_|_], [], _, _, _, _, _, _, _, _, _, _) -->
+insert_arg_unifications_2([_|_], [], _,  _, _, _, _, _, _, _, _) -->
 	{ error("insert_arg_unifications_2: length mismatch") }.
-insert_arg_unifications_2([], [], _, _, _, _, List, VarSet, List, VarSet,
+insert_arg_unifications_2([], [], _, _,  _, List, VarSet, List, VarSet,
 		Info, Info) --> [].
 insert_arg_unifications_2([Var|Vars], [Arg|Args], Context, ArgContext,
-		ForPragmaC, N0, List0, VarSet0, List, VarSet, Info0, Info) -->
+		N0, List0, VarSet0, List, VarSet, Info0, Info) -->
 	{ N1 is N0 + 1 },
 	insert_arg_unification(Var, Arg, Context, ArgContext,
-		ForPragmaC, N1, List0, VarSet0, List1, VarSet1, ArgUnifyConj,
+		N1, List0, VarSet0, List1, VarSet1, ArgUnifyConj,
 		Info0, Info1),
 	(
 		{ ArgUnifyConj = [] }
 	->
 		insert_arg_unifications_2(Vars, Args, Context, ArgContext,
-			ForPragmaC, N1, List1, VarSet1, List, VarSet,
+			N1, List1, VarSet1, List, VarSet,
 			Info1, Info)
 	;
 		insert_arg_unifications_2(Vars, Args, Context, ArgContext,
-			ForPragmaC, N1, List1, VarSet1, List2, VarSet,
+			N1, List1, VarSet1, List2, VarSet,
 			Info1, Info),
 		{ list__append(ArgUnifyConj, List2, List) }
 	).	
@@ -7043,7 +7017,7 @@
 		{ Terms = [Term | Terms1] },
 		{ ArgContexts = [ArgNumber - ArgContext | ArgContexts1] }
 	->
-		insert_arg_unification(Var, Term, Context, ArgContext, no,
+		insert_arg_unification(Var, Term, Context, ArgContext,
 			ArgNumber, List0, VarSet0, List1, VarSet1,
 			UnifyConj, Info0, Info1),
 		insert_arg_unifications_with_supplied_contexts_2(Vars1, Terms1,
@@ -7055,14 +7029,14 @@
 	).
 
 :- pred insert_arg_unification(prog_var, prog_term,
-		prog_context, arg_context, bool, int,
+		prog_context, arg_context, int,
 		list(hlds_goal), prog_varset, list(hlds_goal), prog_varset,
 		list(hlds_goal), transform_info, transform_info,
 		io__state, io__state).
-:- mode insert_arg_unification(in, in, in, in, in, in,
+:- mode insert_arg_unification(in, in, in, in, in,
 		in, in, out, out, out, in, out, di, uo) is det.
 
-insert_arg_unification(Var, Arg, Context, ArgContext, ForPragmaC, N1,
+insert_arg_unification(Var, Arg, Context, ArgContext, N1,
 		List0, VarSet0, List1, VarSet1, ArgUnifyConj, Info0, Info) -->
 	(
 		{ Arg = term__variable(Var) }
@@ -7073,23 +7047,6 @@
 		{ ArgUnifyConj = [] },
 		{ List1 = List0 }
 	;
-		{ Arg = term__variable(ArgVar) },
-		{ ForPragmaC = yes }
-	->
-		% Handle unifications of the form `X = Y' by substitution
-		% if this is safe.
-		{ Info = Info0 },
-		{ ArgUnifyConj = [] },
-		{ map__init(Subst0) },
-		{ map__det_insert(Subst0, ArgVar, Var, Subst) },
-		{ goal_util__rename_vars_in_goals(List0, no, Subst,
-			List1) },
-		{ varset__search_name(VarSet0, ArgVar, ArgVarName) ->
-			varset__name_var(VarSet0, Var, ArgVarName, VarSet1)
-		;
-			VarSet1 = VarSet0
-		}
-	;
 		{ arg_context_to_unify_context(ArgContext, N1,
 			UnifyMainContext, UnifySubContext) },
 		unravel_unification(term__variable(Var), Arg,
@@ -7497,7 +7454,7 @@
 					Purity, GoalInfo) },
 				{ Goal1 = GoalExpr - GoalInfo },
 				insert_arg_unifications(HeadVars, FunctorArgs,
-					FunctorContext, ArgContext, no, Goal1,
+					FunctorContext, ArgContext, Goal1,
 					VarSet1, Goal, VarSet, Info1, Info)
 			)
 		)
@@ -7647,7 +7604,7 @@
 			HLDS_Goal0, VarSet2, Info1, Info2),
 	{ ArgContext = head(PredOrFunc, NumArgs) },
 	insert_arg_unifications(LambdaVars, Args, Context, ArgContext,
-		no, HLDS_Goal0, VarSet2, HLDS_Goal1, VarSet, Info2, Info3),
+		HLDS_Goal0, VarSet2, HLDS_Goal1, VarSet, Info2, Info3),
 
 	%
 	% Now figure out which variables we need to explicitly existentially
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.112
diff -u -u -r1.112 Mmakefile
--- tests/invalid/Mmakefile	9 May 2002 16:31:13 -0000	1.112
+++ tests/invalid/Mmakefile	1 Jun 2002 10:50:11 -0000
@@ -52,6 +52,7 @@
 	ext_type_bug.m \
 	exported_mode.m \
 	field_syntax_error.m \
+	foreign_singleton.m \
 	func_errors.m \
 	funcs_as_preds.m \
 	ho_default_func_1.m \
@@ -170,6 +171,7 @@
 MCFLAGS-duplicate_modes	=	--verbose-error-messages
 MCFLAGS-exported_mode =		--infer-all --no-intermodule-optimization
 MCFLAGS-foreign_type =		--compile-only
+MCFLAGS-foreign_singleton =	--halt-at-warn
 MCFLAGS-imported_mode =		--infer-all --no-intermodule-optimization
 MCFLAGS-missing_det_decls =	--no-infer-det
 MCFLAGS-missing_interface_import = --make-interface
Index: tests/invalid/foreign_singleton.err_exp
===================================================================
RCS file: tests/invalid/foreign_singleton.err_exp
diff -N tests/invalid/foreign_singleton.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/foreign_singleton.err_exp	1 Jun 2002 13:31:13 -0000
@@ -0,0 +1,5 @@
+foreign_singleton.m:026: In clause for predicate `foreign_singleton:f/3':
+foreign_singleton.m:026:   warning: variable `X' occurs only once in this scope.
+foreign_singleton.m:030: In clause for predicate `foreign_singleton:g/3':
+foreign_singleton.m:030:   warning: variable `X' occurs only once in this scope.
+For more information, try recompiling with `-E'.
Index: tests/invalid/foreign_singleton.m
===================================================================
RCS file: tests/invalid/foreign_singleton.m
diff -N tests/invalid/foreign_singleton.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/foreign_singleton.m	1 Jun 2002 13:31:06 -0000
@@ -0,0 +1,36 @@
+:- module foreign_singleton.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main -->
+       f(X),
+       io__write_int(X),
+       io__nl,
+       g(Y),
+       io__write_int(Y),
+       io__nl.
+
+:- pred f(int::out, io::di, io::uo) is det.
+
+:- pragma foreign_proc("C", f(X::out, _IO0::di, _IO::uo),
+        [will_not_call_mercury, promise_pure], "
+    X = 5;
+").
+
+f(X) --> [].
+
+:- pred g(int::out, io::di, io::uo) is det.
+
+g(X) --> [].
+
+:- pragma foreign_proc("C", g(X::out, _IO0::di, _IO::uo),
+        [will_not_call_mercury, promise_pure], "
+    X = 5;
+").
+
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.104
diff -u -u -r1.104 Mmakefile
--- tests/valid/Mmakefile	1 Jun 2002 10:58:52 -0000	1.104
+++ tests/valid/Mmakefile	1 Jun 2002 10:59:42 -0000
@@ -75,6 +75,7 @@
 	explicit_quant.m \
 	fail_ite.m \
 	followcode_det_problem.m \
+	foreign_underscore_var.m \
 	func_int_bug_main.m \
 	func_default_modes.m \
 	headvar_not_found.m \
@@ -278,6 +279,7 @@
 MCFLAGS-deforest_rerun_det	= -O3 --check-termination
 MCFLAGS-double_vn		= -O4
 MCFLAGS-explicit_quant		= --halt-at-warn
+MCFLAGS-foreign_underscore_var	= --halt-at-warn
 MCFLAGS-higher_order_implied_mode = -O-1
 MCFLAGS-inhibit_warn_test       = --inhibit-warnings --halt-at-warn
 MCFLAGS-intermod_dcg_bug	= --intermodule-optimization
Index: tests/valid/foreign_underscore_var.m
===================================================================
RCS file: tests/valid/foreign_underscore_var.m
diff -N tests/valid/foreign_underscore_var.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/foreign_underscore_var.m	1 Jun 2002 10:45:17 -0000
@@ -0,0 +1,24 @@
+:- module foreign_underscore_var.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main -->
+       f(X),
+       io__write_int(X),
+       io__nl.
+
+:- pred f(int::out, io::di, io::uo) is det.
+
+:- pragma foreign_proc("C", f(X::out, _IO0::di, _IO::uo),
+        [will_not_call_mercury, promise_pure], "
+    X = 5;
+").
+
+f(5) --> [].
+
--------------------------------------------------------------------------
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