[m-rev.] for review: fix bugs involving unused foreign_proc args

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Oct 12 15:01:47 AEST 2005


For review by anyone.

Zoltan.

Fix the bugs were exposed by my pre-dummy-type-diff cleanup of polymorphism.m.
This diff deleted a "semidet_fail" in the predicate that tested whether a
namedforeign_proc used a variable, making the test a real test, not a dummy.

The main bugs were in unused_args.m, polymorphism.m and ml_unify_gen.m.

compiler/unused_args.m:
	Fix the mismatch between the analysis and fixup passes' treatment of
	foreign_procs. The analysis pass says that variables representing
	unnamed foreign_proc arguments are unused, and therefore the code
	generating them can be optimized away, but the fixup pass used to leave
	those arguments unchanged. This is usually fine, but there was a
	problem if a variable had two or more such conjoined consumers but no
	other consumers. It then had its generator optimized away, but the
	variable was left in the nonlocal set of each consumer, which meant
	that the code generator aborted when trying to save the value of the
	variable after the first consumer.

	The fix is to rename unnamed foreign proc args, ensuring that they are
	local to the foreign_proc they appear in. The code generators can
	already handle such arguments.

compiler/typecheck.m:
	Detect foreign_procs that are supposed to bind type_info variables,
	but don't, and generate error messages for them. This is now necessary,
	since if accept such predicates, unused_args.m will now rename apart
	the unused type_info argument, and the code generator will abort
	due to the type_info missing its generator.

compiler/typecheck_errors.m:
	Add a predicate for reporting the error.

compiler/goal_util.m:
	Add a utility predicate and export some previously internal predicates
	for use by unused_args.m.

	Delete redundant module prefixes on predicate names to avoid having to
	split long lines.

compiler/polymorphism.m:
	Ensure that all arguments of import foreign_procs are considered used,
	since our contract with foreign language code prevents us from
	optimizing them away.

	Redefine a predicate using the new utility predicate in goal_util.m.

compiler/pragma_c_gen.m:
	Ensure that all arguments of import foreign_procs are considered used,
	since our contract with foreign language code prevents us from
	optimizing them away. This is a belt-and-suspenders fix: the change to
	polymorphism.m should be sufficient to ensure this objective by itself.

compiler/ml_unify_gen.m:
	The mark_static_terms pass was assuming that if X is a static term,
	then after the assignment unification Y = X Y is also a static term.
	However, when processing such assignments, the code generator here
	neglected to copy over the part of the X's state that says what static
	term it is to become part of Y's state. This diff fixes that neglect.

compiler/ml_code_util.m:
	We used to identify MLDS variables holding static terms by a sequence
	number, and then create a name from the number by tacking on the name
	of the HLDS variable referring to it at each reference. This worked
	because each static term was referred to by only one HLDS variable;
	but after the diff to ml_unify_gen, this is no longer the case.
	We therefore now construct the MLDS variable's name when the static
	term is created, and use that name as the translation of all the HLDS
	variables referring to that static term.

compiler/add_pragma.m:
	Minor cleanup.

library/rtti_implementation.m:
library/store.m:
	In some predicates that don't define type_infos for existentially typed
	arguments, mention the type_info that *should* be defined there in
	comments to avoid the error now generated by typecheck.m.

browser/Mercury.options:
deep_profiler/Mercury.options:
	Undo the workaround for the fixed bug.

tests/existential_type_classes.m:
	In predicates that don't define type_infos for existentially typed
	arguments, mention the type_info that *should* be defined there in
	comments to avoid the error now generated by typecheck.m.

tests/existential_type_classes.exp:
	Conform to the changed line numbers in existential_type_classes.m.

tests/warnings/exist_foreign_error.{m,exp}:
	New test case for the error now detected by typecheck.m.

tests/warnings/Mmakefile:
	Enable the new test case.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
Index: browser/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/Mercury.options,v
retrieving revision 1.8
diff -u -b -r1.8 Mercury.options
--- browser/Mercury.options	6 Oct 2005 08:50:15 -0000	1.8
+++ browser/Mercury.options	10 Oct 2005 08:48:46 -0000
@@ -14,10 +14,5 @@
 # exposes.
 MCFLAGS-mdb.declarative_edt = --no-optimize-higher-order
 
-# Bug workarounds for problems introduced in about rotd-2005-10-05.
-#
-MCFLAGS-mdb.declarative_execution = -O0
-MCFLAGS-mdb.declarative_analyser = -O0
-
 EXTRA_LIBRARIES-libmer_browser.so = mer_mdbcomp
 EXTRA_LIBRARIES-libmer_browser.dylib = mer_mdbcomp
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/add_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pragma.m,v
retrieving revision 1.12
diff -u -b -r1.12 add_pragma.m
--- compiler/add_pragma.m	5 Oct 2005 06:33:31 -0000	1.12
+++ compiler/add_pragma.m	12 Oct 2005 03:20:21 -0000
@@ -1155,9 +1155,8 @@
         VeryVerbose = no
     ),
 
-        % Lookup the pred declaration in the predicate table. (If it's not
-        % there, print an error message and insert a dummy declaration
-        % for the predicate.)
+    % Lookup the pred declaration in the predicate table. (If it's not there,
+    % print an error message and insert a dummy declaration for the predicate.)
     module_info_get_predicate_table(!.ModuleInfo, PredicateTable0),
     (
         predicate_table_search_pf_sym_arity(PredicateTable0,
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.115
diff -u -b -r1.115 goal_util.m
--- compiler/goal_util.m	19 Sep 2005 04:28:57 -0000	1.115
+++ compiler/goal_util.m	10 Oct 2005 15:01:58 -0000
@@ -58,31 +58,36 @@
 % and apply that translation. If a var in the input structure does not
 % occur as a key in the mapping, then the variable is left unsubstituted.
 
-    % goal_util__rename_vars_in_goals(GoalList, MustRename, Substitution,
-    %   NewGoalList).
-:- pred goal_util__rename_vars_in_goals(bool::in, prog_var_renaming::in,
+    % rename_vars_in_goals(MustRename, Substitution, GoalList, NewGoalList).
+:- pred rename_vars_in_goals(bool::in, prog_var_renaming::in,
     list(hlds_goal)::in, list(hlds_goal)::out) is det.
 
-:- pred goal_util__rename_vars_in_goal(prog_var_renaming::in,
+:- pred rename_vars_in_goal(prog_var_renaming::in,
     hlds_goal::in, hlds_goal::out) is det.
 
-:- pred goal_util__must_rename_vars_in_goal(prog_var_renaming::in,
+:- pred must_rename_vars_in_goal(prog_var_renaming::in,
     hlds_goal::in, hlds_goal::out) is det.
 
-:- pred goal_util__rename_vars_in_var_set(bool::in, prog_var_renaming::in,
+:- pred rename_vars_in_goal_expr(bool::in, prog_var_renaming::in,
+    hlds_goal_expr::in, hlds_goal_expr::out) is det.
+
+:- pred rename_vars_in_goal_info(bool::in, prog_var_renaming::in,
+    hlds_goal_info::in, hlds_goal_info::out) is det.
+
+:- pred rename_vars_in_var_set(bool::in, prog_var_renaming::in,
     set(prog_var)::in, set(prog_var)::out) is det.
 
-:- pred goal_util__rename_var_list(bool::in, map(var(T), var(T))::in,
+:- pred rename_var_list(bool::in, map(var(T), var(T))::in,
     list(var(T))::in, list(var(T))::out) is det.
 
-:- pred goal_util__rename_var(bool::in, map(var(V), var(V))::in,
+:- pred rename_var(bool::in, map(var(V), var(V))::in,
     var(V)::in, var(V)::out) is det.
 
-    % goal_util__create_variables(OldVariables, OldVarset, InitialVarTypes,
+    % create_variables(OldVariables, OldVarset, InitialVarTypes,
     %   InitialSubstitution, OldVarTypes, OldVarNames,  NewVarset,
     %   NewVarTypes, NewSubstitution):
     %
-    % goal_util__create_variables takes a list of variables, a varset, and map
+    % create_variables takes a list of variables, a varset, and map
     % from vars to types and an initial substitution, and creates new instances
     % of each of the source variables in the substitution, adding each new
     % variable to the varset and the var types map. The name and type of each
@@ -91,7 +96,7 @@
     % uniqueness in the type map for this reason - such is the sacrifice
     % for generality.)
     %
-:- pred goal_util__create_variables(list(prog_var)::in, prog_varset::in,
+:- pred create_variables(list(prog_var)::in, prog_varset::in,
     map(prog_var, type)::in, prog_varset::in, prog_varset::out,
     map(prog_var, type)::in, map(prog_var, type)::out,
     prog_var_renaming::in, prog_var_renaming::out) is det.
@@ -100,26 +105,26 @@
     % Unlike quantification.goal_vars, this predicate returns
     % even the explicitly quantified variables.
     %
-:- pred goal_util__goal_vars(hlds_goal::in, set(prog_var)::out) is det.
+:- pred goal_vars(hlds_goal::in, set(prog_var)::out) is det.
 
     % Return all the variables in the list of goals.
     % Unlike quantification.goal_vars, this predicate returns
     % even the explicitly quantified variables.
     %
-:- pred goal_util__goals_goal_vars(list(hlds_goal)::in, set(prog_var)::in,
+:- pred goals_goal_vars(list(hlds_goal)::in, set(prog_var)::in,
     set(prog_var)::out) is det.
 
     % Return all the variables in a generic call.
     %
-:- pred goal_util__generic_call_vars(generic_call::in, list(prog_var)::out)
+:- pred generic_call_vars(generic_call::in, list(prog_var)::out)
     is det.
 
     % Attach the given goal features to the given goal and all its subgoals.
     %
-:- pred goal_util__attach_features_to_all_goals(list(goal_feature)::in,
+:- pred attach_features_to_all_goals(list(goal_feature)::in,
     hlds_goal::in, hlds_goal::out) is det.
 
-    % goal_util__extra_nonlocal_typeinfos(TypeInfoMap, TypeClassInfoMap,
+    % extra_nonlocal_typeinfos(TypeInfoMap, TypeClassInfoMap,
     %   VarTypes, ExistQVars, NonLocals, NonLocalTypeInfos):
     %
     % Compute which type-info and type-class-info variables may need to be
@@ -137,13 +142,13 @@
     % i.e. a constraint which contrains an existentially quantified type
     % variable.
     %
-:- pred goal_util__extra_nonlocal_typeinfos(rtti_varmaps::in,
+:- pred extra_nonlocal_typeinfos(rtti_varmaps::in,
     map(prog_var, type)::in, existq_tvars::in,
     set(prog_var)::in, set(prog_var)::out) is det.
 
     % See whether the goal is a branched structure.
     %
-:- pred goal_util__goal_is_branched(hlds_goal_expr::in) is semidet.
+:- pred goal_is_branched(hlds_goal_expr::in) is semidet.
 
     % Return an indication of the size of the goal.
     %
@@ -201,7 +206,7 @@
     % for the magic set transformation.
     % This aborts if any of the constructors are existentially typed.
     %
-:- pred goal_util__switch_to_disjunction(prog_var::in, list(case)::in,
+:- pred switch_to_disjunction(prog_var::in, list(case)::in,
     instmap::in, list(hlds_goal)::out, prog_varset::in, prog_varset::out,
     map(prog_var, type)::in, map(prog_var, type)::out,
     module_info::in, module_info::out) is det.
@@ -210,7 +215,7 @@
     % (deconstruction unification) to the case goal.
     % This aborts if the constructor is existentially typed.
     %
-:- pred goal_util__case_to_disjunct(prog_var::in, cons_id::in, hlds_goal::in,
+:- pred case_to_disjunct(prog_var::in, cons_id::in, hlds_goal::in,
     instmap::in, hlds_goal::out, prog_varset::in, prog_varset::out,
     map(prog_var, type)::in, map(prog_var, type)::out,
     module_info::in, module_info::out) is det.
@@ -218,12 +223,12 @@
     % Transform an if-then-else into ( Cond, Then ; \+ Cond, Else ),
     % since magic.m and rl_gen.m don't handle if-then-elses.
     %
-:- pred goal_util__if_then_else_to_disjunction(hlds_goal::in, hlds_goal::in,
+:- pred if_then_else_to_disjunction(hlds_goal::in, hlds_goal::in,
     hlds_goal::in, hlds_goal_info::in, hlds_goal_expr::out) is det.
 
 %-----------------------------------------------------------------------------%
 
-    % goal_util__can_reorder_goals(ModuleInfo, FullyStrict, Goal1, Goal2).
+    % can_reorder_goals(ModuleInfo, FullyStrict, Goal1, Goal2).
     %
     % Goals can be reordered if
     % - the goals are independent
@@ -231,10 +236,10 @@
     % - any possible change in termination behaviour is allowed
     %   according to the semantics options.
     %
-:- pred goal_util__can_reorder_goals(module_info::in, vartypes::in, bool::in,
+:- pred can_reorder_goals(module_info::in, vartypes::in, bool::in,
     instmap::in, hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
 
-    % goal_util__reordering_maintains_termination(ModuleInfo,
+    % reordering_maintains_termination(ModuleInfo,
     %    FullyStrict, Goal1, Goal2)
     %
     % Succeeds if any possible change in termination behaviour from
@@ -242,7 +247,7 @@
     % The information computed by termination analysis is used when
     % making this decision.
     %
-:- pred goal_util__reordering_maintains_termination(module_info::in, bool::in,
+:- pred reordering_maintains_termination(module_info::in, bool::in,
     hlds_goal::in, hlds_goal::in) is semidet.
 
     % generate_simple_call(ModuleName, ProcName, PredOrFunc, ModeNo,
@@ -259,7 +264,7 @@
     % If ModeNo = mode_no(N) then the Nth procedure is used, counting
     % from 0.
     %
-:- pred goal_util__generate_simple_call(module_name::in, string::in,
+:- pred generate_simple_call(module_name::in, string::in,
     pred_or_func::in, mode_no::in, determinism::in, list(prog_var)::in,
     list(goal_feature)::in, assoc_list(prog_var, inst)::in,
     module_info::in, term__context::in, hlds_goal::out) is det.
@@ -278,7 +283,7 @@
     % before Code, SuffixCode after Code, and passes ExtraArgs as well
     % as Args.
     %
-:- pred goal_util__generate_foreign_proc(module_name::in, string::in,
+:- pred generate_foreign_proc(module_name::in, string::in,
     pred_or_func::in, mode_no::in, determinism::in,
     pragma_foreign_proc_attributes::in,
     list(foreign_arg)::in, list(foreign_arg)::in, string::in, string::in,
@@ -287,17 +292,22 @@
 
     % Generate a cast goal.  The input and output insts are just ground.
     %
-:- pred goal_util__generate_cast(cast_type::in, prog_var::in, prog_var::in,
+:- pred generate_cast(cast_type::in, prog_var::in, prog_var::in,
     prog_context::in, hlds_goal::out) is det.
 
     % This version takes input and output inst arguments, which may
     % be necessary when casting, say, solver type values with inst
     % any, or casting between enumeration types and ints.
     %
-:- pred goal_util__generate_cast(cast_type::in, prog_var::in, prog_var::in,
+:- pred generate_cast(cast_type::in, prog_var::in, prog_var::in,
     (inst)::in, (inst)::in, prog_context::in, hlds_goal::out) is det.
 
 %-----------------------------------------------------------------------------%
+
+:- pred foreign_code_uses_variable(pragma_foreign_code_impl::in, string::in)
+    is semidet.
+
+%-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -373,10 +383,9 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__create_variables([], _OldVarNames, _OldVarTypes,
-        !Varset, !VarTypes, !Subn).
-goal_util__create_variables([V | Vs], OldVarNames, OldVarTypes,
-        !Varset, !VarTypes, !Subn) :-
+create_variables([], _OldVarNames, _OldVarTypes, !Varset, !VarTypes, !Subn).
+create_variables([V | Vs], OldVarNames, OldVarTypes, !Varset, !VarTypes,
+        !Subn) :-
     ( map__contains(!.Subn, V) ->
         true
     ;
@@ -393,35 +402,34 @@
             true
         )
     ),
-    goal_util__create_variables(Vs, OldVarNames, OldVarTypes,
-        !Varset, !VarTypes, !Subn).
+    create_variables(Vs, OldVarNames, OldVarTypes, !Varset, !VarTypes, !Subn).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__init_subn(assoc_list(prog_var, prog_var)::in,
+:- pred init_subn(assoc_list(prog_var, prog_var)::in,
     prog_var_renaming::in, prog_var_renaming::out) is det.
 
-goal_util__init_subn([], !Subn).
-goal_util__init_subn([A - H | Vs], !Subn) :-
+init_subn([], !Subn).
+init_subn([A - H | Vs], !Subn) :-
     svmap__set(H, A, !Subn),
-    goal_util__init_subn(Vs, !Subn).
+    init_subn(Vs, !Subn).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_var_pair_list(bool::in, prog_var_renaming::in,
+:- pred rename_var_pair_list(bool::in, prog_var_renaming::in,
     assoc_list(prog_var, T)::in, list(pair(prog_var, T))::out) is det.
 
-goal_util__rename_var_pair_list(_Must, _Subn, [], []).
-goal_util__rename_var_pair_list(Must, Subn, [V - D | VDs], [N - D | NDs]) :-
-    goal_util__rename_var(Must, Subn, V, N),
-    goal_util__rename_var_pair_list(Must, Subn, VDs, NDs).
-
-goal_util__rename_var_list(_Must, _Subn, [], []).
-goal_util__rename_var_list(Must, Subn, [V | Vs], [N | Ns]) :-
-    goal_util__rename_var(Must, Subn, V, N),
-    goal_util__rename_var_list(Must, Subn, Vs, Ns).
+rename_var_pair_list(_Must, _Subn, [], []).
+rename_var_pair_list(Must, Subn, [V - D | VDs], [N - D | NDs]) :-
+    rename_var(Must, Subn, V, N),
+    rename_var_pair_list(Must, Subn, VDs, NDs).
+
+rename_var_list(_Must, _Subn, [], []).
+rename_var_list(Must, Subn, [V | Vs], [N | Ns]) :-
+    rename_var(Must, Subn, V, N),
+    rename_var_list(Must, Subn, Vs, Ns).
 
-goal_util__rename_var(Must, Subn, V, N) :-
+rename_var(Must, Subn, V, N) :-
     ( map__search(Subn, V, N0) ->
         N = N0
     ;
@@ -431,78 +439,73 @@
         ;
             Must = yes,
             term__var_to_int(V, VInt),
-            string__format("goal_util__rename_var: " ++
-                "no substitute for var %i", [i(VInt)], Msg),
+            string__format("rename_var: no substitute for var %i", [i(VInt)],
+                Msg),
             error(Msg)
         )
     ).
 
 %-----------------------------------------------------------------------------%
 
-goal_util__rename_vars_in_goal(Subn, Goal0, Goal) :-
-    goal_util__rename_vars_in_goal(no, Subn, Goal0, Goal).
+rename_vars_in_goal(Subn, Goal0, Goal) :-
+    rename_vars_in_goal(no, Subn, Goal0, Goal).
 
-goal_util__must_rename_vars_in_goal(Subn, Goal0, Goal) :-
-    goal_util__rename_vars_in_goal(yes, Subn, Goal0, Goal).
+must_rename_vars_in_goal(Subn, Goal0, Goal) :-
+    rename_vars_in_goal(yes, Subn, Goal0, Goal).
 
 %-----------------------------------------------------------------------------%
 
-goal_util__rename_vars_in_goals(_, _, [], []).
-goal_util__rename_vars_in_goals(Must, Subn, [Goal0 | Goals0], [Goal | Goals]) :-
-    goal_util__rename_vars_in_goal(Must, Subn, Goal0, Goal),
-    goal_util__rename_vars_in_goals(Must, Subn, Goals0, Goals).
+rename_vars_in_goals(_, _, [], []).
+rename_vars_in_goals(Must, Subn, [Goal0 | Goals0], [Goal | Goals]) :-
+    rename_vars_in_goal(Must, Subn, Goal0, Goal),
+    rename_vars_in_goals(Must, Subn, Goals0, Goals).
 
-:- pred goal_util__rename_vars_in_goal(bool::in, prog_var_renaming::in,
+:- pred rename_vars_in_goal(bool::in, prog_var_renaming::in,
     hlds_goal::in, hlds_goal::out) is det.
 
-goal_util__rename_vars_in_goal(Must, Subn,
-        Goal0 - GoalInfo0, Goal - GoalInfo) :-
-    goal_util__rename_vars_in_goal_expr(Must, Subn, Goal0, Goal),
-    goal_util__rename_vars_in_goal_info(Must, Subn, GoalInfo0, GoalInfo).
+rename_vars_in_goal(Must, Subn, Goal0 - GoalInfo0, Goal - GoalInfo) :-
+    rename_vars_in_goal_expr(Must, Subn, Goal0, Goal),
+    rename_vars_in_goal_info(Must, Subn, GoalInfo0, GoalInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_vars_in_goal_expr(bool::in, prog_var_renaming::in,
-    hlds_goal_expr::in, hlds_goal_expr::out) is det.
-
-goal_util__rename_vars_in_goal_expr(Must, Subn, conj(Goals0), conj(Goals)) :-
-    goal_util__rename_vars_in_goals(Must, Subn, Goals0, Goals).
+rename_vars_in_goal_expr(Must, Subn, conj(Goals0), conj(Goals)) :-
+    rename_vars_in_goals(Must, Subn, Goals0, Goals).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
-        par_conj(Goals0), par_conj(Goals)) :-
-    goal_util__rename_vars_in_goals(Must, Subn, Goals0, Goals).
+rename_vars_in_goal_expr(Must, Subn, par_conj(Goals0), par_conj(Goals)) :-
+    rename_vars_in_goals(Must, Subn, Goals0, Goals).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn, disj(Goals0), disj(Goals)) :-
-    goal_util__rename_vars_in_goals(Must, Subn, Goals0, Goals).
+rename_vars_in_goal_expr(Must, Subn, disj(Goals0), disj(Goals)) :-
+    rename_vars_in_goals(Must, Subn, Goals0, Goals).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         switch(Var0, Det, Cases0), switch(Var, Det, Cases)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var),
-    goal_util__rename_vars_in_cases(Must, Subn, Cases0, Cases).
+    rename_var(Must, Subn, Var0, Var),
+    rename_vars_in_cases(Must, Subn, Cases0, Cases).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         if_then_else(Vars0, Cond0, Then0, Else0),
         if_then_else(Vars, Cond, Then, Else)) :-
-    goal_util__rename_var_list(Must, Subn, Vars0, Vars),
-    goal_util__rename_vars_in_goal(Must, Subn, Cond0, Cond),
-    goal_util__rename_vars_in_goal(Must, Subn, Then0, Then),
-    goal_util__rename_vars_in_goal(Must, Subn, Else0, Else).
+    rename_var_list(Must, Subn, Vars0, Vars),
+    rename_vars_in_goal(Must, Subn, Cond0, Cond),
+    rename_vars_in_goal(Must, Subn, Then0, Then),
+    rename_vars_in_goal(Must, Subn, Else0, Else).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn, not(Goal0), not(Goal)) :-
-    goal_util__rename_vars_in_goal(Must, Subn, Goal0, Goal).
+rename_vars_in_goal_expr(Must, Subn, not(Goal0), not(Goal)) :-
+    rename_vars_in_goal(Must, Subn, Goal0, Goal).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         scope(Reason0, Goal0), scope(Reason, Goal)) :-
     (
         Reason0 = exist_quant(Vars0),
-        goal_util__rename_var_list(Must, Subn, Vars0, Vars),
+        rename_var_list(Must, Subn, Vars0, Vars),
         Reason = exist_quant(Vars)
     ;
         Reason0 = promise_purity(_, _),
         Reason = Reason0
     ;
         Reason0 = promise_equivalent_solutions(Vars0),
-        goal_util__rename_var_list(Must, Subn, Vars0, Vars),
+        rename_var_list(Must, Subn, Vars0, Vars),
         Reason = promise_equivalent_solutions(Vars)
     ;
         Reason0 = barrier(_),
@@ -512,108 +515,106 @@
         Reason = Reason0
     ;
         Reason0 = from_ground_term(Var0),
-        goal_util__rename_var(Must, Subn, Var0, Var),
+        rename_var(Must, Subn, Var0, Var),
         Reason = from_ground_term(Var)
     ),
-    goal_util__rename_vars_in_goal(Must, Subn, Goal0, Goal).
+    rename_vars_in_goal(Must, Subn, Goal0, Goal).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         generic_call(GenericCall0, Args0, Modes, Det),
         generic_call(GenericCall, Args, Modes, Det)) :-
-    goal_util__rename_generic_call(Must, Subn, GenericCall0, GenericCall),
-    goal_util__rename_var_list(Must, Subn, Args0, Args).
+    rename_generic_call(Must, Subn, GenericCall0, GenericCall),
+    rename_var_list(Must, Subn, Args0, Args).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         call(PredId, ProcId, Args0, Builtin, Context, Sym),
         call(PredId, ProcId, Args, Builtin, Context, Sym)) :-
-    goal_util__rename_var_list(Must, Subn, Args0, Args).
+    rename_var_list(Must, Subn, Args0, Args).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         unify(LHS0, RHS0, Mode, Unify0, Context),
         unify(LHS, RHS, Mode, Unify, Context)) :-
-    goal_util__rename_var(Must, Subn, LHS0, LHS),
-    goal_util__rename_unify_rhs(Must, Subn, RHS0, RHS),
-    goal_util__rename_unify(Must, Subn, Unify0, Unify).
+    rename_var(Must, Subn, LHS0, LHS),
+    rename_unify_rhs(Must, Subn, RHS0, RHS),
+    rename_unify(Must, Subn, Unify0, Unify).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         foreign_proc(A, B, C, Args0, Extra0, F),
         foreign_proc(A, B, C, Args, Extra, F)) :-
-    goal_util__rename_arg_list(Must, Subn, Args0, Args),
-    goal_util__rename_arg_list(Must, Subn, Extra0, Extra).
+    rename_arg_list(Must, Subn, Args0, Args),
+    rename_arg_list(Must, Subn, Extra0, Extra).
 
-goal_util__rename_vars_in_goal_expr(Must, Subn,
+rename_vars_in_goal_expr(Must, Subn,
         shorthand(ShorthandGoal0), shorthand(ShrothandGoal)) :-
-    goal_util__rename_vars_in_shorthand(Must, Subn,
-        ShorthandGoal0, ShrothandGoal).
+    rename_vars_in_shorthand(Must, Subn, ShorthandGoal0, ShrothandGoal).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_vars_in_shorthand(bool::in, prog_var_renaming::in,
+:- pred rename_vars_in_shorthand(bool::in, prog_var_renaming::in,
     shorthand_goal_expr::in, shorthand_goal_expr::out) is det.
 
-goal_util__rename_vars_in_shorthand(Must, Subn,
+rename_vars_in_shorthand(Must, Subn,
         bi_implication(LHS0, RHS0), bi_implication(LHS, RHS)) :-
-    goal_util__rename_vars_in_goal(Must, Subn, LHS0, LHS),
-    goal_util__rename_vars_in_goal(Must, Subn, RHS0, RHS).
+    rename_vars_in_goal(Must, Subn, LHS0, LHS),
+    rename_vars_in_goal(Must, Subn, RHS0, RHS).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_arg_list(bool::in, prog_var_renaming::in,
+:- pred rename_arg_list(bool::in, prog_var_renaming::in,
     list(foreign_arg)::in, list(foreign_arg)::out) is det.
 
-goal_util__rename_arg_list(_Must, _Subn, [], []).
-goal_util__rename_arg_list(Must, Subn, [Arg0 | Args0], [Arg | Args]) :-
-    goal_util__rename_arg(Must, Subn, Arg0, Arg),
-    goal_util__rename_arg_list(Must, Subn, Args0, Args).
+rename_arg_list(_Must, _Subn, [], []).
+rename_arg_list(Must, Subn, [Arg0 | Args0], [Arg | Args]) :-
+    rename_arg(Must, Subn, Arg0, Arg),
+    rename_arg_list(Must, Subn, Args0, Args).
 
-:- pred goal_util__rename_arg(bool::in, prog_var_renaming::in,
+:- pred rename_arg(bool::in, prog_var_renaming::in,
     foreign_arg::in, foreign_arg::out) is det.
 
-goal_util__rename_arg(Must, Subn,
-        foreign_arg(Var0, B, C), foreign_arg(Var, B, C)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var).
+rename_arg(Must, Subn, foreign_arg(Var0, B, C), foreign_arg(Var, B, C)) :-
+    rename_var(Must, Subn, Var0, Var).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_vars_in_cases(bool::in, prog_var_renaming::in,
+:- pred rename_vars_in_cases(bool::in, prog_var_renaming::in,
     list(case)::in, list(case)::out) is det.
 
-goal_util__rename_vars_in_cases(_Must, _Subn, [], []).
-goal_util__rename_vars_in_cases(Must, Subn,
+rename_vars_in_cases(_Must, _Subn, [], []).
+rename_vars_in_cases(Must, Subn,
         [case(Cons, G0) | Gs0], [case(Cons, G) | Gs]) :-
-    goal_util__rename_vars_in_goal(Must, Subn, G0, G),
-    goal_util__rename_vars_in_cases(Must, Subn, Gs0, Gs).
+    rename_vars_in_goal(Must, Subn, G0, G),
+    rename_vars_in_cases(Must, Subn, Gs0, Gs).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_unify_rhs(bool::in, prog_var_renaming::in,
+:- pred rename_unify_rhs(bool::in, prog_var_renaming::in,
     unify_rhs::in, unify_rhs::out) is det.
 
-goal_util__rename_unify_rhs(Must, Subn, var(Var0), var(Var)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var).
-goal_util__rename_unify_rhs(Must, Subn,
+rename_unify_rhs(Must, Subn, var(Var0), var(Var)) :-
+    rename_var(Must, Subn, Var0, Var).
+rename_unify_rhs(Must, Subn,
         functor(Functor, E, ArgVars0), functor(Functor, E, ArgVars)) :-
-    goal_util__rename_var_list(Must, Subn, ArgVars0, ArgVars).
-goal_util__rename_unify_rhs(Must, Subn,
+    rename_var_list(Must, Subn, ArgVars0, ArgVars).
+rename_unify_rhs(Must, Subn,
         lambda_goal(Purity, PredOrFunc, EvalMethod, FixModes,
             NonLocals0, Vars0, Modes, Det, Goal0),
         lambda_goal(Purity, PredOrFunc, EvalMethod, FixModes,
             NonLocals, Vars, Modes, Det, Goal)) :-
-    goal_util__rename_var_list(Must, Subn, NonLocals0, NonLocals),
-    goal_util__rename_var_list(Must, Subn, Vars0, Vars),
-    goal_util__rename_vars_in_goal(Must, Subn, Goal0, Goal).
+    rename_var_list(Must, Subn, NonLocals0, NonLocals),
+    rename_var_list(Must, Subn, Vars0, Vars),
+    rename_vars_in_goal(Must, Subn, Goal0, Goal).
 
-:- pred goal_util__rename_unify(bool::in, prog_var_renaming::in,
+:- pred rename_unify(bool::in, prog_var_renaming::in,
     unification::in, unification::out) is det.
 
-goal_util__rename_unify(Must, Subn,
+rename_unify(Must, Subn,
         construct(Var0, ConsId, Vars0, Modes, How0, Uniq, SubInfo0),
         construct(Var, ConsId, Vars, Modes, How, Uniq, SubInfo)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var),
-    goal_util__rename_var_list(Must, Subn, Vars0, Vars),
+    rename_var(Must, Subn, Var0, Var),
+    rename_var_list(Must, Subn, Vars0, Vars),
     (
         How0 = reuse_cell(cell_to_reuse(ReuseVar0, B, C)),
-        goal_util__rename_var(Must, Subn, ReuseVar0, ReuseVar),
+        rename_var(Must, Subn, ReuseVar0, ReuseVar),
         How = reuse_cell(cell_to_reuse(ReuseVar, B, C))
     ;
         How0 = construct_dynamically,
@@ -634,7 +635,7 @@
                 Size = Size0
             ;
                 Size0 = dynamic_size(SizeVar0),
-                goal_util__rename_var(Must, Subn, SizeVar0, SizeVar),
+                rename_var(Must, Subn, SizeVar0, SizeVar),
                 Size = dynamic_size(SizeVar)
             ),
             MaybeSize = yes(Size)
@@ -644,65 +645,62 @@
         SubInfo0 = no_construct_sub_info,
         SubInfo = no_construct_sub_info
     ).
-goal_util__rename_unify(Must, Subn,
+rename_unify(Must, Subn,
         deconstruct(Var0, ConsId, Vars0, Modes, Cat, CanCGC),
         deconstruct(Var, ConsId, Vars, Modes, Cat, CanCGC)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var),
-    goal_util__rename_var_list(Must, Subn, Vars0, Vars).
-goal_util__rename_unify(Must, Subn, assign(L0, R0), assign(L, R)) :-
-    goal_util__rename_var(Must, Subn, L0, L),
-    goal_util__rename_var(Must, Subn, R0, R).
-goal_util__rename_unify(Must, Subn, simple_test(L0, R0), simple_test(L, R)) :-
-    goal_util__rename_var(Must, Subn, L0, L),
-    goal_util__rename_var(Must, Subn, R0, R).
-goal_util__rename_unify(_Must, _Subn,
+    rename_var(Must, Subn, Var0, Var),
+    rename_var_list(Must, Subn, Vars0, Vars).
+rename_unify(Must, Subn, assign(L0, R0), assign(L, R)) :-
+    rename_var(Must, Subn, L0, L),
+    rename_var(Must, Subn, R0, R).
+rename_unify(Must, Subn, simple_test(L0, R0), simple_test(L, R)) :-
+    rename_var(Must, Subn, L0, L),
+    rename_var(Must, Subn, R0, R).
+rename_unify(_Must, _Subn,
         complicated_unify(Modes, Cat, TypeInfoVars),
         complicated_unify(Modes, Cat, TypeInfoVars)).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_generic_call(bool::in, prog_var_renaming::in,
+:- pred rename_generic_call(bool::in, prog_var_renaming::in,
     generic_call::in, generic_call::out) is det.
 
-goal_util__rename_generic_call(Must, Subn,
+rename_generic_call(Must, Subn,
         higher_order(Var0, Purity, PredOrFunc, Arity),
         higher_order(Var, Purity, PredOrFunc, Arity)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var).
-goal_util__rename_generic_call(Must, Subn,
+    rename_var(Must, Subn, Var0, Var).
+rename_generic_call(Must, Subn,
         class_method(Var0, Method, ClassId, MethodId),
         class_method(Var, Method, ClassId, MethodId)) :-
-    goal_util__rename_var(Must, Subn, Var0, Var).
-goal_util__rename_generic_call(_, _, cast(CastType), cast(CastType)).
-goal_util__rename_generic_call(_Must, _Subn,
+    rename_var(Must, Subn, Var0, Var).
+rename_generic_call(_, _, cast(CastType), cast(CastType)).
+rename_generic_call(_Must, _Subn,
         aditi_builtin(Builtin, PredCallId),
         aditi_builtin(Builtin, PredCallId)).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_var_maps(bool::in, prog_var_renaming::in,
+:- pred rename_var_maps(bool::in, prog_var_renaming::in,
     map(prog_var, T)::in, map(prog_var, T)::out) is det.
 
-goal_util__rename_var_maps(Must, Subn, Map0, Map) :-
+rename_var_maps(Must, Subn, Map0, Map) :-
     map__to_assoc_list(Map0, AssocList0),
-    goal_util__rename_var_maps_2(Must, Subn, AssocList0, AssocList),
+    rename_var_maps_2(Must, Subn, AssocList0, AssocList),
     map__from_assoc_list(AssocList, Map).
 
-:- pred goal_util__rename_var_maps_2(bool::in, map(var(V), var(V))::in,
+:- pred rename_var_maps_2(bool::in, map(var(V), var(V))::in,
     assoc_list(var(V), T)::in, assoc_list(var(V), T)::out) is det.
 
-goal_util__rename_var_maps_2(_Must, _Subn, [], []).
-goal_util__rename_var_maps_2(Must, Subn, [V - L | Vs], [N - L | Ns]) :-
-    goal_util__rename_var(Must, Subn, V, N),
-    goal_util__rename_var_maps_2(Must, Subn, Vs, Ns).
+rename_var_maps_2(_Must, _Subn, [], []).
+rename_var_maps_2(Must, Subn, [V - L | Vs], [N - L | Ns]) :-
+    rename_var(Must, Subn, V, N),
+    rename_var_maps_2(Must, Subn, Vs, Ns).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__rename_vars_in_goal_info(bool::in, prog_var_renaming::in,
-    hlds_goal_info::in, hlds_goal_info::out) is det.
-
-goal_util__rename_vars_in_goal_info(Must, Subn, !GoalInfo) :-
+rename_vars_in_goal_info(Must, Subn, !GoalInfo) :-
     goal_info_get_nonlocals(!.GoalInfo, NonLocals0),
-    goal_util__rename_vars_in_var_set(Must, Subn, NonLocals0, NonLocals),
+    rename_vars_in_var_set(Must, Subn, NonLocals0, NonLocals),
     goal_info_set_nonlocals(NonLocals, !GoalInfo),
 
     goal_info_get_instmap_delta(!.GoalInfo, InstMap0),
@@ -710,22 +708,21 @@
     goal_info_set_instmap_delta(InstMap, !GoalInfo),
 
     goal_info_get_code_gen_info(!.GoalInfo, CodeGenInfo0),
-    goal_util__rename_vars_in_code_gen_info(Must, Subn,
-        CodeGenInfo0, CodeGenInfo),
+    rename_vars_in_code_gen_info(Must, Subn, CodeGenInfo0, CodeGenInfo),
     goal_info_set_code_gen_info(CodeGenInfo, !GoalInfo).
 
 %-----------------------------------------------------------------------------%
 
-goal_util__rename_vars_in_var_set(Must, Subn, Vars0, Vars) :-
+rename_vars_in_var_set(Must, Subn, Vars0, Vars) :-
     set__to_sorted_list(Vars0, VarsList0),
-    goal_util__rename_var_list(Must, Subn, VarsList0, VarsList),
+    rename_var_list(Must, Subn, VarsList0, VarsList),
     set__list_to_set(VarsList, Vars).
 
-:- pred goal_util__rename_vars_in_code_gen_info(bool::in,
+:- pred rename_vars_in_code_gen_info(bool::in,
     prog_var_renaming::in,
     hlds_goal_code_gen_info::in, hlds_goal_code_gen_info::out) is det.
 
-goal_util__rename_vars_in_code_gen_info(Must, Subn,
+rename_vars_in_code_gen_info(Must, Subn,
         CodeGenInfo0, CodeGenInfo) :-
     (
         CodeGenInfo0 = no_code_gen_info,
@@ -738,13 +735,13 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__goal_vars(Goal - _GoalInfo, Set) :-
-    goal_util__goal_vars_2(Goal, set__init, Set).
+goal_vars(Goal - _GoalInfo, Set) :-
+    goal_vars_2(Goal, set__init, Set).
 
-:- pred goal_util__goal_vars_2(hlds_goal_expr::in,
+:- pred goal_vars_2(hlds_goal_expr::in,
     set(prog_var)::in, set(prog_var)::out) is det.
 
-goal_util__goal_vars_2(unify(Var, RHS, _, Unif, _), !Set) :-
+goal_vars_2(unify(Var, RHS, _, Unif, _), !Set) :-
     set__insert(!.Set, Var, !:Set),
     ( Unif = construct(_, _, _, _, CellToReuse, _, _) ->
         ( CellToReuse = reuse_cell(cell_to_reuse(Var, _, _)) ->
@@ -755,30 +752,30 @@
     ;
         true
     ),
-    goal_util__rhs_goal_vars(RHS, !Set).
+    rhs_goal_vars(RHS, !Set).
 
-goal_util__goal_vars_2(generic_call(GenericCall, ArgVars, _, _), !Set) :-
-    goal_util__generic_call_vars(GenericCall, Vars0),
+goal_vars_2(generic_call(GenericCall, ArgVars, _, _), !Set) :-
+    generic_call_vars(GenericCall, Vars0),
     set__insert_list(!.Set, Vars0, !:Set),
     set__insert_list(!.Set, ArgVars, !:Set).
 
-goal_util__goal_vars_2(call(_, _, ArgVars, _, _, _), !Set) :-
+goal_vars_2(call(_, _, ArgVars, _, _, _), !Set) :-
     set__insert_list(!.Set, ArgVars, !:Set).
 
-goal_util__goal_vars_2(conj(Goals), !Set) :-
-    goal_util__goals_goal_vars(Goals, !Set).
+goal_vars_2(conj(Goals), !Set) :-
+    goals_goal_vars(Goals, !Set).
 
-goal_util__goal_vars_2(par_conj(Goals), !Set) :-
-    goal_util__goals_goal_vars(Goals, !Set).
+goal_vars_2(par_conj(Goals), !Set) :-
+    goals_goal_vars(Goals, !Set).
 
-goal_util__goal_vars_2(disj(Goals), !Set) :-
-    goal_util__goals_goal_vars(Goals, !Set).
+goal_vars_2(disj(Goals), !Set) :-
+    goals_goal_vars(Goals, !Set).
 
-goal_util__goal_vars_2(switch(Var, _Det, Cases), !Set) :-
+goal_vars_2(switch(Var, _Det, Cases), !Set) :-
     set__insert(!.Set, Var, !:Set),
-    goal_util__cases_goal_vars(Cases, !Set).
+    cases_goal_vars(Cases, !Set).
 
-goal_util__goal_vars_2(scope(Reason, Goal - _), !Set) :-
+goal_vars_2(scope(Reason, Goal - _), !Set) :-
     (
         Reason = exist_quant(Vars),
         set__insert_list(!.Set, Vars, !:Set)
@@ -795,64 +792,64 @@
         Reason = from_ground_term(Var),
         set__insert(!.Set, Var, !:Set)
     ),
-    goal_util__goal_vars_2(Goal, !Set).
+    goal_vars_2(Goal, !Set).
 
-goal_util__goal_vars_2(not(Goal - _GoalInfo), !Set) :-
-    goal_util__goal_vars_2(Goal, !Set).
+goal_vars_2(not(Goal - _GoalInfo), !Set) :-
+    goal_vars_2(Goal, !Set).
 
-goal_util__goal_vars_2(if_then_else(Vars, A - _, B - _, C - _), !Set) :-
+goal_vars_2(if_then_else(Vars, A - _, B - _, C - _), !Set) :-
     set__insert_list(!.Set, Vars, !:Set),
-    goal_util__goal_vars_2(A, !Set),
-    goal_util__goal_vars_2(B, !Set),
-    goal_util__goal_vars_2(C, !Set).
+    goal_vars_2(A, !Set),
+    goal_vars_2(B, !Set),
+    goal_vars_2(C, !Set).
 
-goal_util__goal_vars_2(foreign_proc(_, _, _, Args, ExtraArgs, _), !Set) :-
+goal_vars_2(foreign_proc(_, _, _, Args, ExtraArgs, _), !Set) :-
     ArgVars = list__map(foreign_arg_var, Args),
     ExtraVars = list__map(foreign_arg_var, ExtraArgs),
     set__insert_list(!.Set, list__append(ArgVars, ExtraVars), !:Set).
 
-goal_util__goal_vars_2(shorthand(ShorthandGoal), !Set) :-
-    goal_util__goal_vars_2_shorthand(ShorthandGoal, !Set).
+goal_vars_2(shorthand(ShorthandGoal), !Set) :-
+    goal_vars_2_shorthand(ShorthandGoal, !Set).
 
-:- pred goal_util__goal_vars_2_shorthand(shorthand_goal_expr::in,
+:- pred goal_vars_2_shorthand(shorthand_goal_expr::in,
     set(prog_var)::in, set(prog_var)::out) is det.
 
-goal_util__goal_vars_2_shorthand(bi_implication(LHS - _, RHS - _), !Set) :-
-    goal_util__goal_vars_2(LHS, !Set),
-    goal_util__goal_vars_2(RHS, !Set).
-
-goal_util__goals_goal_vars([], !Set).
-goal_util__goals_goal_vars([Goal - _ | Goals], !Set) :-
-    goal_util__goal_vars_2(Goal, !Set),
-    goal_util__goals_goal_vars(Goals, !Set).
+goal_vars_2_shorthand(bi_implication(LHS - _, RHS - _), !Set) :-
+    goal_vars_2(LHS, !Set),
+    goal_vars_2(RHS, !Set).
+
+goals_goal_vars([], !Set).
+goals_goal_vars([Goal - _ | Goals], !Set) :-
+    goal_vars_2(Goal, !Set),
+    goals_goal_vars(Goals, !Set).
 
-:- pred goal_util__cases_goal_vars(list(case)::in,
+:- pred cases_goal_vars(list(case)::in,
     set(prog_var)::in, set(prog_var)::out) is det.
 
-goal_util__cases_goal_vars([], !Set).
-goal_util__cases_goal_vars([case(_, Goal - _) | Cases], !Set) :-
-    goal_util__goal_vars_2(Goal, !Set),
-    goal_util__cases_goal_vars(Cases, !Set).
+cases_goal_vars([], !Set).
+cases_goal_vars([case(_, Goal - _) | Cases], !Set) :-
+    goal_vars_2(Goal, !Set),
+    cases_goal_vars(Cases, !Set).
 
-:- pred goal_util__rhs_goal_vars(unify_rhs::in,
+:- pred rhs_goal_vars(unify_rhs::in,
     set(prog_var)::in, set(prog_var)::out) is det.
 
-goal_util__rhs_goal_vars(RHS, !Set) :-
+rhs_goal_vars(RHS, !Set) :-
     RHS = var(X),
     set__insert(!.Set, X, !:Set).
-goal_util__rhs_goal_vars(RHS, !Set) :-
+rhs_goal_vars(RHS, !Set) :-
     RHS = functor(_Functor, _, ArgVars),
     set__insert_list(!.Set, ArgVars, !:Set).
-goal_util__rhs_goal_vars(RHS, !Set) :-
+rhs_goal_vars(RHS, !Set) :-
     RHS = lambda_goal(_, _, _, _, NonLocals, LambdaVars, _, _, Goal - _),
     set__insert_list(!.Set, NonLocals, !:Set),
     set__insert_list(!.Set, LambdaVars, !:Set),
-    goal_util__goal_vars_2(Goal, !Set).
+    goal_vars_2(Goal, !Set).
 
-goal_util__generic_call_vars(higher_order(Var, _, _, _), [Var]).
-goal_util__generic_call_vars(class_method(Var, _, _, _), [Var]).
-goal_util__generic_call_vars(cast(_), []).
-goal_util__generic_call_vars(aditi_builtin(_, _), []).
+generic_call_vars(higher_order(Var, _, _, _), [Var]).
+generic_call_vars(class_method(Var, _, _, _), [Var]).
+generic_call_vars(cast(_), []).
+generic_call_vars(aditi_builtin(_, _), []).
 
 %-----------------------------------------------------------------------------%
 
@@ -924,7 +921,7 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__extra_nonlocal_typeinfos(RttiVarMaps, VarTypes, ExistQVars,
+extra_nonlocal_typeinfos(RttiVarMaps, VarTypes, ExistQVars,
         NonLocals, NonLocalTypeInfos) :-
 
         % Find all non-local type vars.  That is, type vars that are
@@ -970,9 +967,9 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__goal_is_branched(if_then_else(_, _, _, _)).
-goal_util__goal_is_branched(switch(_, _, _)).
-goal_util__goal_is_branched(disj(_)).
+goal_is_branched(if_then_else(_, _, _, _)).
+goal_is_branched(switch(_, _, _)).
+goal_is_branched(disj(_)).
 
 %-----------------------------------------------------------------------------%
 
@@ -1235,17 +1232,16 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__switch_to_disjunction(_, [], _, [],
-        !VarSet, !VarTypes, !ModuleInfo).
-goal_util__switch_to_disjunction(Var, [case(ConsId, Goal0) | Cases], InstMap,
+switch_to_disjunction(_, [], _, [], !VarSet, !VarTypes, !ModuleInfo).
+switch_to_disjunction(Var, [case(ConsId, Goal0) | Cases], InstMap,
         [Goal | Goals], !VarSet, !VarTypes, !ModuleInfo) :-
-    goal_util__case_to_disjunct(Var, ConsId, Goal0, InstMap, Goal,
-        !VarSet, !VarTypes, !ModuleInfo),
-    goal_util__switch_to_disjunction(Var, Cases, InstMap, Goals,
-        !VarSet, !VarTypes, !ModuleInfo).
+    case_to_disjunct(Var, ConsId, Goal0, InstMap, Goal, !VarSet, !VarTypes,
+        !ModuleInfo),
+    switch_to_disjunction(Var, Cases, InstMap, Goals, !VarSet, !VarTypes,
+        !ModuleInfo).
 
-goal_util__case_to_disjunct(Var, ConsId, CaseGoal, InstMap, Disjunct,
-        !VarSet, !VarTypes, !ModuleInfo) :-
+case_to_disjunct(Var, ConsId, CaseGoal, InstMap, Disjunct, !VarSet, !VarTypes,
+        !ModuleInfo) :-
     ConsArity = cons_id_arity(ConsId),
     varset__new_vars(!.VarSet, ConsArity, ArgVars, !:VarSet),
     map__lookup(!.VarTypes, Var, VarType),
@@ -1259,7 +1255,7 @@
     ->
         ArgInsts = ArgInsts1
     ;
-        error("goal_util__case_to_disjunct - get_arg_insts failed")
+        unexpected(this_file, "case_to_disjunct - get_arg_insts failed")
     ),
     InstToUniMode = (pred(ArgInst::in, ArgUniMode::out) is det :-
             ArgUniMode = ((ArgInst - free) -> (ArgInst - ArgInst))
@@ -1299,9 +1295,8 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__if_then_else_to_disjunction(Cond0, Then, Else, GoalInfo, Goal) :-
-    goal_util__compute_disjunct_goal_info(Cond0, Then,
-        GoalInfo, CondThenInfo),
+if_then_else_to_disjunction(Cond0, Then, Else, GoalInfo, Goal) :-
+    compute_disjunct_goal_info(Cond0, Then, GoalInfo, CondThenInfo),
     conj_list_to_goal([Cond0, Then], CondThenInfo, CondThen),
 
     Cond0 = _ - CondInfo0,
@@ -1326,8 +1321,9 @@
     ( MaybeNegCondDet = yes(NegCondDet1) ->
         NegCondDet = NegCondDet1
     ;
-        error("goal_util__if_then_else_to_disjunction: " ++
-            "inappropriate determinism in a negation.")
+        unexpected(this_file,
+            "if_then_else_to_disjunction: "
+                ++ "inappropriate determinism in a negation.")
     ),
     determinism_components(NegCondDet, _, NegCondMaxSoln),
     ( NegCondMaxSoln = at_most_zero ->
@@ -1340,17 +1336,17 @@
     goal_info_init(CondNonLocals, NegCondDelta, NegCondDet, CondPurity,
         NegCondInfo),
 
-    goal_util__compute_disjunct_goal_info(not(Cond) - NegCondInfo, Else,
+    compute_disjunct_goal_info(not(Cond) - NegCondInfo, Else,
         GoalInfo, NegCondElseInfo),
     conj_list_to_goal([not(Cond) - NegCondInfo, Else],
         NegCondElseInfo, NegCondElse),
     Goal = disj([CondThen, NegCondElse]).
 
     % Compute a hlds_goal_info for a pair of conjoined goals.
-:- pred goal_util__compute_disjunct_goal_info(hlds_goal::in, hlds_goal::in,
+:- pred compute_disjunct_goal_info(hlds_goal::in, hlds_goal::in,
     hlds_goal_info::in, hlds_goal_info::out) is det.
 
-goal_util__compute_disjunct_goal_info(Goal1, Goal2, GoalInfo, CombinedInfo) :-
+compute_disjunct_goal_info(Goal1, Goal2, GoalInfo, CombinedInfo) :-
     Goal1 = _ - GoalInfo1,
     Goal2 = _ - GoalInfo2,
 
@@ -1378,9 +1374,8 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-goal_util__can_reorder_goals(ModuleInfo, VarTypes, FullyStrict,
-        InstmapBeforeEarlierGoal, EarlierGoal, InstmapBeforeLaterGoal,
-        LaterGoal) :-
+can_reorder_goals(ModuleInfo, VarTypes, FullyStrict, InstmapBeforeEarlierGoal,
+        EarlierGoal, InstmapBeforeLaterGoal, LaterGoal) :-
 
     EarlierGoal = _ - EarlierGoalInfo,
     LaterGoal = _ - LaterGoalInfo,
@@ -1389,7 +1384,7 @@
     \+ goal_info_is_impure(EarlierGoalInfo),
     \+ goal_info_is_impure(LaterGoalInfo),
 
-    goal_util__reordering_maintains_termination(ModuleInfo, FullyStrict,
+    reordering_maintains_termination(ModuleInfo, FullyStrict,
         EarlierGoal, LaterGoal),
 
     %
@@ -1409,7 +1404,7 @@
     \+ goal_depends_on_earlier_goal(EarlierGoal, LaterGoal,
         InstmapBeforeLaterGoal, VarTypes, ModuleInfo).
 
-goal_util__reordering_maintains_termination(ModuleInfo, FullyStrict,
+reordering_maintains_termination(ModuleInfo, FullyStrict,
         EarlierGoal, LaterGoal) :-
     EarlierGoal = _ - EarlierGoalInfo,
     LaterGoal = _ - LaterGoalInfo,
@@ -1463,8 +1458,8 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__generate_simple_call(ModuleName, ProcName, PredOrFunc, ModeNo,
-        Detism, Args, Features, InstMap, ModuleInfo, Context, Goal) :-
+generate_simple_call(ModuleName, ProcName, PredOrFunc, ModeNo, Detism, Args,
+        Features, InstMap, ModuleInfo, Context, Goal) :-
     list__length(Args, Arity),
     lookup_builtin_pred_proc_id(ModuleInfo, ModuleName, ProcName,
         PredOrFunc, Arity, ModeNo, PredId, ProcId),
@@ -1492,9 +1487,9 @@
     list__foldl(goal_info_add_feature, Features, GoalInfo0, GoalInfo),
     Goal = GoalExpr - GoalInfo.
 
-goal_util__generate_foreign_proc(ModuleName, ProcName, PredOrFunc, ModeNo,
-        Detism, Attributes, Args, ExtraArgs, PrefixCode, Code,
-        SuffixCode, Features, InstMap, ModuleInfo, Context, Goal) :-
+generate_foreign_proc(ModuleName, ProcName, PredOrFunc, ModeNo, Detism,
+        Attributes, Args, ExtraArgs, PrefixCode, Code, SuffixCode, Features,
+        InstMap, ModuleInfo, Context, Goal) :-
     list__length(Args, Arity),
     lookup_builtin_pred_proc_id(ModuleInfo, ModuleName, ProcName,
         PredOrFunc, Arity, ModeNo, PredId, ProcId),
@@ -1519,13 +1514,11 @@
     list__foldl(goal_info_add_feature, Features, GoalInfo0, GoalInfo),
     Goal = GoalExpr - GoalInfo.
 
-goal_util__generate_cast(CastType, InArg, OutArg, Context, Goal) :-
+generate_cast(CastType, InArg, OutArg, Context, Goal) :-
     Ground = ground_inst,
-    goal_util__generate_cast(CastType, InArg, OutArg, Ground, Ground,
-        Context, Goal).
+    generate_cast(CastType, InArg, OutArg, Ground, Ground, Context, Goal).
 
-goal_util__generate_cast(CastType, InArg, OutArg, InInst, OutInst, Context,
-        Goal) :-
+generate_cast(CastType, InArg, OutArg, InInst, OutInst, Context, Goal) :-
     set__list_to_set([InArg, OutArg], NonLocals),
     instmap_delta_from_assoc_list([OutArg - OutInst], InstMapDelta),
     goal_info_init(NonLocals, InstMapDelta, det, pure, Context, GoalInfo),
@@ -1550,6 +1543,21 @@
         % goal_calls_pred_id has multiple modes.
     P = (pred(PredId::out) is nondet :- goal_calls_pred_id(Goal, PredId)),
     solutions(P, PredIds).
+
+%-----------------------------------------------------------------------------%
+
+foreign_code_uses_variable(Impl, VarName) :-
+    (
+        Impl = ordinary(ForeignBody, _),
+        string__sub_string_search(ForeignBody, VarName, _)
+    ;
+        Impl = nondet(FB1, _, FB2, _, FB3, _, _, FB4, _),
+        ( string__sub_string_search(FB1, VarName, _)
+        ; string__sub_string_search(FB2, VarName, _)
+        ; string__sub_string_search(FB3, VarName, _)
+        ; string__sub_string_search(FB4, VarName, _)
+        )
+    ).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.96
diff -u -b -r1.96 ml_code_util.m
--- compiler/ml_code_util.m	5 Oct 2005 06:33:44 -0000	1.96
+++ compiler/ml_code_util.m	11 Oct 2005 14:48:22 -0000
@@ -646,16 +646,18 @@
 :- pred ml_gen_info_new_const(const_seq::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-    % Set the `const' sequence number corresponding to a given HLDS variable.
+    % Set the `const' variable name corresponding to the given HLDS variable.
     %
-:- pred ml_gen_info_set_const_num(prog_var::in, const_seq::in,
+:- pred ml_gen_info_set_const_var_name(prog_var::in, mlds__var_name::in,
     ml_gen_info::in, ml_gen_info::out) is det.
 
     % Lookup the `const' sequence number corresponding to a given HLDS
     % variable.
     %
-:- pred ml_gen_info_lookup_const_num(ml_gen_info::in, prog_var::in,
-    const_seq::out) is det.
+:- pred ml_gen_info_lookup_const_var_name(ml_gen_info::in, prog_var::in,
+    mlds__var_name::out) is det.
+:- pred ml_gen_info_search_const_var_name(ml_gen_info::in, prog_var::in,
+    mlds__var_name::out) is semidet.
 
     % A success continuation specifies the (rval for the variable holding
     % the address of the) function that a nondet procedure should call
@@ -2379,7 +2381,7 @@
                 cond_var            :: counter,
                 conv_var            :: counter,
                 const_num           :: counter,
-                const_num_map       :: map(prog_var, const_seq),
+                const_var_name_map  :: map(prog_var, mlds__var_name),
                 success_cont_stack  :: stack(success_cont),
                                     % A partial mapping from vars to lvals,
                                     % used to override the normal lval
@@ -2512,12 +2514,15 @@
     counter__allocate(ConstVar, Counter0, Counter),
     !:Info = !.Info ^ const_num := Counter.
 
-ml_gen_info_set_const_num(Var, ConstVar, !Info) :-
-    !:Info = !.Info ^ const_num_map :=
-        map__set(!.Info ^ const_num_map, Var, ConstVar).
+ml_gen_info_set_const_var_name(Var, Name, !Info) :-
+    !:Info = !.Info ^ const_var_name_map :=
+        map__set(!.Info ^ const_var_name_map, Var, Name).
 
-ml_gen_info_lookup_const_num(Info, Var, ConstVar) :-
-    ConstVar = map__lookup(Info ^ const_num_map, Var).
+ml_gen_info_lookup_const_var_name(Info, Var, Name) :-
+    Name = map__lookup(Info ^ const_var_name_map, Var).
+
+ml_gen_info_search_const_var_name(Info, Var, Name) :-
+    Name = map__search(Info ^ const_var_name_map, Var).
 
 ml_gen_info_push_success_cont(SuccCont, !Info) :-
     !:Info = !.Info ^ success_cont_stack :=
Index: compiler/ml_unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.87
diff -u -b -r1.87 ml_unify_gen.m
--- compiler/ml_unify_gen.m	5 Oct 2005 06:33:45 -0000	1.87
+++ compiler/ml_unify_gen.m	11 Oct 2005 14:55:52 -0000
@@ -121,20 +121,34 @@
 %-----------------------------------------------------------------------------%
 
 ml_gen_unification(Unification, CodeModel, Context, [], Statements, !Info) :-
-    Unification = assign(Var1, Var2),
+    Unification = assign(TargetVar, SourceVar),
     require(unify(CodeModel, model_det), "ml_code_gen: assign not det"),
     (
         % Skip dummy argument types, since they will not have been declared.
-        ml_variable_type(!.Info, Var1, Type),
+        ml_variable_type(!.Info, TargetVar, Type),
         ml_gen_info_get_module_info(!.Info, ModuleInfo),
         is_dummy_argument_type(ModuleInfo, Type)
     ->
         Statements = []
     ;
-        ml_gen_var(!.Info, Var1, Var1Lval),
-        ml_gen_var(!.Info, Var2, Var2Lval),
-        Statement = ml_gen_assign(Var1Lval, lval(Var2Lval), Context),
+        ml_gen_var(!.Info, TargetVar, TargetLval),
+        ml_gen_var(!.Info, SourceVar, SourceLval),
+        Statement = ml_gen_assign(TargetLval, lval(SourceLval), Context),
         Statements = [Statement]
+    ),
+    ( ml_gen_info_search_const_var_name(!.Info, SourceVar, Name) ->
+        % If the source variable is a constant, so is the target after
+        % this assignment.
+        %
+        % The mark_static_terms assumes that if SourceVar is a constant term,
+        % then after this assignment unification TargetVar is a constant term
+        % also. Therefore later constant terms may contain TargetVar among
+        % their arguments. If we didn't copy the constant info here, the
+        % construction of the later constant could cause a code generator
+        % abort.
+        ml_gen_info_set_const_var_name(TargetVar, Name, !Info)
+    ;
+        true
     ).
 
 ml_gen_unification(Unification, CodeModel, Context, [], [Statement], !Info) :-
@@ -158,8 +172,7 @@
         !Info) :-
     Unification = construct(Var, ConsId, Args, ArgModes, HowToConstruct,
         _CellIsUnique, SubInfo),
-    require(unify(CodeModel, model_det),
-        "ml_code_gen: construct not det"),
+    require(unify(CodeModel, model_det), "ml_code_gen: construct not det"),
     (
         SubInfo = no_construct_sub_info
     ;
@@ -659,7 +672,7 @@
         UsesBaseClass = (MaybeCtorName = yes(_) -> no ; yes),
         ConstType = get_type_for_cons_id(MLDS_Type, UsesBaseClass,
             MaybeConsId, HighLevelData, Globals),
-        % XXX if the secondary tag is in a base class, then ideally its
+        % XXX If the secondary tag is in a base class, then ideally its
         % initializer should be wrapped in `init_struct([init_obj(X)])'
         % rather than just `init_obj(X)' -- the fact that we don't leads to
         % some warnings from GNU C about missing braces in initializers.
@@ -1067,21 +1080,17 @@
 
 ml_gen_static_const_name(Var, ConstName, !Info) :-
     ml_gen_info_new_const(SequenceNum, !Info),
-    ml_gen_info_set_const_num(Var, SequenceNum, !Info),
     ml_gen_info_get_varset(!.Info, VarSet),
     VarName = ml_gen_var_name(VarSet, Var),
     ml_format_static_const_name(!.Info, ml_var_name_to_string(VarName),
-        SequenceNum, ConstName).
+        SequenceNum, ConstName),
+    ml_gen_info_set_const_var_name(Var, ConstName, !Info).
 
 :- pred ml_lookup_static_const_name(ml_gen_info::in, prog_var::in,
     mlds__var_name::out) is det.
 
 ml_lookup_static_const_name(Info, Var, ConstName) :-
-    ml_gen_info_lookup_const_num(Info, Var, SequenceNum),
-    ml_gen_info_get_varset(Info, VarSet),
-    VarName = ml_gen_var_name(VarSet, Var),
-    ml_format_static_const_name(Info, ml_var_name_to_string(VarName),
-        SequenceNum, ConstName).
+    ml_gen_info_lookup_const_var_name(Info, Var, ConstName).
 
     % Generate an rval containing the address of the local static constant
     % for a given variable.
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.279
diff -u -b -r1.279 polymorphism.m
--- compiler/polymorphism.m	10 Oct 2005 07:54:36 -0000	1.279
+++ compiler/polymorphism.m	12 Oct 2005 03:19:54 -0000
@@ -1465,33 +1465,44 @@
     % Insert the type_info vars into the argname map, so that the foreign_proc
     % can refer to the type_info variable for type T as `TypeInfo_for_T'.
     Goal0 = foreign_proc(Attributes, PredId, ProcId, Args0, ProcExtraArgs,
-        PragmaCode0),
+        Impl0),
     ArgVars0 = list__map(foreign_arg_var, Args0),
     process_call(PredId, ArgVars0, GoalInfo0, GoalInfo, ExtraVars, ExtraGoals,
         !Info),
-    process_foreign_proc_args(PredInfo, PragmaCode0, ExtraVars, ExtraArgs),
+    ( Impl0 = import(_, _, _, _) ->
+        % The reference manual guarantees a one-to-one correspondence between
+        % the arguments of the predicate (as augmented by with type_info and/or
+        % typeclass_info arguments by polymorphism.m) and the arguments of the
+        % imported function.
+        CanOptAwayUnnamed = no
+    ;
+        CanOptAwayUnnamed = yes
+    ),
+    process_foreign_proc_args(PredInfo, CanOptAwayUnnamed, Impl0, ExtraVars,
+        ExtraArgs),
     Args = ExtraArgs ++ Args0,
 
     % Add the type info arguments to the list of variables
     % to call for a pragma import.
-    ( PragmaCode0 = import(Name, HandleReturn, Variables0, MaybeContext) ->
+    ( Impl0 = import(Name, HandleReturn, Variables0, MaybeContext) ->
         Variables = type_info_vars(ModuleInfo, ExtraArgs, Variables0),
-        PragmaCode = import(Name, HandleReturn, Variables, MaybeContext)
+        Impl = import(Name, HandleReturn, Variables, MaybeContext)
     ;
-        PragmaCode = PragmaCode0
+        Impl = Impl0
     ),
 
     % Plug it all back together.
     CallExpr = foreign_proc(Attributes, PredId, ProcId, Args, ProcExtraArgs,
-        PragmaCode),
+        Impl),
     Call = CallExpr - GoalInfo,
     list__append(ExtraGoals, [Call], GoalList),
     conj_list_to_goal(GoalList, GoalInfo0, Goal).
 
-:- pred process_foreign_proc_args(pred_info::in, pragma_foreign_code_impl::in,
-    list(prog_var)::in, list(foreign_arg)::out) is det.
+:- pred process_foreign_proc_args(pred_info::in, bool::in,
+    pragma_foreign_code_impl::in, list(prog_var)::in, list(foreign_arg)::out)
+    is det.
 
-process_foreign_proc_args(PredInfo, Impl, Vars, Args) :-
+process_foreign_proc_args(PredInfo, CanOptAwayUnnamed, Impl, Vars, Args) :-
     pred_info_arg_types(PredInfo, PredTypeVarSet, ExistQVars, PredArgTypes),
 
     % Find out which variables are constrained (so that we don't add
@@ -1517,19 +1528,19 @@
     in_mode(In),
     out_mode(Out),
 
-    list__map(foreign_proc_add_typeclass_info(Out, Impl, PredTypeVarSet),
-        ExistCs, ExistTypeClassArgInfos),
-    list__map(foreign_proc_add_typeclass_info(In, Impl, PredTypeVarSet),
-        UnivCs, UnivTypeClassArgInfos),
+    list__map(foreign_proc_add_typeclass_info(CanOptAwayUnnamed, Out, Impl,
+        PredTypeVarSet), ExistCs, ExistTypeClassArgInfos),
+    list__map(foreign_proc_add_typeclass_info(CanOptAwayUnnamed, In, Impl,
+        PredTypeVarSet), UnivCs, UnivTypeClassArgInfos),
     TypeClassArgInfos = UnivTypeClassArgInfos ++ ExistTypeClassArgInfos,
 
     list__filter((pred(X::in) is semidet :- list__member(X, ExistQVars)),
         PredTypeVars, ExistUnconstrainedVars, UnivUnconstrainedVars),
 
-    list__map(foreign_proc_add_typeinfo(Out, Impl, PredTypeVarSet),
-        ExistUnconstrainedVars, ExistTypeArgInfos),
-    list__map(foreign_proc_add_typeinfo(In, Impl, PredTypeVarSet),
-        UnivUnconstrainedVars, UnivTypeArgInfos),
+    list__map(foreign_proc_add_typeinfo(CanOptAwayUnnamed, Out, Impl,
+        PredTypeVarSet), ExistUnconstrainedVars, ExistTypeArgInfos),
+    list__map(foreign_proc_add_typeinfo(CanOptAwayUnnamed, In, Impl,
+        PredTypeVarSet), UnivUnconstrainedVars, UnivTypeArgInfos),
     TypeInfoArgInfos = UnivTypeArgInfos ++ ExistTypeArgInfos,
 
     ArgInfos = TypeInfoArgInfos ++ TypeClassArgInfos,
@@ -1544,11 +1555,11 @@
 
     make_foreign_args(Vars, ArgInfos, OrigArgTypes, Args).
 
-:- pred foreign_proc_add_typeclass_info((mode)::in,
+:- pred foreign_proc_add_typeclass_info(bool::in, (mode)::in,
     pragma_foreign_code_impl::in, tvarset::in, prog_constraint::in,
     maybe(pair(string, mode))::out) is det.
 
-foreign_proc_add_typeclass_info(Mode, Impl, TypeVarSet,
+foreign_proc_add_typeclass_info(CanOptAwayUnnamed, Mode, Impl, TypeVarSet,
         Constraint, MaybeArgName) :-
     Constraint = constraint(Name0, Types),
     mdbcomp__prim_data__sym_name_to_string(Name0, "__", Name),
@@ -1558,21 +1569,29 @@
         ConstraintVarName),
     % If the variable name corresponding to the typeclass_info isn't mentioned
     % in the C code fragment, don't pass the variable to the C code at all.
-    ( foreign_code_does_not_use_variable(Impl, ConstraintVarName) ->
+    (
+        CanOptAwayUnnamed = yes,
+        foreign_code_does_not_use_variable(Impl, ConstraintVarName)
+    ->
         MaybeArgName = no
     ;
         MaybeArgName = yes(ConstraintVarName - Mode)
     ).
 
-:- pred foreign_proc_add_typeinfo((mode)::in, pragma_foreign_code_impl::in,
-    tvarset::in, tvar::in, maybe(pair(string, mode))::out) is det.
+:- pred foreign_proc_add_typeinfo(bool::in, (mode)::in,
+    pragma_foreign_code_impl::in, tvarset::in, tvar::in,
+    maybe(pair(string, mode))::out) is det.
 
-foreign_proc_add_typeinfo(Mode, Impl, TypeVarSet, TVar, MaybeArgName) :-
+foreign_proc_add_typeinfo(CanOptAwayUnnamed, Mode, Impl, TypeVarSet, TVar,
+        MaybeArgName) :-
     ( varset__search_name(TypeVarSet, TVar, TypeVarName) ->
         string__append("TypeInfo_for_", TypeVarName, C_VarName),
         % If the variable name corresponding to the type_info isn't mentioned
         % in the C code fragment, don't pass the variable to the C code at all.
-        ( foreign_code_does_not_use_variable(Impl, C_VarName) ->
+        (
+            CanOptAwayUnnamed = yes,
+            foreign_code_does_not_use_variable(Impl, C_VarName)
+        ->
             MaybeArgName = no
         ;
             MaybeArgName = yes(C_VarName - Mode)
@@ -1589,16 +1608,7 @@
     % the compiler to abort when compiling declarative_execution.m in stage2,
     % but this is no longer the case.
     % semidet_fail,
-    (
-        Impl = ordinary(ForeignBody, _),
-        \+ string__sub_string_search(ForeignBody, VarName, _)
-    ;
-        Impl = nondet(FB1, _, FB2, _, FB3, _, _, FB4, _),
-        \+ string__sub_string_search(FB1, VarName, _),
-        \+ string__sub_string_search(FB2, VarName, _),
-        \+ string__sub_string_search(FB3, VarName, _),
-        \+ string__sub_string_search(FB4, VarName, _)
-    ).
+    \+ foreign_code_uses_variable(Impl, VarName).
 
 :- func underscore_and_tvar_name(tvarset, tvar) = string.
 
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.83
diff -u -b -r1.83 pragma_c_gen.m
--- compiler/pragma_c_gen.m	10 Oct 2005 07:54:36 -0000	1.83
+++ compiler/pragma_c_gen.m	12 Oct 2005 02:43:23 -0000
@@ -344,26 +344,31 @@
         Args, ExtraArgs, GoalInfo, PragmaImpl, Code, !CI) :-
     (
         PragmaImpl = ordinary(C_Code, Context),
+        CanOptAwayUnnamedArgs = yes,
         pragma_c_gen__ordinary_pragma_c_code(CodeModel, Attributes,
             PredId, ProcId, Args, ExtraArgs, C_Code, Context, GoalInfo,
-            Code, !CI)
+            CanOptAwayUnnamedArgs, Code, !CI)
     ;
         PragmaImpl = nondet(Fields, FieldsContext, First, FirstContext,
             Later, LaterContext, Treat, Shared, SharedContext),
         require(unify(ExtraArgs, []),
             "generate_pragma_c_code: extra args nondet"),
+        CanOptAwayUnnamedArgs = yes,
         pragma_c_gen__nondet_pragma_c_code(CodeModel, Attributes,
             PredId, ProcId, Args, Fields, FieldsContext,
             First, FirstContext, Later, LaterContext,
-            Treat, Shared, SharedContext, Code, !CI)
+            Treat, Shared, SharedContext, CanOptAwayUnnamedArgs, Code, !CI)
     ;
         PragmaImpl = import(Name, HandleReturn, Vars, Context),
         require(unify(ExtraArgs, []),
             "generate_pragma_c_code: extra args import"),
         C_Code = HandleReturn ++ " " ++ Name ++ "(" ++ Vars ++ ");",
+
+        % The imported function was generated with all arguments present.
+        CanOptAwayUnnamedArgs = no,
         pragma_c_gen__ordinary_pragma_c_code(CodeModel, Attributes,
             PredId, ProcId, Args, ExtraArgs, C_Code, Context, GoalInfo,
-            Code, !CI)
+            CanOptAwayUnnamedArgs, Code, !CI)
     ).
 
 %---------------------------------------------------------------------------%
@@ -371,18 +376,18 @@
 :- pred pragma_c_gen__ordinary_pragma_c_code(code_model::in,
     pragma_foreign_proc_attributes::in, pred_id::in, proc_id::in,
     list(foreign_arg)::in, list(foreign_arg)::in, string::in,
-    maybe(prog_context)::in, hlds_goal_info::in, code_tree::out,
+    maybe(prog_context)::in, hlds_goal_info::in, bool::in, code_tree::out,
     code_info::in, code_info::out) is det.
 
 pragma_c_gen__ordinary_pragma_c_code(CodeModel, Attributes, PredId, ProcId,
-        Args, ExtraArgs, C_Code, Context, GoalInfo, Code, !CI) :-
+        Args, ExtraArgs, C_Code, Context, GoalInfo, CanOptAwayUnnamedArgs, 
+        Code, !CI) :-
     % Extract the attributes.
     MayCallMercury = may_call_mercury(Attributes),
     ThreadSafe = thread_safe(Attributes),
-    %
+
     % The maybe_thread_safe attribute should have been changed
     % to the real value by now.
-    %
     (
         ThreadSafe = thread_safe
     ;
@@ -405,16 +410,13 @@
     set__init(DeadVars0),
     find_dead_input_vars(InCArgs, PostDeaths, DeadVars0, DeadVars),
 
-    %
-    % Generate code to <save live variables on stack>
-    %
+    % Generate code to <save live variables on stack>.
     (
         MayCallMercury = will_not_call_mercury,
         SaveVarsCode = empty
     ;
         MayCallMercury = may_call_mercury,
-        % The C code might call back Mercury code
-        % which clobbers the succip.
+        % The C code might call back Mercury code which clobbers the succip.
         code_info__succip_is_used(!CI),
 
         % The C code might call back Mercury code which clobbers the
@@ -425,42 +427,32 @@
         code_info__save_variables(OutVarsSet, _, SaveVarsCode, !CI)
     ),
 
-    %
     % Generate the values of input variables.
     % (NB we need to be careful that the rvals generated here
     % remain valid below.)
-    %
-    get_pragma_input_vars(InCArgs, InputDescs, InputVarsCode, !CI),
+    get_pragma_input_vars(InCArgs, InputDescs, CanOptAwayUnnamedArgs,
+        InputVarsCode, !CI),
 
-    %
     % We cannot kill the forward dead input arguments until we have
     % finished generating the code producing the input variables.
     % (The forward dead variables will be dead after the pragma_c_code,
     % but are live during its input phase.)
     code_info__make_vars_forward_dead(DeadVars, !CI),
 
-    %
-    % Generate <declaration of one local variable for each arg>
-    %
-    make_pragma_decls(CArgs, ModuleInfo, Decls),
+    % Generate <declaration of one local variable for each arg>.
+    make_pragma_decls(CArgs, ModuleInfo, CanOptAwayUnnamedArgs, Decls),
 
-    %
     % Generate #define MR_PROC_LABEL <procedure label> /* see note (5) */
-    % and #undef MR_PROC_LABEL
-    %
+    % and #undef MR_PROC_LABEL.
     code_info__get_pred_id(!.CI, CallerPredId),
     code_info__get_proc_id(!.CI, CallerProcId),
     make_proc_label_hash_define(ModuleInfo, CallerPredId, CallerProcId,
         ProcLabelHashDefine, ProcLabelHashUndef),
 
-    %
     % <assignment of input values from registers to local vars>
-    %
     InputComp = pragma_c_inputs(InputDescs),
 
-    %
     % MR_save_registers(); /* see notes (1) and (2) above */
-    %
     (
         MayCallMercury = will_not_call_mercury,
         SaveRegsComp = pragma_c_raw_code("", cannot_branch_away,
@@ -549,7 +541,7 @@
     ;
         MayCallMercury = may_call_mercury,
         goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
-        (instmap_delta_is_reachable(InstMapDelta) ->
+        ( instmap_delta_is_reachable(InstMapDelta) ->
             OkToDelete = no
         ;
             OkToDelete = yes
@@ -559,7 +551,8 @@
 
     % <assignment of the output values from local variables to registers>
     pragma_acquire_regs(OutCArgs, Regs, !CI),
-    place_pragma_output_args_in_regs(OutCArgs, Regs, OutputDescs, !CI),
+    place_pragma_output_args_in_regs(OutCArgs, Regs, CanOptAwayUnnamedArgs,
+        OutputDescs, !CI),
     OutputComp = pragma_c_outputs(OutputDescs),
 
     % Join all the components of the pragma_c together.
@@ -643,13 +636,13 @@
     string::in, maybe(prog_context)::in,
     string::in, maybe(prog_context)::in,
     string::in, maybe(prog_context)::in, pragma_shared_code_treatment::in,
-    string::in, maybe(prog_context)::in, code_tree::out,
+    string::in, maybe(prog_context)::in, bool::in, code_tree::out,
     code_info::in, code_info::out) is det.
 
 pragma_c_gen__nondet_pragma_c_code(CodeModel, Attributes, PredId, ProcId,
         Args, _Fields, _FieldsContext,
-        First, FirstContext, Later, LaterContext, Treat, Shared,
-        SharedContext, Code, !CI) :-
+        First, FirstContext, Later, LaterContext, Treat, Shared, SharedContext,
+        CanOptAwayUnnamedArgs, Code, !CI) :-
     require(unify(CodeModel, model_non),
         "inappropriate code model for nondet pragma C code"),
     % Extract the may_call_mercury attribute.
@@ -672,11 +665,13 @@
     make_c_arg_list(Args, ArgInfos, CArgs),
     pragma_select_in_args(CArgs, InCArgs),
     pragma_select_out_args(CArgs, OutCArgs),
-    make_pragma_decls(CArgs, ModuleInfo, Decls),
-    make_pragma_decls(OutCArgs, ModuleInfo, OutDecls),
+    make_pragma_decls(CArgs, ModuleInfo, CanOptAwayUnnamedArgs, Decls),
+    make_pragma_decls(OutCArgs, ModuleInfo, CanOptAwayUnnamedArgs, OutDecls),
 
-    input_descs_from_arg_info(!.CI, InCArgs, InputDescs),
-    output_descs_from_arg_info(!.CI, OutCArgs, OutputDescs),
+    input_descs_from_arg_info(!.CI, InCArgs, CanOptAwayUnnamedArgs,
+        InputDescs),
+    output_descs_from_arg_info(!.CI, OutCArgs, CanOptAwayUnnamedArgs,
+        OutputDescs),
 
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     ModuleName = pred_info_module(PredInfo),
@@ -1095,7 +1090,7 @@
         mode_to_arg_mode(ModuleInfo, Mode, OrigType, ArgMode)
     ;
         MaybeNameMode = no,
-        error("make_extra_c_arg_list_seq: no name")
+        unexpected(this_file, "make_extra_c_arg_list_seq: no name")
     ),
     NextReg = LastReg + 1,
     % Extra args are always input.
@@ -1148,9 +1143,12 @@
 
 %---------------------------------------------------------------------------%
 
-    % var_is_not_singleton determines whether or not a given pragma_c variable
-    % is singleton (i.e. starts with an underscore) or anonymous (in which case
-    % it's singleton anyway, it just doesn't necessarily have a singleton name).
+    % var_should_be_passed determines whether or not a variable with the given
+    % user-defined name (if any) should be passed to the foreign_proc.
+    % 
+    % Named non-singleton variables are always passed. Unnamed or singleton
+    % variables are ignored if we are allowed to optimize them away, but we
+    % aren't, we replace their name with UnnamedArgN.
     %
     % Singleton vars should be ignored when generating the declarations for
     % pragma_c arguments because:
@@ -1158,10 +1156,25 @@
     %   - they should not appear in the C code
     %   - they could clash with the system name space
     %
-:- pred var_is_not_singleton(maybe(string)::in, string::out) is semidet.
+:- func var_should_be_passed(bool, prog_var, maybe(string)) = maybe(string).
 
-var_is_not_singleton(yes(Name), Name) :-
-    \+ string__first_char(Name, '_', _).
+var_should_be_passed(CanOptAwayUnnamedArgs, Var, MaybeName)
+        = MaybeUseName :-
+    (
+        MaybeName = yes(Name),
+        not string__first_char(Name, '_', _)
+    ->
+        MaybeUseName = yes(Name)
+    ;
+        (
+            CanOptAwayUnnamedArgs = yes,
+            MaybeUseName = no
+        ;
+            CanOptAwayUnnamedArgs = no,
+            UseName = "UnnamedArg" ++ int_to_string(term__var_to_int(Var)),
+            MaybeUseName = yes(UseName)
+        )
+    ).
 
 %---------------------------------------------------------------------------%
 
@@ -1169,20 +1182,21 @@
     % data structure in the LLDS. It is essentially a list of pairs of type and
     % variable name, so that declarations of the form "Type Name;" can be made.
     %
-:- pred make_pragma_decls(list(c_arg)::in, module_info::in,
+:- pred make_pragma_decls(list(c_arg)::in, module_info::in, bool::in,
     list(pragma_c_decl)::out) is det.
 
-make_pragma_decls([], _, []).
-make_pragma_decls([Arg | Args], Module, Decls) :-
-    make_pragma_decls(Args, Module, DeclsTail),
-    Arg = c_arg(_Var, ArgName, OrigType, _ArgInfo),
-    ( var_is_not_singleton(ArgName, Name) ->
+make_pragma_decls([], _, _, []).
+make_pragma_decls([Arg | Args], Module, CanOptAwayUnnamedArgs, Decls) :-
+    make_pragma_decls(Args, Module, CanOptAwayUnnamedArgs, DeclsTail),
+    Arg = c_arg(Var, MaybeArgName, OrigType, _ArgInfo),
+    MaybeName = var_should_be_passed(CanOptAwayUnnamedArgs, Var, MaybeArgName),
+    (
+        MaybeName = yes(Name),
         OrigTypeString = foreign__to_type_string(c, Module, OrigType),
         Decl = pragma_c_arg_decl(OrigType, OrigTypeString, Name),
         Decls = [Decl | DeclsTail]
     ;
-        % if the variable doesn't occur in the ArgNames list,
-        % it can't be used, so we just ignore it
+        MaybeName = no,
         Decls = DeclsTail
     ).
 
@@ -1208,12 +1222,15 @@
     % variables, and the corresponding rvals assigned to those (C) variables.
     %
 :- pred get_pragma_input_vars(list(c_arg)::in, list(pragma_c_input)::out,
-    code_tree::out, code_info::in, code_info::out) is det.
+    bool::in, code_tree::out, code_info::in, code_info::out) is det.
 
-get_pragma_input_vars([], [], empty, !CI).
-get_pragma_input_vars([Arg | Args], Inputs, Code, !CI) :-
-    Arg = c_arg(Var, MaybeName, OrigType, _ArgInfo),
-    ( var_is_not_singleton(MaybeName, Name) ->
+get_pragma_input_vars([], [], _, empty, !CI).
+get_pragma_input_vars([Arg | Args], Inputs, CanOptAwayUnnamedArgs, Code,
+        !CI) :-
+    Arg = c_arg(Var, MaybeArgName, OrigType, _ArgInfo),
+    MaybeName = var_should_be_passed(CanOptAwayUnnamedArgs, Var, MaybeArgName),
+    (
+        MaybeName = yes(Name),
         VarType = variable_type(!.CI, Var),
         code_info__produce_variable(Var, FirstCode, Rval, !CI),
         MaybeForeign = get_maybe_foreign_type_info(!.CI, OrigType),
@@ -1225,13 +1242,14 @@
         ),
         Input = pragma_c_input(Name, VarType, IsDummy, OrigType, Rval,
             MaybeForeign),
-        get_pragma_input_vars(Args, Inputs1, RestCode, !CI),
+        get_pragma_input_vars(Args, Inputs1, CanOptAwayUnnamedArgs, RestCode,
+            !CI),
         Inputs = [Input | Inputs1],
         Code = tree(FirstCode, RestCode)
     ;
-        % If the variable doesn't occur in the ArgNames list, it can't be used,
-        % so we just ignore it.
-        get_pragma_input_vars(Args, Inputs, Code, !CI)
+        MaybeName = no,
+        % Just ignore the argument.
+        get_pragma_input_vars(Args, Inputs, CanOptAwayUnnamedArgs, Code, !CI)
     ).
 
 :- func get_maybe_foreign_type_info(code_info, (type)) =
@@ -1252,8 +1270,7 @@
             MaybeForeignTypeInfo = yes(pragma_c_foreign_type(Name, Assertions))
         ;
             MaybeC = no,
-            % This is ensured by check_foreign_type in
-            % make_hlds.
+            % This is ensured by check_foreign_type in make_hlds.
             unexpected(this_file,
                 "get_maybe_foreign_type_name: no c foreign type")
         )
@@ -1282,17 +1299,23 @@
     % hold the output value.
     %
 :- pred place_pragma_output_args_in_regs(list(c_arg)::in, list(lval)::in,
-    list(pragma_c_output)::out, code_info::in, code_info::out) is det.
+    bool::in, list(pragma_c_output)::out, code_info::in, code_info::out)
+    is det.
 
-place_pragma_output_args_in_regs([], [], [], !CI).
-place_pragma_output_args_in_regs([Arg | Args], [Reg | Regs], Outputs, !CI) :-
-    place_pragma_output_args_in_regs(Args, Regs, OutputsTail, !CI),
-    Arg = c_arg(Var, MaybeName, OrigType, _ArgInfo),
+place_pragma_output_args_in_regs([], [], _, [], !CI).
+place_pragma_output_args_in_regs([Arg | Args], [Reg | Regs],
+        CanOptAwayUnnamedArgs, Outputs, !CI) :-
+    place_pragma_output_args_in_regs(Args, Regs, CanOptAwayUnnamedArgs,
+        OutputsTail, !CI),
+    Arg = c_arg(Var, MaybeArgName, OrigType, _ArgInfo),
     code_info__release_reg(Reg, !CI),
     ( code_info__variable_is_forward_live(!.CI, Var) ->
         code_info__set_var_location(Var, Reg, !CI),
         MaybeForeign = get_maybe_foreign_type_info(!.CI, OrigType),
-        ( var_is_not_singleton(MaybeName, Name) ->
+        MaybeName = var_should_be_passed(CanOptAwayUnnamedArgs, Var,
+            MaybeArgName),
+        (
+            MaybeName = yes(Name),
             code_info__get_module_info(!.CI, ModuleInfo),
             VarType = variable_type(!.CI, Var),
             ( is_dummy_argument_type(ModuleInfo, VarType) ->
@@ -1304,14 +1327,15 @@
                 Name, MaybeForeign),
             Outputs = [PragmaCOutput | OutputsTail]
         ;
+            MaybeName = no,
             Outputs = OutputsTail
         )
     ;
         Outputs = OutputsTail
     ).
-place_pragma_output_args_in_regs([_|_], [], _, !CI) :-
+place_pragma_output_args_in_regs([_ | _], [], _, _, !CI) :-
     unexpected(this_file, "place_pragma_output_args_in_regs: length mismatch").
-place_pragma_output_args_in_regs([], [_|_], _, !CI) :-
+place_pragma_output_args_in_regs([], [_ | _], _, _, !CI) :-
     unexpected(this_file, "place_pragma_output_args_in_regs: length mismatch").
 
 %---------------------------------------------------------------------------%
@@ -1320,13 +1344,15 @@
     % are pairs of rvals and (C) variables which receive the input value.
     %
 :- pred input_descs_from_arg_info(code_info::in, list(c_arg)::in,
-    list(pragma_c_input)::out) is det.
+    bool::in, list(pragma_c_input)::out) is det.
 
-input_descs_from_arg_info(_, [], []).
-input_descs_from_arg_info(CI, [Arg | Args], Inputs) :-
-    input_descs_from_arg_info(CI, Args, InputsTail),
-    Arg = c_arg(Var, MaybeName, OrigType, ArgInfo),
-    ( var_is_not_singleton(MaybeName, Name) ->
+input_descs_from_arg_info(_, [], _, []).
+input_descs_from_arg_info(CI, [Arg | Args], CanOptAwayUnnamedArgs, Inputs) :-
+    input_descs_from_arg_info(CI, Args, CanOptAwayUnnamedArgs, InputsTail),
+    Arg = c_arg(Var, MaybeArgName, OrigType, ArgInfo),
+    MaybeName = var_should_be_passed(CanOptAwayUnnamedArgs, Var, MaybeArgName),
+    (
+        MaybeName = yes(Name),
         VarType = variable_type(CI, Var),
         ArgInfo = arg_info(N, _),
         Reg = reg(r, N),
@@ -1341,6 +1367,7 @@
             MaybeForeign),
         Inputs = [Input | InputsTail]
     ;
+        MaybeName = no,
         Inputs = InputsTail
     ).
 
@@ -1351,13 +1378,15 @@
     % output value.
     %
 :- pred output_descs_from_arg_info(code_info::in, list(c_arg)::in,
-    list(pragma_c_output)::out) is det.
+    bool::in, list(pragma_c_output)::out) is det.
 
-output_descs_from_arg_info(_, [], []).
-output_descs_from_arg_info(CI, [Arg | Args], Outputs) :-
-    output_descs_from_arg_info(CI, Args, OutputsTail),
-    Arg = c_arg(Var, MaybeName, OrigType, ArgInfo),
-    ( var_is_not_singleton(MaybeName, Name) ->
+output_descs_from_arg_info(_, [], _, []).
+output_descs_from_arg_info(CI, [Arg | Args], CanOptAwayUnnamedArgs, Outputs) :-
+    output_descs_from_arg_info(CI, Args, CanOptAwayUnnamedArgs, OutputsTail),
+    Arg = c_arg(Var, MaybeArgName, OrigType, ArgInfo),
+    MaybeName = var_should_be_passed(CanOptAwayUnnamedArgs, Var, MaybeArgName),
+    (
+        MaybeName = yes(Name),
         VarType = variable_type(CI, Var),
         ArgInfo = arg_info(N, _),
         Reg = reg(r, N),
@@ -1372,6 +1401,7 @@
             MaybeForeign),
         Outputs = [Output | OutputsTail]
     ;
+        MaybeName = no,
         Outputs = OutputsTail
     ).
 
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.379
diff -u -b -r1.379 typecheck.m
--- compiler/typecheck.m	11 Oct 2005 03:17:23 -0000	1.379
+++ compiler/typecheck.m	11 Oct 2005 03:18:02 -0000
@@ -459,8 +459,8 @@
                 Constraints, Status, Markers, !:Info),
             typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
             get_clause_list(ClausesRep1, Clauses1),
-            typecheck_clause_list(HeadVars, ArgTypes0,
-                Clauses1, Clauses, !Info, !IO),
+            typecheck_clause_list(HeadVars, ArgTypes0, Clauses1, Clauses,
+                !Info, !IO),
             % we need to perform a final pass of context reduction
             % at the end, before checking the typeclass constraints
             perform_context_reduction(OrigTypeAssignSet, !Info, !IO),
@@ -559,6 +559,10 @@
                     Origin1 = Origin0
                 ;
                     ExistQVars0 = [_ | _],
+                    list__foldl(
+                        check_existq_clause(!.Info, TypeVarSet, ExistQVars0),
+                        Clauses, !IO),
+
                     apply_var_renaming_to_var_list(ExistQVars0,
                         ExistTypeRenaming, ExistQVars1),
                     apply_variable_renaming_to_type_list(ExistTypeRenaming,
@@ -595,6 +599,30 @@
 
 ignore(_).
 
+:- pred check_existq_clause(typecheck_info::in, tvarset::in, existq_tvars::in,
+    clause::in, io::di, io::uo) is det.
+
+check_existq_clause(Info, TypeVarSet, ExistQVars, Clause, !IO) :-
+    Goal = Clause ^ clause_body,
+    ( Goal = foreign_proc(_, _, _, _, _, Impl) - _ ->
+        list__foldl(check_mention_existq_var(Info, TypeVarSet, Impl),
+            ExistQVars, !IO)
+    ;
+        true
+    ).
+
+:- pred check_mention_existq_var(typecheck_info::in, tvarset::in,
+    pragma_foreign_code_impl::in, tvar::in, io::di, io::uo) is det.
+
+check_mention_existq_var(Info, TypeVarSet, Impl, TVar, !IO) :-
+    varset__lookup_name(TypeVarSet, TVar, Name),
+    VarName = "TypeInfo_for_" ++ Name,
+    ( foreign_code_uses_variable(Impl, VarName) ->
+        true
+    ;
+        report_missing_tvar_in_foreign_code(Info, VarName, !IO)
+    ).
+
     % Mark the predicate as a stub, and generate a clause of the form
     %   <p>(...) :-
     %       PredName = "<Predname>",
@@ -1151,7 +1179,8 @@
         % previous type assignment set (so that it can detect other errors
         % in the same clause).
         TypeAssignSet = [],
-        error("internal error in typechecker: no type-assignment")
+        unexpected(this_file,
+            "internal error in typechecker: no type-assignment")
     ;
         TypeAssignSet = [_SingleTypeAssign]
     ;
Index: compiler/typecheck_errors.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck_errors.m,v
retrieving revision 1.6
diff -u -b -r1.6 typecheck_errors.m
--- compiler/typecheck_errors.m	30 Sep 2005 08:08:37 -0000	1.6
+++ compiler/typecheck_errors.m	12 Oct 2005 01:02:49 -0000
@@ -77,6 +77,9 @@
 :- pred report_unsatisfiable_constraints(type_assign_set::in,
 	typecheck_info::in, typecheck_info::out, io::di, io::uo) is det.
 
+:- pred report_missing_tvar_in_foreign_code(typecheck_info::in, string::in,
+	io::di, io::uo) is det.
+
 %-----------------------------------------------------------------------------%
 
 	% Write out the inferred `pred' or `func' declarations
@@ -1236,6 +1239,20 @@
 	io__write_list(UnprovenProgConstraints, "', `",
 		mercury_output_constraint(VarSet, AppendVarnums), !IO),
 	io__write_string("'.\n", !IO).
+
+%-----------------------------------------------------------------------------%
+
+report_missing_tvar_in_foreign_code(Info, VarName, !IO) :-
+	typecheck_info_get_module_info(Info, ModuleInfo),
+	typecheck_info_get_context(Info, Context),
+	typecheck_info_get_predid(Info, PredId),
+	Pieces = [words("The foreign language code for") |
+		describe_one_pred_name(ModuleInfo, should_module_qualify,
+			PredId)] ++
+		[words("should define the variable"),
+		fixed(add_quotes(VarName)), suffix(".")],
+	write_error_pieces(Context, 0, Pieces, !IO),
+	io__set_exit_status(1, !IO).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.109
diff -u -b -r1.109 unused_args.m
--- compiler/unused_args.m	10 Oct 2005 07:54:37 -0000	1.109
+++ compiler/unused_args.m	10 Oct 2005 13:33:19 -0000
@@ -107,6 +107,7 @@
 :- import_module std_util.
 :- import_module string.
 :- import_module svmap.
+:- import_module varset.
 
     % Information about the dependencies of a variable
     % that is not known to be used.
@@ -428,7 +429,7 @@
                 TypeInfoLiveness = no
             ),
 
-            proc_info_goal(ProcInfo, Goal - _),
+            proc_info_goal(ProcInfo, Goal),
             Info = traverse_info(!.ModuleInfo, VarTypes),
             traverse_goal(Info, Goal, !VarDep),
             svmap__set(proc(PredId, ProcId), !.VarDep, !VarUsage),
@@ -451,7 +452,7 @@
 %
 % Predicates for manipulating the var_usage and var_dep structures.
 
-    % For each variable ensure the typeinfos describing the type parameters
+    % For each variable, ensure the typeinfos describing the type parameters
     % of the type of the variable depend on the head variable. For example,
     % if HeadVar1 has type list(T), then TypeInfo_for_T is used if HeadVar1
     % is used.
@@ -462,6 +463,13 @@
 setup_typeinfo_deps([], _, _, _, !VarDep).
 setup_typeinfo_deps([Var | Vars], VarTypeMap, PredProcId, RttiVarMaps,
         !VarDep) :-
+    setup_typeinfo_dep(Var, VarTypeMap, PredProcId, RttiVarMaps, !VarDep),
+    setup_typeinfo_deps(Vars, VarTypeMap, PredProcId, RttiVarMaps, !VarDep).
+
+:- pred setup_typeinfo_dep(prog_var::in, map(prog_var, type)::in,
+    pred_proc_id::in, rtti_varmaps::in, var_dep::in, var_dep::out) is det.
+
+setup_typeinfo_dep(Var, VarTypeMap, PredProcId, RttiVarMaps, !VarDep) :-
     map__lookup(VarTypeMap, Var, Type),
     prog_type__vars(Type, TVars),
     list__map((pred(TVar::in, TypeInfoVar::out) is det :-
@@ -472,8 +480,7 @@
         (pred(TVar::in, VarDepA::in, VarDepB::out) is det :-
             add_arg_dep(TVar, PredProcId, Var, VarDepA, VarDepB)
         ),
-    list__foldl(AddArgDependency, TypeInfoVars, !VarDep),
-    setup_typeinfo_deps(Vars, VarTypeMap, PredProcId, RttiVarMaps, !VarDep).
+    list__foldl(AddArgDependency, TypeInfoVars, !VarDep).
 
     % Get output arguments for a procedure given the headvars and the
     % argument modes, and set them as used.
@@ -544,108 +551,118 @@
                 vartypes    :: vartypes
             ).
 
-:- pred traverse_goal(traverse_info::in, hlds_goal_expr::in,
+:- pred traverse_goal(traverse_info::in, hlds_goal::in,
     var_dep::in, var_dep::out) is det.
 
-traverse_goal(Info, conj(Goals), !VarDep) :-
-    traverse_list_of_goals(Info, Goals, !VarDep).
-
-traverse_goal(Info, par_conj(Goals), !VarDep) :-
-    traverse_list_of_goals(Info, Goals, !VarDep).
-
-traverse_goal(Info, disj(Goals), !VarDep) :-
-    traverse_list_of_goals(Info, Goals, !VarDep).
-
-traverse_goal(Info, switch(Var, _, Cases), !VarDep) :-
+traverse_goal(Info, Goal, !VarDep) :-
+    Goal = GoalExpr - _GoalInfo,
+    (
+        GoalExpr = conj(Goals),
+        traverse_list_of_goals(Info, Goals, !VarDep)
+    ;
+        GoalExpr = par_conj(Goals),
+        traverse_list_of_goals(Info, Goals, !VarDep)
+    ;
+        GoalExpr = disj(Goals),
+        traverse_list_of_goals(Info, Goals, !VarDep)
+    ;
+        GoalExpr = switch(Var, _, Cases),
     set_var_used(Var, !VarDep),
     list_case_to_list_goal(Cases, Goals),
-    traverse_list_of_goals(Info, Goals, !VarDep).
-
-traverse_goal(Info, call(PredId, ProcId, Args, _, _, _), !VarDep) :-
-    module_info_pred_proc_info(Info^module_info, PredId, ProcId, _Pred, Proc),
+        traverse_list_of_goals(Info, Goals, !VarDep)
+    ;
+        GoalExpr = call(PredId, ProcId, Args, _, _, _),
+        module_info_pred_proc_info(Info ^ module_info, PredId, ProcId,
+            _Pred, Proc),
     proc_info_headvars(Proc, HeadVars),
-    add_pred_call_arg_dep(proc(PredId, ProcId), Args, HeadVars, !VarDep).
-
-traverse_goal(Info, if_then_else(_, Cond - _, Then - _, Else - _), !VarDep) :-
+        add_pred_call_arg_dep(proc(PredId, ProcId), Args, HeadVars, !VarDep)
+    ;
+        GoalExpr = if_then_else(_, Cond, Then, Else),
     traverse_goal(Info, Cond, !VarDep),
     traverse_goal(Info, Then, !VarDep),
-    traverse_goal(Info, Else, !VarDep).
-
-traverse_goal(Info, not(Goal - _), !VarDep) :-
-    traverse_goal(Info, Goal, !VarDep).
-
-traverse_goal(Info, scope(_, Goal - _), !VarDep) :-
-    traverse_goal(Info, Goal, !VarDep).
-
-traverse_goal(_, generic_call(GenericCall, Args, _, _), !VarDep) :-
+        traverse_goal(Info, Else, !VarDep)
+    ;
+        GoalExpr = not(SubGoal),
+        traverse_goal(Info, SubGoal, !VarDep)
+    ;
+        GoalExpr = scope(_, SubGoal),
+        traverse_goal(Info, SubGoal, !VarDep)
+    ;
+        GoalExpr = generic_call(GenericCall, Args, _, _),
     goal_util__generic_call_vars(GenericCall, CallArgs),
     set_list_vars_used(CallArgs, !VarDep),
-    set_list_vars_used(Args, !VarDep).
-
-traverse_goal(_, foreign_proc(_, _, _, Args, ExtraArgs, _), !VarDep) :-
-    % Only those arguments which have names can be used in the foreign code.
+        set_list_vars_used(Args, !VarDep)
+    ;
+        GoalExpr = foreign_proc(_, _, _, Args, ExtraArgs, _),
+        % Only arguments with names can be used in the foreign code.
+        % The code in here should be kept in sync with the treatment of
+        % foreign_procs in fixup_goal_expr: any variable considered unused here
+        % should be renamed apart in fixup_goal_expr.
     ArgIsUsed = (pred(Arg::in, Var::out) is semidet :-
         Arg = foreign_arg(Var, MaybeNameAndMode, _),
         MaybeNameAndMode = yes(_)
     ),
     list__filter_map(ArgIsUsed, Args ++ ExtraArgs, UsedVars),
-    set_list_vars_used(UsedVars, !VarDep).
-
-traverse_goal(_, unify(_, _, _, simple_test(Var1, Var2),_), !VarDep) :-
+        set_list_vars_used(UsedVars, !VarDep)
+    ;
+        GoalExpr = unify(LHS, RHS, _, Unify, _),
+        (
+            Unify = simple_test(Var1, Var2),
     set_var_used(Var1, !VarDep),
-    set_var_used(Var2, !VarDep).
-
-traverse_goal(_, unify(_, _, _, assign(Var1, Var2), _), !VarDep) :-
-    ( local_var_is_used(!.VarDep, Var1) ->
-        % If Var1 is used to instantiate an output argument, Var2 is used.
         set_var_used(Var2, !VarDep)
     ;
-        add_aliases(Var2, [Var1], !VarDep)
-    ).
-
-traverse_goal(Info,
-        unify(Var1, _, _, deconstruct(_, _, Args, Modes, CanFail, _), _),
-        !VarDep) :-
-    partition_deconstruct_args(Info, Args, Modes, InputVars, OutputVars),
-    % The deconstructed variable is used if any of the variables that the
-    % deconstruction binds are used.
-    add_aliases(Var1, OutputVars, !VarDep),
+            Unify = assign(Target, Source),
+            ( local_var_is_used(!.VarDep, Target) ->
+                % If Target is used to instantiate an output argument,
+                % Source is used.
+                set_var_used(Source, !VarDep)
+            ;
+                add_aliases(Source, [Target], !VarDep)
+            )
+        ;
+            Unify = deconstruct(CellVar, _, Args, Modes, CanFail, _),
+            require(unify(CellVar, LHS), "traverse_goal: LHS != CellVar"),
+            partition_deconstruct_args(Info, Args, Modes,
+                InputVars, OutputVars),
+            % The deconstructed variable is used if any of the variables that
+            % the deconstruction binds are used.
+            add_aliases(CellVar, OutputVars, !VarDep),
     % Treat a deconstruction that further instantiates its left arg
     % as a partial construction.
-    add_construction_aliases(Var1, InputVars, !VarDep),
+            add_construction_aliases(CellVar, InputVars, !VarDep),
     (
         CanFail = can_fail,
         % A deconstruction that can_fail uses its left arg.
-        set_var_used(Var1, !VarDep)
+                set_var_used(CellVar, !VarDep)
     ;
         CanFail = cannot_fail
-    ).
-
-traverse_goal(_, unify(Var1, _, _, construct(_, _, Args, _, _, _, _), _),
-        !VarDep) :-
-    ( local_var_is_used(!.VarDep, Var1) ->
+            )
+        ;
+            Unify = construct(CellVar, _, Args, _, _, _, _),
+            require(unify(CellVar, LHS), "traverse_goal: LHS != CellVar"),
+            ( local_var_is_used(!.VarDep, CellVar) ->
         set_list_vars_used(Args, !VarDep)
     ;
-        add_construction_aliases(Var1, Args, !VarDep)
-    ).
-
+                add_construction_aliases(CellVar, Args, !VarDep)
+            )
+        ;
+            Unify = complicated_unify(_, _, _),
     % These should be transformed into calls by polymorphism.m.
-traverse_goal(_, unify(Var, Rhs, _, complicated_unify(_, _, _), _),
-        !VarDep) :-
     % This is here to cover the case where unused arguments is called
     % with --error-check-only and polymorphism has not been run.
-    % Complicated unifications should only be var-var.
-    ( Rhs = var(RhsVar) ->
-        set_var_used(RhsVar, !VarDep),
-        set_var_used(Var, !VarDep)
+            ( RHS = var(RHSVar) ->
+                set_var_used(RHSVar, !VarDep),
+                set_var_used(LHS, !VarDep)
     ;
         unexpected(this_file,
             "complicated unifications should only be var-var")
-    ).
-
-traverse_goal(_, shorthand(_), _, _) :-
+            )
+        )
+    ;
+        GoalExpr = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "traverse_goal: unexpected shorthand").
+        unexpected(this_file, "traverse_goal: unexpected shorthand")
+    ).
 
     % Add PredProc - HeadVar as an alias for the same element of Args.
     %
@@ -695,13 +712,13 @@
         partition_deconstruct_args(Info, Vars, Modes, InputVars1, OutputVars1),
         Mode = ((InitialInst1 - InitialInst2) -> (FinalInst1 - FinalInst2)),
 
-        map__lookup(Info^vartypes, Var, Type),
+        map__lookup(Info ^ vartypes, Var, Type),
 
         % If the inst of the argument of the LHS is changed,
         % the argument is input.
         (
             inst_matches_binding(InitialInst1, FinalInst1,
-                Type, Info^module_info)
+                Type, Info ^ module_info)
         ->
             InputVars = InputVars1
         ;
@@ -755,7 +772,7 @@
     var_dep::in, var_dep::out) is det.
 
 traverse_list_of_goals(_, [], !VarDep).
-traverse_list_of_goals(Info, [Goal - _ | Goals], !VarDep) :-
+traverse_list_of_goals(Info, [Goal | Goals], !VarDep) :-
     traverse_goal(Info, Goal, !VarDep),
     traverse_list_of_goals(Info, Goals, !VarDep).
 
@@ -1118,15 +1135,15 @@
     map__from_corresponding_lists(HeadVars, VarTypeList, VarTypes1),
     % The varset should probably be fixed up, but it shouldn't make
     % too much difference.
-    proc_info_varset(!.OldProc, Varset0),
+    proc_info_varset(!.OldProc, VarSet0),
     remove_listof_elements(1, UnusedArgs, HeadVars, NewHeadVars),
     GoalExpr = call(NewPredId, NewProcId, NewHeadVars,
         not_builtin, no, qualified(PredModule, PredName)),
     Goal1 = GoalExpr - GoalInfo1,
-    implicitly_quantify_goal(NonLocals, _, Goal1, Goal, Varset0, Varset,
+    implicitly_quantify_goal(NonLocals, _, Goal1, Goal, VarSet0, VarSet,
         VarTypes1, VarTypes),
     proc_info_set_goal(Goal, !OldProc),
-    proc_info_set_varset(Varset, !OldProc),
+    proc_info_set_varset(VarSet, !OldProc),
     proc_info_set_vartypes(VarTypes, !OldProc).
 
     % Create a pred_info for an imported pred with a pragma unused_args
@@ -1207,9 +1224,23 @@
     proc_call_info::in, module_info::in, module_info::out, bool::in,
     io::di, io::uo) is det.
 
-fixup_unused_args(_, [], _, !ModuleInfo, _, !IO).
-fixup_unused_args(VarUsage, [PredProc | PredProcs], ProcCallInfo, !ModuleInfo,
-        VeryVerbose, !IO) :-
+fixup_unused_args(VarUsage, PredProcs, ProcCallInfo, !ModuleInfo, VeryVerbose,
+        !IO) :-
+    map__keys(VarUsage, VarUsageKeys),
+    list__sort(PredProcs, SortedPredProcs),
+    require(unify(VarUsageKeys, SortedPredProcs),
+        "fixup_unused_args: VarUsageKeys != SortedPredProcs"),
+    list__foldl2(fixup_unused_args_proc(VeryVerbose, VarUsage, ProcCallInfo),
+        PredProcs, !ModuleInfo, !IO).
+
+    % Note - we should probably remove unused variables from the type map.
+    %
+:- pred fixup_unused_args_proc(bool::in, var_usage::in, proc_call_info::in,
+    pred_proc_id::in, module_info::in, module_info::out, io::di, io::uo)
+    is det.
+
+fixup_unused_args_proc(VeryVerbose, VarUsage, ProcCallInfo, PredProc,
+        !ModuleInfo, !IO) :-
     (
         VeryVerbose = yes,
         PredProc = proc(PredId, ProcId),
@@ -1226,9 +1257,7 @@
     ;
         VeryVerbose = no
     ),
-    do_fixup_unused_args(VarUsage, PredProc, ProcCallInfo, !ModuleInfo),
-    fixup_unused_args(VarUsage, PredProcs, ProcCallInfo, !ModuleInfo,
-        VeryVerbose, !IO).
+    do_fixup_unused_args(VarUsage, PredProc, ProcCallInfo, !ModuleInfo).
 
 :- pred do_fixup_unused_args(var_usage::in, pred_proc_id::in,
     proc_call_info::in, module_info::in, module_info::out) is det.
@@ -1258,7 +1287,7 @@
 
     proc_info_headvars(ProcInfo0, HeadVars0),
     proc_info_argmodes(ProcInfo0, ArgModes0),
-    proc_info_varset(ProcInfo0, Varset0),
+    proc_info_varset(ProcInfo0, VarSet0),
     proc_info_goal(ProcInfo0, Goal0),
     remove_listof_elements(1, UnusedArgs, HeadVars0, HeadVars),
     remove_listof_elements(1, UnusedArgs, ArgModes0, ArgModes),
@@ -1271,20 +1300,21 @@
         proc_info_set_argmodes(ArgModes, !ProcInfo),
 
         % Remove unused vars from goal.
-        fixup_goal(ModuleInfo0, UnusedVars, ProcCallInfo, Changed, !Goal),
+        FixupInfo0 = fixup_info(ModuleInfo0, ProcCallInfo, UnusedVars,
+            VarSet0, VarTypes0),
+        fixup_goal(!Goal, FixupInfo0, FixupInfo, Changed),
+        FixupInfo = fixup_info(_, _, _, VarSet1, VarTypes1),
         (
             Changed = yes,
             % If anything has changed, rerun quantification.
             set__list_to_set(HeadVars, NonLocals),
             implicitly_quantify_goal(NonLocals, _, !Goal,
-                Varset0, Varset, VarTypes0, VarTypes),
+                VarSet1, VarSet, VarTypes1, VarTypes),
             proc_info_set_goal(!.Goal, !ProcInfo),
-            proc_info_set_varset(Varset, !ProcInfo),
+            proc_info_set_varset(VarSet, !ProcInfo),
             proc_info_set_vartypes(VarTypes, !ProcInfo)
         ;
-            Changed = no,
-            % XXX The next call seems redundant.
-            proc_info_set_vartypes(VarTypes0, !ProcInfo)
+            Changed = no
         ),
         ProcInfo = !.ProcInfo
     ),
@@ -1294,121 +1324,164 @@
     map__set(Preds0, PredId, PredInfo, Preds),
     module_info_set_preds(Preds, ModuleInfo0, ModuleInfo).
 
+:- type fixup_info
+    --->    fixup_info(
+                fixup_module_info       :: module_info,
+                fixup_proc_call_info    :: proc_call_info,
+                fixup_unused_vars       :: list(prog_var),
+                fixup_varset            :: prog_varset,
+                fixup_vartypes          :: vartypes
+            ).
+
     % This is the important bit of the transformation.
     %
-:- pred fixup_goal(module_info::in, list(prog_var)::in, proc_call_info::in,
-    bool::out, hlds_goal::in, hlds_goal::out) is det.
+:- pred fixup_goal(hlds_goal::in, hlds_goal::out,
+    fixup_info::in, fixup_info::out, bool::out) is det.
 
-fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, Changed, Goal0, Goal) :-
-    fixup_goal_expr(ModuleInfo, UnusedVars, ProcCallInfo, Changed,
-        Goal0, Goal1),
-    Goal1 = GoalExpr - GoalInfo0,
+fixup_goal(Goal0, Goal, !Info, Changed) :-
+    fixup_goal_expr(Goal0, Goal1, !Info, Changed),
+    Goal1 = GoalExpr1 - GoalInfo1,
     (
         Changed = yes,
-        fixup_goal_info(UnusedVars, GoalInfo0, GoalInfo)
+        UnusedVars = !.Info ^ fixup_unused_vars,
+        fixup_goal_info(UnusedVars, GoalInfo1, GoalInfo)
     ;
         Changed = no,
-        GoalInfo = GoalInfo0
+        GoalInfo = GoalInfo1
     ),
-    Goal = GoalExpr - GoalInfo.
+    Goal = GoalExpr1 - GoalInfo.
 
-:- pred fixup_goal_expr(module_info::in, list(prog_var)::in,
-    proc_call_info::in, bool::out, hlds_goal::in, hlds_goal::out) is det.
+:- pred fixup_goal_expr(hlds_goal::in, hlds_goal::out,
+    fixup_info::in, fixup_info::out, bool::out) is det.
 
-fixup_goal_expr(ModuleInfo, UnusedVars, ProcCallInfo, Changed,
-        GoalExpr0 - GoalInfo, GoalExpr - GoalInfo) :-
+fixup_goal_expr(GoalExpr0 - GoalInfo0, Goal, !Info, Changed) :-
     (
         GoalExpr0 = conj(Goals0),
-        fixup_conjuncts(ModuleInfo, UnusedVars, ProcCallInfo, no, Changed,
-            Goals0, Goals),
-        GoalExpr = conj(Goals)
+        fixup_conjuncts(Goals0, Goals, !Info, no, Changed),
+        GoalExpr = conj(Goals),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = par_conj(Goals0),
-        fixup_conjuncts(ModuleInfo, UnusedVars, ProcCallInfo, no, Changed,
-            Goals0, Goals),
-        GoalExpr = par_conj(Goals)
+        fixup_conjuncts(Goals0, Goals, !Info, no, Changed),
+        GoalExpr = par_conj(Goals),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = disj(Goals0),
-        fixup_disjuncts(ModuleInfo, UnusedVars, ProcCallInfo, no, Changed,
-            Goals0, Goals),
-        GoalExpr = disj(Goals)
+        fixup_disjuncts(Goals0, Goals, !Info, no, Changed),
+        GoalExpr = disj(Goals),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = not(NegGoal0),
-        fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, Changed,
-            NegGoal0, NegGoal),
-        GoalExpr = not(NegGoal)
+        fixup_goal(NegGoal0, NegGoal, !Info, Changed),
+        GoalExpr = not(NegGoal),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = switch(Var, CanFail, Cases0),
-        fixup_cases(ModuleInfo, UnusedVars, ProcCallInfo, no, Changed,
-            Cases0, Cases),
-        GoalExpr = switch(Var, CanFail, Cases)
+        fixup_cases(Cases0, Cases, !Info, no, Changed),
+        GoalExpr = switch(Var, CanFail, Cases),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
-        fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, Changed1,
-            Cond0, Cond),
-        fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, Changed2,
-            Then0, Then),
-        fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, Changed3,
-            Else0, Else),
+        fixup_goal(Cond0, Cond, !Info, Changed1),
+        fixup_goal(Then0, Then, !Info, Changed2),
+        fixup_goal(Else0, Else, !Info, Changed3),
         bool__or_list([Changed1, Changed2, Changed3], Changed),
-        GoalExpr = if_then_else(Vars, Cond, Then, Else)
+        GoalExpr = if_then_else(Vars, Cond, Then, Else),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = scope(Reason, SubGoal0),
-        fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, Changed,
-            SubGoal0, SubGoal),
-        GoalExpr = scope(Reason, SubGoal)
-    ;
-        GoalExpr0 = call(PredId0, ProcId0, ArgVars0, B, C, Name0),
-        (
-            map__search(ProcCallInfo, proc(PredId0, ProcId0),
-                call_info(NewPredId, NewProcId, NewName, UnusedArgs))
-        ->
+        fixup_goal(SubGoal0, SubGoal, !Info, Changed),
+        GoalExpr = scope(Reason, SubGoal),
+        Goal = GoalExpr - GoalInfo0
+    ;
+        GoalExpr0 = call(PredId, ProcId, ArgVars0, Builtin, UnifyC, _Name),
+        ProcCallInfo = !.Info ^ fixup_proc_call_info,
+        ( map__search(ProcCallInfo, proc(PredId, ProcId), CallInfo) ->
+            CallInfo = call_info(NewPredId, NewProcId, NewName, UnusedArgs),
             Changed = yes,
             remove_listof_elements(1, UnusedArgs, ArgVars0, ArgVars),
-            PredId = NewPredId,
-            ProcId = NewProcId,
-            Name = NewName
+            GoalExpr = call(NewPredId, NewProcId, ArgVars, Builtin, UnifyC,
+                NewName),
+            Goal = GoalExpr - GoalInfo0
         ;
             Changed = no,
-            PredId = PredId0,
-            ProcId = ProcId0,
-            ArgVars = ArgVars0,
-            Name = Name0
-        ),
-        GoalExpr = call(PredId, ProcId, ArgVars, B, C, Name)
+            Goal = GoalExpr0 - GoalInfo0
+        )
     ;
         GoalExpr0 = unify(_Var, _RHS, _Mode, Unify, _Context),
+        ModuleInfo = !.Info ^ fixup_module_info,
+        UnusedVars = !.Info ^ fixup_unused_vars,
         ( need_unify(ModuleInfo, UnusedVars, Unify, ChangedPrime) ->
             GoalExpr = GoalExpr0,
             Changed = ChangedPrime
         ;
             GoalExpr = conj([]),
             Changed = yes
-        )
+        ),
+        Goal = GoalExpr - GoalInfo0
     ;
         GoalExpr0 = generic_call(_, _, _, _),
-        GoalExpr = GoalExpr0,
+        Goal = GoalExpr0 - GoalInfo0,
         Changed = no
     ;
-        GoalExpr0 = foreign_proc(_, _, _, _, _, _),
-        GoalExpr = GoalExpr0,
-        Changed = no
+        GoalExpr0 = foreign_proc(Attributes, PredId, ProcId, Args0, ExtraArgs0,
+            Impl),
+        % The code in here should be kept in sync with the treatment of
+        % foreign_procs in traverse_goal.
+        Changed0 = no,
+        map__init(Subst0),
+        list__map_foldl3(rename_apart_unused_foreign_arg,
+            Args0, Args, Subst0, Subst1, !Info, Changed0, ArgsChanged),
+        list__map_foldl3(rename_apart_unused_foreign_arg,
+            ExtraArgs0, ExtraArgs, Subst1, Subst, !Info, ArgsChanged, Changed),
+        GoalExpr = foreign_proc(Attributes, PredId, ProcId, Args, ExtraArgs,
+            Impl),
+        rename_vars_in_goal_info(no, Subst, GoalInfo0, GoalInfo),
+        Goal = GoalExpr - GoalInfo
     ;
         GoalExpr0 = shorthand(_),
         % These should have been expanded out by now.
         unexpected(this_file, "fixup_goal_expr: shorthand")
     ).
 
+:- pred rename_apart_unused_foreign_arg(foreign_arg::in, foreign_arg::out,
+    map(prog_var, prog_var)::in, map(prog_var, prog_var)::out,
+    fixup_info::in, fixup_info::out, bool::in, bool::out) is det.
+
+rename_apart_unused_foreign_arg(Arg0, Arg, !Subst, !Info, !Changed) :-
+    Arg0 = foreign_arg(OldVar, MaybeName, OrigType),
+    (
+        MaybeName = yes(_),
+        Arg = Arg0
+    ;
+        MaybeName = no,
+        VarSet0 = !.Info ^ fixup_varset,
+        VarTypes0 = !.Info ^ fixup_vartypes,
+        ( varset__search_name(VarSet0, OldVar, Name) ->
+            varset__new_named_var(VarSet0, Name, NewVar, VarSet)
+        ;
+            varset__new_var(VarSet0, NewVar, VarSet)
+        ),
+        map__lookup(VarTypes0, OldVar, Type),
+        map__det_insert(VarTypes0, NewVar, Type, VarTypes),
+        !:Info = !.Info ^ fixup_varset := VarSet,
+        !:Info = !.Info ^ fixup_vartypes := VarTypes,
+
+        % It is possible for an unnamed input argument to occur more than once
+        % in the list of foreign_args.
+        svmap__set(OldVar, NewVar, !Subst),
+        Arg = foreign_arg(NewVar, MaybeName, OrigType),
+        !:Changed = yes
+    ).
+
     % Remove useless unifications from a list of conjuncts.
     %
-:- pred fixup_conjuncts(module_info::in, list(prog_var)::in, proc_call_info::in,
-    bool::in, bool::out, hlds_goals::in, hlds_goals::out) is det.
+:- pred fixup_conjuncts(hlds_goals::in, hlds_goals::out,
+    fixup_info::in, fixup_info::out, bool::in, bool::out) is det.
 
-fixup_conjuncts(_, _, _, !Changed, [], []).
-fixup_conjuncts(ModuleInfo, UnusedVars, ProcCallInfo, !Changed,
-        [Goal0 | Goals0], Goals) :-
-    fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, LocalChanged,
-        Goal0, Goal),
+fixup_conjuncts([], [], !Info, !Changed).
+fixup_conjuncts([Goal0 | Goals0], Goals, !Info, !Changed) :-
+    fixup_goal(Goal0, Goal, !Info, LocalChanged),
     (
         LocalChanged = yes,
         !:Changed = yes
@@ -1421,45 +1494,39 @@
     ;
         Goals = [Goal | Goals1]
     ),
-    fixup_conjuncts(ModuleInfo, UnusedVars, ProcCallInfo, !Changed,
-        Goals0, Goals1).
+    fixup_conjuncts(Goals0, Goals1, !Info, !Changed).
 
     % We can't remove unused goals from the list of disjuncts as we do
     % for conjuncts, since that would change the determinism of the goal.
     %
-:- pred fixup_disjuncts(module_info::in, list(prog_var)::in, proc_call_info::in,
-    bool::in, bool::out, hlds_goals::in, hlds_goals::out) is det.
+:- pred fixup_disjuncts(hlds_goals::in, hlds_goals::out,
+    fixup_info::in, fixup_info::out, bool::in, bool::out) is det.
 
-fixup_disjuncts(_, _, _, !Changed, [], []).
-fixup_disjuncts(ModuleInfo, UnusedVars, ProcCallInfo, !Changed,
-        [Goal0 | Goals0], [Goal | Goals]) :-
-    fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, LocalChanged,
-        Goal0, Goal),
+fixup_disjuncts([], [], !Info, !Changed).
+fixup_disjuncts([Goal0 | Goals0], [Goal | Goals], !Info, !Changed) :-
+    fixup_goal(Goal0, Goal, !Info, LocalChanged),
     (
         LocalChanged = yes,
         !:Changed = yes
     ;
         LocalChanged = no
     ),
-    fixup_disjuncts(ModuleInfo, UnusedVars, ProcCallInfo, !Changed,
-        Goals0, Goals).
+    fixup_disjuncts(Goals0, Goals, !Info, !Changed).
 
-:- pred fixup_cases(module_info::in, list(prog_var)::in, proc_call_info::in,
-    bool::in, bool::out, list(case)::in, list(case)::out) is det.
+:- pred fixup_cases(list(case)::in, list(case)::out,
+    fixup_info::in, fixup_info::out, bool::in, bool::out) is det.
 
-fixup_cases(_, _, _, !Changed, [], []).
-fixup_cases(ModuleInfo, UnusedVars, ProcCallInfo, !Changed,
-        [case(ConsId, Goal0) | Cases0], [case(ConsId, Goal) | Cases]) :-
-    fixup_goal(ModuleInfo, UnusedVars, ProcCallInfo, LocalChanged,
-        Goal0, Goal),
+fixup_cases([], [], !Info, !Changed).
+fixup_cases([case(ConsId, Goal0) | Cases0], [case(ConsId, Goal) | Cases],
+        !Info, !Changed) :-
+    fixup_goal(Goal0, Goal, !Info, LocalChanged),
     (
         LocalChanged = yes,
         !:Changed = yes
     ;
         LocalChanged = no
     ),
-    fixup_cases(ModuleInfo, UnusedVars, ProcCallInfo, !Changed,
-        Cases0, Cases).
+    fixup_cases(Cases0, Cases, !Info, !Changed).
 
     % Fail if the unification is no longer needed.
     %
@@ -1596,7 +1663,6 @@
             % when trying to read them back in from the `.opt' files. 
             \+ check_marker(Markers, class_instance_method),
             \+ check_marker(Markers, named_class_instance_method)   
-
         ->
             write_unused_args_to_opt_file(WriteOptPragmas,
                 PredInfo, ProcId, UnusedArgs, !IO),
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
Index: deep_profiler/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/Mercury.options,v
retrieving revision 1.5
diff -u -b -r1.5 Mercury.options
--- deep_profiler/Mercury.options	9 Oct 2005 06:36:18 -0000	1.5
+++ deep_profiler/Mercury.options	10 Oct 2005 08:48:54 -0000
@@ -22,22 +22,19 @@
 #
 # XXX These flags should be deleted when the problem is fixed.
 
-
-# We are temporarily compiling all these modules at -O0
-# because of a bug in rotd-2005-10-05 and later.  The bug
-# triggers an assertion failure in the ll code generator
-# when compiling with -O5 --intermodule-optimization --opt-space.
-# This workaround can be removed when the bug is fixed.
-MCFLAGS-array_util =	--no-optimize-duplicate-calls -O0
-MCFLAGS-callgraph = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-canonical =	--no-optimize-duplicate-calls -O0
+MCFLAGS-array_util =	--no-optimize-duplicate-calls
+MCFLAGS-callgraph = 	--no-optimize-duplicate-calls
+MCFLAGS-canonical =	--no-optimize-duplicate-calls
+# Compiling at -O0 is a due to an assertion failure in
+# rotd-2005-10-05.  It can be removed when that is fixed.
+# Also for exclude.m.
 MCFLAGS-cliques = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-dense_bitset = 	--no-optimize-duplicate-calls -O0
+MCFLAGS-dense_bitset = 	--no-optimize-duplicate-calls 
 MCFLAGS-exclude = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-html_format = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-measurements = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-profile = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-query = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-read_profile = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-startup = 	--no-optimize-duplicate-calls -O0
-MCFLAGS-top_procs = 	--no-optimize-duplicate-calls -O0
+MCFLAGS-html_format = 	--no-optimize-duplicate-calls
+MCFLAGS-measurements = 	--no-optimize-duplicate-calls
+MCFLAGS-profile = 	--no-optimize-duplicate-calls
+MCFLAGS-query = 	--no-optimize-duplicate-calls
+MCFLAGS-read_profile = 	--no-optimize-duplicate-calls
+MCFLAGS-startup = 	--no-optimize-duplicate-calls
+MCFLAGS-top_procs = 	--no-optimize-duplicate-calls
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/rtti_implementation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/rtti_implementation.m,v
retrieving revision 1.60
diff -u -b -r1.60 rtti_implementation.m
--- library/rtti_implementation.m	11 Oct 2005 03:17:26 -0000	1.60
+++ library/rtti_implementation.m	11 Oct 2005 03:23:41 -0000
@@ -1608,7 +1608,7 @@
     get_pti_from_arg_types(ArgTypes::in, Index::in) = (ArgTypeInfo::out),
     [will_not_call_mercury, promise_pure],
 "
-    // XXX Should this be something else?
+    // XXX This should be something else.
     TypeInfo_for_T = null;
 
     ArgTypeInfo = ArgTypes[Index];
@@ -1616,7 +1616,11 @@
 
 :- pragma foreign_proc("C#",
     get_pti_from_arg_types(ArgTypes::in, Index::in) = (ArgTypeInfo::out),
-    [promise_pure], "
+    [promise_pure],
+"
+    // XXX This should be something else.
+    // TypeInfo_for_T
+
     ArgTypeInfo = ArgTypes[Index];
 ").
 
@@ -1631,6 +1635,9 @@
     get_pti_from_type_info(TypeInfo::in, Index::in) = (PTI::out),
     [promise_pure],
 "
+    // XXX This should be something else.
+    TypeInfo_for_T = NULL;
+
     PTI = TypeInfo[Index];
 ").
 
@@ -2202,6 +2209,9 @@
     type_ctor_unify_pred(TypeCtorInfo::in) = (UnifyPred::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
+    // XXX This should be something else.
+    // TypeInfo_for_P
+
     UnifyPred = TypeCtorInfo[
         (int) type_ctor_info_field_nums.type_ctor_unify_pred];
 ").
@@ -2209,7 +2219,12 @@
     type_ctor_unify_pred(TypeCtorInfo::in) = (UnifyPred::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    MR_TypeCtorInfo tci = (MR_TypeCtorInfo) TypeCtorInfo;
+    MR_TypeCtorInfo tci;
+
+    /* XXX This should be something else. */
+    TypeInfo_for_P = 0;
+
+    tci = (MR_TypeCtorInfo) TypeCtorInfo;
     UnifyPred = (MR_Integer) tci->MR_type_ctor_unify_pred;
 ").
 type_ctor_unify_pred(_) = "dummy value" :-
@@ -2222,6 +2237,9 @@
     type_ctor_compare_pred(TypeCtorInfo::in) = (UnifyPred::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
+    // XXX This should be something else.
+    TypeInfo_for_P = NULL;
+
     UnifyPred = TypeCtorInfo[
         (int) type_ctor_info_field_nums.type_ctor_compare_pred];
 ").
@@ -2230,7 +2248,12 @@
     type_ctor_compare_pred(TypeCtorInfo::in) = (UnifyPred::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    MR_TypeCtorInfo tci = (MR_TypeCtorInfo) TypeCtorInfo;
+    MR_TypeCtorInfo tci;
+
+    /* XXX This should be something else. */
+    TypeInfo_for_P = 0;
+
+    tci = (MR_TypeCtorInfo) TypeCtorInfo;
     UnifyPred = (MR_Integer) tci->MR_type_ctor_compare_pred;
 ").
 
Index: library/store.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/store.m,v
retrieving revision 1.50
diff -u -b -r1.50 store.m
--- library/store.m	11 Oct 2005 04:45:52 -0000	1.50
+++ library/store.m	11 Oct 2005 23:56:29 -0000
@@ -272,12 +272,24 @@
 
 :- some [S] pred store__do_init(store(S)::uo) is det.
 
-:- pragma foreign_proc("C", store__do_init(_S0::uo),
-    [will_not_call_mercury, promise_pure], "").
-:- pragma foreign_proc("C#", store__do_init(_S0::uo),
-    [will_not_call_mercury, promise_pure], "").
-:- pragma foreign_proc("Java", store__do_init(_S0::uo),
-    [will_not_call_mercury, promise_pure], "").
+:- pragma foreign_proc("C",
+    store__do_init(_S0::uo),
+    [will_not_call_mercury, promise_pure],
+"
+    /* TypeInfo_for_S */
+").
+:- pragma foreign_proc("C#",
+    store__do_init(_S0::uo),
+    [will_not_call_mercury, promise_pure],
+"
+    // TypeInfo_for_S
+").
+:- pragma foreign_proc("Java",
+    store__do_init(_S0::uo),
+    [will_not_call_mercury, promise_pure],
+"
+    // TypeInfo_for_S
+").
 
 % Note -- the syntax for the operations on stores
 % might be nicer if we used some new operators, e.g.
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/existential_type_classes.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/existential_type_classes.exp,v
retrieving revision 1.15
diff -u -b -r1.15 existential_type_classes.exp
--- tests/debugger/existential_type_classes.exp	16 Nov 2004 00:16:39 -0000	1.15
+++ tests/debugger/existential_type_classes.exp	11 Oct 2005 15:19:26 -0000
@@ -137,9 +137,9 @@
        X (arg 1)              	43
        N (arg 2)              	86
 mdb> continue -a
-     E40:    C21 CALL existential_type_classes.m:82 (from existential_type_classes.m:55)
+     E40:    C21 CALL existential_type_classes.m:86 (from existential_type_classes.m:55)
                          func existential_type_classes.my_univ/1-0 (det)
-     E41:    C21 EXIT existential_type_classes.m:82 (from existential_type_classes.m:55)
+     E41:    C21 EXIT existential_type_classes.m:86 (from existential_type_classes.m:55)
                          func existential_type_classes.my_univ/1-0 (det)
      E42:    C22 CALL existential_type_classes.m:76 (from existential_type_classes.m:55)
                          func existential_type_classes.my_univ_value/1-0 (det)
@@ -174,10 +174,10 @@
        X (arg 1)              	45
        N (arg 2)              	90
 mdb> 
-     E52:    C27 CALL existential_type_classes.m:82 (from existential_type_classes.m:56)
+     E52:    C27 CALL existential_type_classes.m:86 (from existential_type_classes.m:56)
                          func existential_type_classes.my_univ/1-0 (det)
 mdb> 
-     E53:    C27 EXIT existential_type_classes.m:82 (from existential_type_classes.m:56)
+     E53:    C27 EXIT existential_type_classes.m:86 (from existential_type_classes.m:56)
                          func existential_type_classes.my_univ/1-0 (det)
 mdb> 
      E54:    C28 CALL existential_type_classes.m:72 (from existential_type_classes.m:56)
Index: tests/debugger/existential_type_classes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/existential_type_classes.m,v
retrieving revision 1.6
diff -u -b -r1.6 existential_type_classes.m
--- tests/debugger/existential_type_classes.m	18 Mar 2001 23:10:15 -0000	1.6
+++ tests/debugger/existential_type_classes.m	11 Oct 2005 15:19:00 -0000
@@ -73,13 +73,20 @@
 
 my_exist_t = 43.
 
-:- pragma c_code(my_univ_value(Univ::in) = (Value::out), will_not_call_mercury, "
+:- pragma c_code(
+	my_univ_value(Univ::in) = (Value::out),
+	[will_not_call_mercury],
+"
+	/* mention TypeInfo_for_T */
 	TypeClassInfo_for_existential_type_classes__fooable_T =
 		MR_field(MR_UNIV_TAG, Univ, 0);
 	Value = MR_field(MR_UNIV_TAG, Univ, 1);
 ").
 
-:- pragma c_code(my_univ(Value::in) = (Univ::out), will_not_call_mercury, "
+:- pragma c_code(
+	my_univ(Value::in) = (Univ::out),
+	[will_not_call_mercury],
+"
 	MR_tag_incr_hp(Univ, MR_UNIV_TAG, 2);
 	MR_field(MR_UNIV_TAG, Univ, 0) =
 		(MR_Word) TypeClassInfo_for_existential_type_classes__fooable_T;
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
Index: tests/warnings/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/warnings/Mmakefile,v
retrieving revision 1.39
diff -u -b -r1.39 Mmakefile
--- tests/warnings/Mmakefile	27 Aug 2005 09:42:10 -0000	1.39
+++ tests/warnings/Mmakefile	10 Oct 2005 15:11:20 -0000
@@ -18,6 +18,7 @@
 	double_underscore \
 	duplicate_call \
 	duplicate_const \
+	exist_foreign_error \
 	inference_test \
 	infinite_recursion \
 	inf_recursion_lambda \
Index: tests/warnings/exist_foreign_error.err
===================================================================
RCS file: tests/warnings/exist_foreign_error.err
diff -N tests/warnings/exist_foreign_error.err
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/warnings/exist_foreign_error.err	11 Oct 2005 21:19:17 -0000
@@ -0,0 +1,3 @@
+exist_foreign_error.m:025: The foreign language code for function
+exist_foreign_error.m:025:   `exist_foreign_error.get_pti_from_arg_types/2'
+exist_foreign_error.m:025:   should define the variable `TypeInfo_for_T'
Index: tests/warnings/exist_foreign_error.m
===================================================================
RCS file: tests/warnings/exist_foreign_error.m
diff -N tests/warnings/exist_foreign_error.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/warnings/exist_foreign_error.m	10 Oct 2005 15:15:06 -0000
@@ -0,0 +1,30 @@
+:- module exist_foreign_error.
+
+:- interface.
+
+    % Get the pseudo-typeinfo at the given index from the argument types.
+    %
+:- some [T] func get_pti_from_arg_types(string, int) = T.
+
+:- implementation.
+
+:- pragma foreign_proc("Java",
+    get_pti_from_arg_types(ArgTypes::in, Index::in) = (ArgTypeInfo::out),
+    [will_not_call_mercury, promise_pure],
+"
+    ArgTypeInfo = ArgTypes[Index];
+").
+
+:- pragma foreign_proc("C#",
+    get_pti_from_arg_types(ArgTypes::in, Index::in) = (ArgTypeInfo::out),
+    [promise_pure],
+"
+    ArgTypeInfo = ArgTypes[Index];
+").
+
+:- pragma foreign_proc("C",
+    get_pti_from_arg_types(ArgTypes::in, Index::in) = (ArgTypeInfo::out),
+    [promise_pure],
+"
+    ArgTypeInfo = ArgTypes[Index];
+").
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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