[m-rev.] for review: exists_casts

Mark Brown mark at cs.mu.OZ.AU
Fri Aug 12 01:50:03 AEST 2005


For review by Zoltan.

Cheers,
Mark.

Estimated hours taken: 15
Branches: main

Introduce a distinction between variables that are typed according to the
external view of a procedure, in which the types may contain an existentially
quantified type variable, and variables that are typed according to the
internal view of a procedure, in which existentially quantified type
variables may be bound to a known type.  The distinction is maintained by
adding "exists_cast" goals which assign an internal variable to its
corresponding external variable.

Any output head variable which is existentially typed and for which the
external view differs from the internal view is replaced by a new variable.
An exists_cast goal is added to the end of the procedure which casts the
old headvar to the new one.  We also do the same for any type_infos and
typeclass_infos that are output.

Exists casts are implemented as a variant on unsafe_cast generic calls.
We also add other variants to distinguish the different kinds of casts:
	- equiv_casts for when the types are the same modulo equivalence
	  types;
	- unsafe_type_casts for when the types are different but the insts
	  are compatible; and
	- unsafe_type_inst_casts for when the type and inst are changed by
	  the cast.

The purpose of this change is to make it possible to include both the
internal and external views in the rtti_varmaps structure.

compiler/polymorphism.m:
	Perform the transformation on proc_infos to include the exists_cast
	goals.  This is done at the end of the polymorphism transformation,
	when we recompute the argument types for the newly transformed
	procedure.  The clauses_infos are left untouched by this
	transformation, since after this stage they should no longer be used.

compiler/hlds_goal.m:
	Modify the generic_call type to include the type of cast.

compiler/hlds_pred.m:
	Modify the generic_call_id type to include the type of cast.

compiler/goal_util.m:
	Add an argument to `generate_unsafe_cast' which specifies the type
	of cast to generate.

compiler/higher_order.m:
	Use the predicate in goal_util to generate the cast, instead of doing
	it manually.

compiler/prog_rep.m:
	All variants of the cast generic call are represented in the same
	way.  This is to avoid to the need to change the format of static
	data in programs compiled with full declarative debugging.  If we
	do need the distinction to be made here, then that can be done as
	a separate change.

compiler/purity.m:
	Calls to private_builtin.unsafe_type_cast are translated into
	unsafe_type_cast generic calls.

compiler/aditi_builtin_ops.m:
	Use unsafe_type_inst_cast when casting between aditi_bottom_up
	closures and their transformed versions.

compiler/common.m:
	Use unsafe_type_cast when generating assignments for variables whose
	types do not match exactly.

compiler/unify_proc.m:
	Use equiv_type_cast when generating casts in unification, comparison
	and initialisation clauses for equivalence types.

	Use unsafe_type_cast when casting enum types to integers for the
	purposes of comparison or unification.

compiler/*.m:
	Handle the new generic_calls.

Index: compiler/aditi_builtin_ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/aditi_builtin_ops.m,v
retrieving revision 1.15
diff -u -r1.15 aditi_builtin_ops.m
--- compiler/aditi_builtin_ops.m	24 Mar 2005 05:33:58 -0000	1.15
+++ compiler/aditi_builtin_ops.m	5 Aug 2005 08:33:49 -0000
@@ -119,7 +119,7 @@
 		{ Call = class_method(_, _, _, _) },
 		{ Goal = Goal0 }
 	;
-		{ Call = unsafe_cast },
+		{ Call = cast(_) },
 		{ Goal = Goal0 }
 	;
 		{ Call = aditi_builtin(Builtin0, _) },
@@ -289,7 +289,7 @@
 				NonCurriedArgModes, CalleeDetism))) },
 	{ CastModes = [(CastInputInst -> CastInputInst),
 			(free_inst -> CastOutputInst)] },
-	{ CastGoal = generic_call(unsafe_cast, [NewVar, Var],
+	{ CastGoal = generic_call(cast(unsafe_type_inst_cast), [NewVar, Var],
 			CastModes, det) - GoalInfo },
 
 	{ Goals = list__condense([ConstArgGoals, TupleGoals,
@@ -419,8 +419,8 @@
 	{ instmap_delta_from_assoc_list([CastClosure - CastOutputInst],
 		InstMapDelta) },
 	{ goal_info_init(NonLocals, InstMapDelta, det, pure, GoalInfo) },
-	{ CastGoal = generic_call(unsafe_cast, [Closure, CastClosure],
-			CastModes, det) - GoalInfo },
+	{ CastGoal = generic_call(cast(unsafe_type_inst_cast),
+		[Closure, CastClosure], CastModes, det) - GoalInfo },
 
 	% Produce the call
 	% aditi_private_builtin__do_bulk_*(RelationName, UpdateProc,
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.163
diff -u -r1.163 call_gen.m
--- compiler/call_gen.m	8 Aug 2005 02:57:09 -0000	1.163
+++ compiler/call_gen.m	10 Aug 2005 02:21:54 -0000
@@ -147,16 +147,16 @@
     % the outputs from the locations that we know the runtime system leaves
     % them in.
 
-    % `unsafe_cast' differs from the other generic call types in
-    % that there is no address. Also, live_vars.m assumes that
-    % unsafe_casts do not require live variables to be saved to the stack.
-    ( GenericCall = unsafe_cast ->
+    % `cast' differs from the other generic call types in that there is no
+    % address. Also, live_vars.m assumes that casts do not require live
+    % variables to be saved to the stack.
+    ( GenericCall = cast(_) ->
         ( Args0 = [InputArg, OutputArg] ->
             call_gen__generate_assign_builtin(OutputArg,
                 leaf(InputArg), Code, !CI)
         ;
             unexpected(this_file,
-                "generate_generic_call: invalid unsafe_cast call")
+                "generate_generic_call: invalid type/inst cast call")
         )
     ;
         call_gen__generate_generic_call_2(OuterCodeModel,
@@ -265,7 +265,7 @@
 call_gen__generic_call_info(_, class_method(TCVar, _, _, _),
         do_call_class_method, [TCVar - arg_info(1, top_in)], 4).
     % Casts are generated inline.
-call_gen__generic_call_info(_, unsafe_cast, do_not_reached, [], 1).
+call_gen__generic_call_info(_, cast(_), do_not_reached, [], 1).
 call_gen__generic_call_info(_, aditi_builtin(_, _), _, _, _) :-
     % These should have been transformed into normal calls.
     error("call_gen__generic_call_info: aditi_builtin").
@@ -304,11 +304,11 @@
         assign(reg(r, 3), const(int_const(NInVars))) -
             "Assign number of immediate input arguments"
     ]).
-call_gen__generic_call_nonvar_setup(unsafe_cast, _, _, _, !CI) :-
-    error("call_gen__generic_call_nonvar_setup: unsafe_cast").
+call_gen__generic_call_nonvar_setup(cast(_), _, _, _, !CI) :-
+    unexpected(this_file, "generic_call_nonvar_setup: cast").
 call_gen__generic_call_nonvar_setup(aditi_builtin(_, _), _, _, _, !CI) :-
     % These should have been transformed into normal calls.
-    error("call_gen__generic_call_info: aditi_builtin").
+    unexpected(this_file, "generic_call_nonvar_setup: aditi_builtin").
 
 %---------------------------------------------------------------------------%
 
Index: compiler/common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/common.m,v
retrieving revision 1.78
diff -u -r1.78 common.m
--- compiler/common.m	18 May 2005 05:49:12 -0000	1.78
+++ compiler/common.m	5 Aug 2005 08:36:02 -0000
@@ -762,7 +762,8 @@
         % since the call to the type cast hides the equivalence of
         % the input and output.
         Modes = [(ToVarInst -> ToVarInst), (free -> ToVarInst)],
-        GoalExpr = generic_call(unsafe_cast, [FromVar, ToVar], Modes, det)
+        GoalExpr = generic_call(cast(unsafe_type_cast), [FromVar, ToVar],
+            Modes, det)
     ),
 
     % `ToVar' may not appear in the original instmap_delta,
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.33
diff -u -r1.33 deep_profiling.m
--- compiler/deep_profiling.m	24 Mar 2005 05:34:00 -0000	1.33
+++ compiler/deep_profiling.m	5 Aug 2005 08:48:58 -0000
@@ -1051,7 +1051,7 @@
 		wrap_call(Path, Goal0 - GoalInfo0, GoalAndInfo, !DeepInfo),
 		AddedImpurity = yes
 	;
-		GenericCall = unsafe_cast,
+		GenericCall = cast(_),
 		GoalAndInfo = Goal0 - GoalInfo0,
 		AddedImpurity = no
 	;
@@ -1205,8 +1205,8 @@
 			]) - PrepareCallGoalInfo,
 			CallSite = method_call(FileName, LineNumber, GoalPath)
 		;
-			Generic = unsafe_cast,
-			error("deep_profiling__wrap_call: unsafe_cast")
+			Generic = cast(_),
+			error("deep_profiling__wrap_call: cast")
 		;
 			Generic = aditi_builtin(_, _),
 			error("deep_profiling__wrap_call: aditi_builtin")
Index: compiler/exception_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exception_analysis.m,v
retrieving revision 1.10
diff -u -r1.10 exception_analysis.m
--- compiler/exception_analysis.m	4 Aug 2005 09:08:40 -0000	1.10
+++ compiler/exception_analysis.m	5 Aug 2005 08:53:21 -0000
@@ -383,7 +383,7 @@
         Details = class_method(_, _, _, _),
         !:Result = !.Result ^ status := may_throw(user_exception)
     ;
-        Details = unsafe_cast
+        Details = cast(_)
     ;
         Details = aditi_builtin(_, _),
         !:Result = !.Result ^ status := may_throw(user_exception)
Index: compiler/follow_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/follow_vars.m,v
retrieving revision 1.71
diff -u -r1.71 follow_vars.m
--- compiler/follow_vars.m	24 Mar 2005 05:34:01 -0000	1.71
+++ compiler/follow_vars.m	5 Aug 2005 08:49:25 -0000
@@ -225,8 +225,8 @@
 		Call @ generic_call(GenericCall, Args, Modes, Det), Call,
 		GoalInfo, GoalInfo, VarTypes, ModuleInfo,
 		!FollowVarsMap, !NextNonReserved) :-
-	% unsafe_casts are generated inline.
-	( GenericCall = unsafe_cast ->
+	% Casts are generated inline.
+	( GenericCall = cast(_) ->
 		true
 	;
 		determinism_to_code_model(Det, CodeModel),
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.108
diff -u -r1.108 goal_util.m
--- compiler/goal_util.m	22 Jul 2005 12:31:54 -0000	1.108
+++ compiler/goal_util.m	9 Aug 2005 08:53:35 -0000
@@ -262,17 +262,16 @@
 	string::in, list(goal_feature)::in, assoc_list(prog_var, inst)::in,
 	module_info::in, term__context::in, hlds_goal::out) is det.
 
-	% Generate an unsafe cast goal.  The input and output insts
-	% are just ground.
+	% Generate a cast goal.  The input and output insts are just ground.
 	%
-:- pred goal_util__generate_unsafe_cast(prog_var::in, prog_var::in,
+:- pred goal_util__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_unsafe_cast(prog_var::in, prog_var::in,
+:- pred goal_util__generate_cast(cast_type::in, prog_var::in, prog_var::in,
 	(inst)::in, (inst)::in, prog_context::in, hlds_goal::out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -633,7 +632,7 @@
 goal_util__rename_generic_call(class_method(Var0, Method, ClassId, MethodId),
 		Must, Subn, class_method(Var, Method, ClassId, MethodId)) :-
 	goal_util__rename_var(Var0, Must, Subn, Var).
-goal_util__rename_generic_call(unsafe_cast, _, _, unsafe_cast).
+goal_util__rename_generic_call(cast(CastType), _, _, cast(CastType)).
 goal_util__rename_generic_call(aditi_builtin(Builtin, PredCallId),
 		_Must, _Subn, aditi_builtin(Builtin, PredCallId)).
 
@@ -812,7 +811,7 @@
 
 goal_util__generic_call_vars(higher_order(Var, _, _, _), [Var]).
 goal_util__generic_call_vars(class_method(Var, _, _, _), [Var]).
-goal_util__generic_call_vars(unsafe_cast, []).
+goal_util__generic_call_vars(cast(_), []).
 goal_util__generic_call_vars(aditi_builtin(_, _), []).
 
 %-----------------------------------------------------------------------------%
@@ -1483,15 +1482,17 @@
 	goal_info_add_features(Features, GoalInfo0, GoalInfo),
 	Goal = GoalExpr - GoalInfo.
 
-generate_unsafe_cast(InArg, OutArg, Context, Goal) :-
-	Ground = ground(shared, none),
-	generate_unsafe_cast(InArg, OutArg, Ground, Ground, Context, Goal).
+goal_util__generate_cast(CastType, InArg, OutArg, Context, Goal) :-
+	Ground = ground_inst,
+	goal_util__generate_cast(CastType, InArg, OutArg, Ground, Ground,
+		Context, Goal).
 
-generate_unsafe_cast(InArg, OutArg, InInst, OutInst, Context, Goal) :-
+goal_util__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),
-	Goal = generic_call(unsafe_cast, [InArg, OutArg],
+	Goal = generic_call(cast(CastType), [InArg, OutArg],
 		[in_mode(InInst), out_mode(OutInst)], det) - GoalInfo.
 
 %-----------------------------------------------------------------------------%
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.129
diff -u -r1.129 higher_order.m
--- compiler/higher_order.m	22 Jul 2005 12:31:54 -0000	1.129
+++ compiler/higher_order.m	5 Aug 2005 11:00:57 -0000
@@ -2249,11 +2249,7 @@
 
 generate_unsafe_type_cast(Context, ToType, Arg, CastArg, Goal, !ProcInfo) :-
 	proc_info_create_var_from_type(ToType, no, CastArg, !ProcInfo),
-	set__list_to_set([Arg, CastArg], NonLocals),
-	instmap_delta_from_assoc_list([CastArg - ground_inst], InstMapDelta),
-	goal_info_init(NonLocals, InstMapDelta, det, pure, Context, GoalInfo),
-	Goal = generic_call(unsafe_cast, [Arg, CastArg],
-		[in_mode, out_mode], det) - GoalInfo.
+	generate_cast(unsafe_type_cast, Arg, CastArg, Context, Goal).
 
 :- pred unwrap_no_tag_arg((type)::in, prog_context::in, sym_name::in,
 	prog_var::in, prog_var::out, hlds_goal::out,
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.132
diff -u -r1.132 hlds_goal.m
--- compiler/hlds_goal.m	17 Jun 2005 10:13:52 -0000	1.132
+++ compiler/hlds_goal.m	5 Aug 2005 08:46:12 -0000
@@ -378,16 +378,38 @@
 			simple_call_id	% name of the called method
 		)
 
-		% unsafe_cast(Input, Output).
+		% cast(Input, Output).
 		% Assigns `Input' to `Output', performing a type
 		% and/or inst cast.
-	;	unsafe_cast
+	;	cast(cast_type)
 
 	;	aditi_builtin(
 			aditi_builtin,
 			simple_call_id
 		).
 
+	% The various kinds of casts that we can do.
+	%
+:- type cast_type
+	--->	unsafe_type_cast
+			% An unsafe type cast between ground values.
+
+	;	unsafe_type_inst_cast
+			% An unsafe type and inst cast.
+
+	;	equiv_type_cast
+			% A safe type cast between equivalent types.
+
+	;	exists_cast.
+			% A safe cast between an internal type_info or
+			% typeclass_info variable, for which the bindings of
+			% existential type variables are known, to an external
+			% type_info or typeclass_info head variable, for which
+			% they are not.  These are used instead of assignments
+			% so that the simplification pass does not attempt to
+			% merge the two variables, which could lead to
+			% inconsistencies in the rtti_varmaps.
+
 	% Get a description of a generic_call goal.
 	%
 :- pred hlds_goal__generic_call_id(generic_call::in, call_id::out) is det.
@@ -1369,14 +1391,14 @@
 hlds_goal__generic_call_id(
 		class_method(_, _, ClassId, MethodId),
 		generic_call(class_method(ClassId, MethodId))).
-hlds_goal__generic_call_id(unsafe_cast, generic_call(unsafe_cast)).
+hlds_goal__generic_call_id(cast(CastType), generic_call(cast(CastType))).
 hlds_goal__generic_call_id(aditi_builtin(Builtin, Name),
 		generic_call(aditi_builtin(Builtin, Name))).
 
 generic_call_pred_or_func(higher_order(_, _, PredOrFunc, _)) = PredOrFunc.
 generic_call_pred_or_func(class_method(_, _, _, CallId)) =
 	simple_call_id_pred_or_func(CallId).
-generic_call_pred_or_func(unsafe_cast) = predicate.
+generic_call_pred_or_func(cast(_)) = predicate.
 generic_call_pred_or_func(aditi_builtin(_, CallId)) =
 	simple_call_id_pred_or_func(CallId).
 
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.360
diff -u -r1.360 hlds_out.m
--- compiler/hlds_out.m	8 Aug 2005 02:33:08 -0000	1.360
+++ compiler/hlds_out.m	10 Aug 2005 02:13:17 -0000
@@ -427,12 +427,20 @@
 		++ " call".
 hlds_out__generic_call_id_to_string(class_method(_ClassId, MethodId)) =
 	simple_call_id_to_string(MethodId).
-hlds_out__generic_call_id_to_string(unsafe_cast) = "unsafe_cast".
+hlds_out__generic_call_id_to_string(cast(CastType)) =
+	hlds_out__cast_type_to_string(CastType).
 hlds_out__generic_call_id_to_string(aditi_builtin(AditiBuiltin, CallId))
 		= Str :-
 	hlds_out__aditi_builtin_name(AditiBuiltin, Name),
 	Str = "`" ++ Name ++ "' of " ++ simple_call_id_to_string(CallId).
 
+:- func hlds_out__cast_type_to_string(cast_type) = string.
+
+hlds_out__cast_type_to_string(unsafe_type_cast) = "unsafe_type_cast".
+hlds_out__cast_type_to_string(unsafe_type_inst_cast) = "unsafe_type_inst_cast".
+hlds_out__cast_type_to_string(equiv_type_cast) = "equiv_type_cast".
+hlds_out__cast_type_to_string(exists_cast) = "exists_cast".
+
 hlds_out__write_call_arg_id(CallId, ArgNum, PredMarkers, !IO) :-
 	Str = hlds_out__call_arg_id_to_string(CallId, ArgNum, PredMarkers),
 	io__write_string(Str, !IO).
@@ -516,7 +524,7 @@
 	).
 hlds_out__arg_number_to_string(generic_call(class_method(_, _)), ArgNum) =
 	"argument " ++ int_to_string(ArgNum).
-hlds_out__arg_number_to_string(generic_call(unsafe_cast), ArgNum) =
+hlds_out__arg_number_to_string(generic_call(cast(_)), ArgNum) =
 	"argument " ++ int_to_string(ArgNum).
 hlds_out__arg_number_to_string(generic_call(aditi_builtin(Builtin, CallId)),
 		ArgNum) =
@@ -1768,12 +1776,13 @@
 		mercury_output_term(Term, VarSet, AppendVarNums, !IO),
 		io__write_string(Follow, !IO)
 	;
-		GenericCall = unsafe_cast,
+		GenericCall = cast(CastType),
+		CastTypeString = hlds_out__cast_type_to_string(CastType),
 		globals__io_lookup_string_option(dump_hlds_options, Verbose,
 			!IO),
 		( string__contains_char(Verbose, 'l') ->
 			hlds_out__write_indent(Indent, !IO),
-			io__write_string("% unsafe_cast\n", !IO)
+			io__write_strings(["% ", CastTypeString, "\n"], !IO)
 		;
 			true
 		),
@@ -1786,7 +1795,7 @@
 		;
 			true
 		),
-		Functor = term__atom("unsafe_cast"),
+		Functor = term__atom(CastTypeString),
 		term__var_list_to_term_list(ArgVars, ArgTerms),
 		term__context_init(Context),
 		Term = term__functor(Functor, ArgTerms, Context),
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.168
diff -u -r1.168 hlds_pred.m
--- compiler/hlds_pred.m	8 Aug 2005 02:33:09 -0000	1.168
+++ compiler/hlds_pred.m	10 Aug 2005 02:09:52 -0000
@@ -134,7 +134,7 @@
 :- type generic_call_id
 	--->	higher_order(purity, pred_or_func, arity)
 	;	class_method(class_id, simple_call_id)
-	;	unsafe_cast
+	;	cast(cast_type)
 	;	aditi_builtin(aditi_builtin, simple_call_id).
 
 :- type pred_proc_list	==	list(pred_proc_id).
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.171
diff -u -r1.171 intermod.m
--- compiler/intermod.m	23 May 2005 03:15:36 -0000	1.171
+++ compiler/intermod.m	5 Aug 2005 08:54:00 -0000
@@ -508,7 +508,7 @@
 		Goal - Info, DoWrite, !Info) :-
 	( CallType = higher_order(_, _, _, _), DoWrite = yes
 	; CallType = class_method(_, _, _, _), DoWrite = no
-	; CallType = unsafe_cast, DoWrite = no
+	; CallType = cast(_), DoWrite = no
 	; CallType = aditi_builtin(_, _), DoWrite = yes
 	).
 intermod__traverse_goal(switch(Var, CanFail, Cases0) - Info,
Index: compiler/interval.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/interval.m,v
retrieving revision 1.4
diff -u -r1.4 interval.m
--- compiler/interval.m	30 Mar 2005 01:32:29 -0000	1.4
+++ compiler/interval.m	5 Aug 2005 08:34:56 -0000
@@ -289,8 +289,8 @@
 		ArgModes, ArgTypes, InputArgs, _OutputArgs),
 	determinism_to_code_model(Detism, CodeModel),
 
-	% unsafe_casts are generated inline.
-	( GenericCall = unsafe_cast ->
+	% Casts are generated inline.
+	( GenericCall = cast(_) ->
 		require_in_regs(InputArgs, !IntervalInfo),
 		require_access(InputArgs, !IntervalInfo)
 	;
@@ -967,8 +967,8 @@
 record_decisions_in_goal(Goal0, Goal, !VarInfo, !VarRename, InsertMap,
                 MaybeFeature) :-
 	Goal0 = generic_call(GenericCall, _ , _, _) - _,
-	% unsafe_casts are generated inline.
-	( GenericCall = unsafe_cast ->
+	% Casts are generated inline.
+	( GenericCall = cast(_) ->
 		MustHaveMap = no
 	;
 		MustHaveMap = yes
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.109
diff -u -r1.109 live_vars.m
--- compiler/live_vars.m	22 Jul 2005 12:31:56 -0000	1.109
+++ compiler/live_vars.m	5 Aug 2005 08:49:43 -0000
@@ -293,7 +293,7 @@
 build_live_sets_in_goal_2(Goal, Goal, GoalInfo0, GoalInfo, ResumeVars0,
 		AllocData, !StackAlloc, !Liveness, !NondetLiveness) :-
 	Goal = generic_call(GenericCall, ArgVars, Modes, _Det),
-	( GenericCall = unsafe_cast ->
+	( GenericCall = cast(_) ->
 		GoalInfo = GoalInfo0
 	;
 		ProcInfo = AllocData ^ proc_info,
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.51
diff -u -r1.51 ml_call_gen.m
--- compiler/ml_call_gen.m	22 Mar 2005 06:40:08 -0000	1.51
+++ compiler/ml_call_gen.m	5 Aug 2005 08:52:52 -0000
@@ -164,7 +164,7 @@
 		Determinism, Context, Decls, Statements, !Info) :-
 	ml_gen_generic_call_2(GenericCall, ArgVars, ArgModes, Determinism,
 		Context, Decls, Statements, !Info).
-ml_gen_generic_call(unsafe_cast, ArgVars, _ArgModes, _Determinism, Context,
+ml_gen_generic_call(cast(_), ArgVars, _ArgModes, _Determinism, Context,
 		Decls, Statements, !Info) :-
 	ml_gen_cast(Context, ArgVars, Decls, Statements, !Info).
 ml_gen_generic_call(aditi_builtin(_, _), _, _, _, _, _, _, !Info) :-
@@ -255,8 +255,8 @@
 		FuncType = mlds__func_type(Params),
 		FuncRval = unop(unbox(FuncType), lval(FuncLval))
 	;
-		GenericCall = unsafe_cast,
-		error("ml_gen_generic_call_2: unsafe_cast")
+		GenericCall = cast(_),
+		error("ml_gen_generic_call_2: cast")
 	;
 		GenericCall = aditi_builtin(_, _),
 		error("ml_gen_generic_call_2: aditi_builtin")
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.10
diff -u -r1.10 mode_constraints.m
--- compiler/mode_constraints.m	23 May 2005 03:15:37 -0000	1.10
+++ compiler/mode_constraints.m	5 Aug 2005 08:36:41 -0000
@@ -1236,8 +1236,8 @@
 			!GCInfo),
 		error("mode_constraints.m: class_method call in clause")
 	;
-		GenericCall = unsafe_cast,
-		error("mode_constraints.m: unsafe_cast call NYI")
+		GenericCall = cast(_),
+		error("mode_constraints.m: type/inst cast call NYI")
 	;
 		GenericCall = aditi_builtin(_, _),
 		error("mode_constraints.m: aditi_builtin call NYI")
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.303
diff -u -r1.303 modes.m
--- compiler/modes.m	10 Aug 2005 06:10:34 -0000	1.303
+++ compiler/modes.m	10 Aug 2005 16:14:35 -0000
@@ -1504,7 +1504,7 @@
         GenericCall = class_method(_, _, _, _),
         error("modecheck_goal_expr: class_method_call")
     ;
-        GenericCall = unsafe_cast,
+        GenericCall = cast(_CastType),
         (
             goal_info_has_feature(GoalInfo0, keep_constant_binding),
             mode_info_get_instmap(!.ModeInfo, InstMap),
@@ -1516,7 +1516,7 @@
                 Mode1 = Mode1Prime,
                 Mode2 = Mode2Prime
             ;
-                error("modecheck_goal_expr: bad unsafe_cast")
+                error("modecheck_goal_expr: bad cast")
             ),
             Mode1 = in_mode,
             Mode2 = out_mode,
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.266
diff -u -r1.266 polymorphism.m
--- compiler/polymorphism.m	22 Jul 2005 12:31:59 -0000	1.266
+++ compiler/polymorphism.m	11 Aug 2005 15:15:51 -0000
@@ -379,6 +379,7 @@
 :- import_module libs__globals.
 :- import_module libs__options.
 :- import_module mdbcomp__prim_data.
+:- import_module parse_tree__error_util.
 :- import_module parse_tree__prog_io.
 :- import_module parse_tree__prog_mode.
 :- import_module parse_tree__prog_out.
@@ -392,6 +393,8 @@
 :- import_module require.
 :- import_module set.
 :- import_module string.
+:- import_module svmap.
+:- import_module svvarset.
 :- import_module term.
 :- import_module varset.
 
@@ -478,7 +481,7 @@
 		ExtraHeadVars = ExtraHeadVars0,
 		OldHeadVars = OldHeadVars0
 	;
-		error("polymorphism.m: list__split_list failed")
+		unexpected(this_file, "fixup_pred: list__split_list failed")
 	),
 
 	map__apply_to_list(ExtraHeadVars, VarTypes0, ExtraArgTypes),
@@ -487,12 +490,11 @@
 		PredInfo0, PredInfo1),
 
 	%
-	% If the clauses binds some existentially quantified
-	% type variables, make sure the types of the type-infos
-	% for those type variables in the variable types map
-	% are as specific as possible. The predicate argument
-	% types shouldn't be substituted, because the binding
-	% should not be visible to calling predicates.
+	% If the clauses bind some existentially quantified type variables,
+	% introduce exists_casts goals for affected head variables, including
+	% the new type_info and typeclass_info arguments.  Make sure the
+	% types of the internal versions of type_infos for those type
+	% variables in the variable types map are as specific as possible.
 	%
 	(
 		ExistQVars \= [],
@@ -502,26 +504,8 @@
 		type_list_subsumes(ArgTypes0, OldHeadVarTypes, Subn),
 		\+ map__is_empty(Subn)
 	->
-		list__foldl(
-			(pred(HeadVar::in, Types0::in, Types::out) is det :-
-				map__lookup(Types0, HeadVar, HeadVarType0),
-				term__apply_rec_substitution(HeadVarType0,
-					Subn, HeadVarType),
-				map__set(Types0, HeadVar, HeadVarType, Types)
-			), ExtraHeadVars, VarTypes0, VarTypes),
-		clauses_info_set_vartypes(VarTypes, ClausesInfo0, ClausesInfo),
-		pred_info_set_clauses_info(ClausesInfo, PredInfo1, PredInfo2),
-
-		% Fix up the var-types in the procedures as well.
-		% It would be better if this were done before copying
-		% clauses to procs, but that's difficult to arrange.
-		pred_info_procedures(PredInfo2, Procs0),
-		map__map_values(
-			(pred(_::in, ProcInfo0::in, ProcInfo::out) is det :-
-				proc_info_set_vartypes(VarTypes,
-					ProcInfo0, ProcInfo)
-			), Procs0, Procs),
-		pred_info_set_procedures(Procs, PredInfo2, PredInfo)
+		introduce_exists_casts_pred(!.ModuleInfo, Subn, ExtraHeadVars,
+			PredInfo1, PredInfo)
 	;
 		PredInfo = PredInfo1
 	),
@@ -529,6 +513,208 @@
 	map__det_update(PredTable0, PredId, PredInfo, PredTable),
 	module_info_set_preds(PredTable, !ModuleInfo).
 
+:- pred introduce_exists_casts_pred(module_info::in, tsubst::in,
+	list(prog_var)::in, pred_info::in, pred_info::out) is det.
+
+introduce_exists_casts_pred(ModuleInfo, Subn, ExtraHeadVars, !PredInfo) :-
+	list__length(ExtraHeadVars, NumExtraHeadVars),
+
+	% Note that updating the vartypes here, and also below, only needs
+	% to be done because type_info/1 and typeclass_info/1 have types
+	% appearing in their respective arguments.  When we get rid of those,
+	% updating the vartypes will no longer be required.
+	%
+	% XXX Do we really need to modify the clauses_info here?  The
+	% clauses_info shouldn't be used beyond this point anyway.  Do we
+	% also need to introduce the exists_cast goals to the clauses_info?
+	%
+	pred_info_clauses_info(!.PredInfo, ClausesInfo0),
+	clauses_info_vartypes(ClausesInfo0, VarTypes0),
+	list__foldl(
+		(pred(HeadVar::in, Types0::in, Types::out) is det :-
+			map__lookup(Types0, HeadVar, HeadVarType0),
+			term__apply_rec_substitution(HeadVarType0,
+				Subn, HeadVarType),
+			map__set(Types0, HeadVar, HeadVarType, Types)
+		), ExtraHeadVars, VarTypes0, VarTypes),
+	clauses_info_set_vartypes(VarTypes, ClausesInfo0, ClausesInfo),
+	pred_info_set_clauses_info(ClausesInfo, !PredInfo),
+
+	pred_info_procedures(!.PredInfo, Procs0),
+	pred_info_arg_types(!.PredInfo, ArgTypes),
+	map__map_values(
+		(pred(_::in, !.ProcInfo::in, !:ProcInfo::out) is det :-
+			% Add the extra goals to each procedure.
+			introduce_exists_casts_proc(ModuleInfo, ArgTypes, Subn,
+				NumExtraHeadVars, !ProcInfo)
+		), Procs0, Procs),
+	pred_info_set_procedures(Procs, !PredInfo).
+
+:- pred introduce_exists_casts_proc(module_info::in, list(type)::in,
+	tsubst::in, int::in, proc_info::in, proc_info::out) is det.
+
+introduce_exists_casts_proc(ModuleInfo, ArgTypes, Subn, NumExtraHeadVars,
+		!ProcInfo) :-
+	proc_info_varset(!.ProcInfo, VarSet0),
+	proc_info_vartypes(!.ProcInfo, VarTypes0),
+	proc_info_headvars(!.ProcInfo, HeadVars0),
+	proc_info_goal(!.ProcInfo, Body0),
+	proc_info_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
+	proc_info_argmodes(!.ProcInfo, ArgModes),
+
+	(
+		list__drop(NumExtraHeadVars, ArgTypes, OrigArgTypes0),
+		list__split_list(NumExtraHeadVars, HeadVars0,
+			ExtraHeadVars0, OrigHeadVars0),
+		list__split_list(NumExtraHeadVars, ArgModes,
+			ExtraArgModes0, OrigArgModes0)
+	->
+		OrigArgTypes = OrigArgTypes0,
+		ExtraHeadVars1 = ExtraHeadVars0,
+		OrigHeadVars1 = OrigHeadVars0,
+		ExtraArgModes = ExtraArgModes0,
+		OrigArgModes = OrigArgModes0
+	;
+		unexpected(this_file, "introduce_exists_casts_proc: "
+			++ "split_list failed")
+	),
+
+	% Add exists_casts for any head vars which are existentially typed,
+	% and for which the type is bound inside the procedure.  The tsubst
+	% that we pass in represents which existential types are bound.
+	introduce_exists_casts_head(ModuleInfo, Subn, OrigArgTypes,
+		OrigArgModes, OrigHeadVars1, OrigHeadVars, VarSet0, VarSet1,
+		VarTypes0, VarTypes1, [], ExistsCastHeadGoals),
+
+	% Add exists_casts for any existential type_infos or typeclass_infos.
+	% We determine which of these are existential by looking at the mode.
+	introduce_exists_casts_extra(ModuleInfo, Subn, ExtraArgModes,
+		ExtraHeadVars1, ExtraHeadVars, VarSet1, VarSet,
+		VarTypes1, VarTypes, RttiVarMaps0, RttiVarMaps,
+		ExistsCastExtraGoals),
+
+	Body0 = _ - GoalInfo0,
+	goal_to_conj_list(Body0, Goals0),
+	list__append(ExistsCastHeadGoals, ExistsCastExtraGoals,
+		ExistsCastGoals),
+	list__append(Goals0, ExistsCastGoals, Goals),
+	list__append(ExtraHeadVars, OrigHeadVars, HeadVars),
+	set__list_to_set(HeadVars, NonLocals),
+	goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo),
+	Body = conj(Goals) - GoalInfo,
+	proc_info_set_body(VarSet, VarTypes, HeadVars, Body, RttiVarMaps,
+		!ProcInfo).
+
+:- pred introduce_exists_casts_head(module_info::in, tsubst::in,
+	list(type)::in, list(mode)::in, list(prog_var)::in,
+	list(prog_var)::out, prog_varset::in, prog_varset::out,
+	vartypes::in, vartypes::out, list(hlds_goal)::in, list(hlds_goal)::out)
+	is det.
+
+introduce_exists_casts_head(ModuleInfo, Subn, ArgTypes, ArgModes, !HeadVars,
+		!VarSet, !VarTypes, !ExtraGoals) :-
+	(
+		ArgTypes = [],
+		ArgModes = [],
+		!.HeadVars = []
+	->
+		true
+	;
+		ArgTypes = [ArgType | ArgTypesRest],
+		ArgModes = [ArgMode | ArgModesRest],
+		!.HeadVars = [HeadVar0 | HeadVarsRest0]
+	->
+		introduce_exists_casts_head(ModuleInfo, Subn, ArgTypesRest,
+			ArgModesRest, HeadVarsRest0, HeadVarsRest, !VarSet,
+			!VarTypes, !ExtraGoals),
+		introduce_exists_casts_head_2(ModuleInfo, Subn, ArgType,
+			ArgMode, HeadVar0, HeadVar, !VarSet, !VarTypes,
+			!ExtraGoals),
+		!:HeadVars = [HeadVar | HeadVarsRest]
+	;
+		unexpected(this_file,
+			"introduce_exists_casts_head: length mismatch")
+	).
+
+:- pred introduce_exists_casts_head_2(module_info::in, tsubst::in,
+	(type)::in, (mode)::in, prog_var::in, prog_var::out,
+	prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
+	list(hlds_goal)::in, list(hlds_goal)::out) is det.
+
+introduce_exists_casts_head_2(ModuleInfo, Subn, ExternalType, ArgMode,
+		HeadVar0, HeadVar, !VarSet, !VarTypes, !ExtraGoals) :-
+	term__apply_rec_substitution(ExternalType, Subn, InternalType),
+	(
+		% Add an exists_cast for the head variable if its type
+		% inside the procedure is different from its type at the
+		% interface.
+		InternalType \= ExternalType
+	->
+		term__context_init(Context),
+		svmap__det_update(HeadVar0, InternalType, !VarTypes),
+		make_new_exist_cast_var(HeadVar0, HeadVar, !VarSet),
+		svmap__det_insert(HeadVar, ExternalType, !VarTypes),
+		mode_get_insts(ModuleInfo, ArgMode, _, Inst),
+		generate_cast(exists_cast, HeadVar0, HeadVar, Inst, Inst,
+			Context, ExtraGoal),
+		!:ExtraGoals = [ExtraGoal | !.ExtraGoals]
+	;
+		HeadVar = HeadVar0
+	).
+
+:- pred introduce_exists_casts_extra(module_info::in, tsubst::in,
+	list(mode)::in, list(prog_var)::in, list(prog_var)::out,
+	prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
+	rtti_varmaps::in,  rtti_varmaps::out, list(hlds_goal)::out) is det.
+
+introduce_exists_casts_extra(_, _, [], [], [], !VarSet, !VarTypes,
+	!RttiVarMaps, []).
+introduce_exists_casts_extra(_, _, [], [_ | _], _, _, _, _, _, _, _, _) :-
+	unexpected(this_file, "introduce_exists_casts_extra: length mismatch").
+introduce_exists_casts_extra(_, _, [_ | _], [], _, _, _, _, _, _, _, _) :-
+	unexpected(this_file, "introduce_exists_casts_extra: length mismatch").
+introduce_exists_casts_extra(ModuleInfo, Subn, [ArgMode | ArgModes],
+		[Var0 | Vars0], [Var | Vars], !VarSet, !VarTypes, !RttiVarMaps,
+		ExtraGoals) :-
+	introduce_exists_casts_extra(ModuleInfo, Subn, ArgModes, Vars0, Vars,
+		!VarSet, !VarTypes, !RttiVarMaps, ExtraGoals0),
+
+	(
+		mode_is_output(ModuleInfo, ArgMode)
+	->
+			% Update the type of this variable.  This only needs
+			% to be done because type_info/1 and typeclass_info/1
+			% have types in their respective arguments.
+			%
+		map__lookup(!.VarTypes, Var0, ExternalType),
+		term__apply_rec_substitution(ExternalType, Subn, InternalType),
+		svmap__det_update(Var0, InternalType, !VarTypes),
+
+			% Create the exists_cast goal.
+			%
+		term__context_init(Context),
+		make_new_exist_cast_var(Var0, Var, !VarSet),
+		svmap__det_insert(Var, ExternalType, !VarTypes),
+		generate_cast(exists_cast, Var0, Var, Context, ExtraGoal),
+		ExtraGoals = [ExtraGoal | ExtraGoals0],
+	
+			% Update the rtti_varmaps.
+			% XXX need to do this
+		true
+	;
+		Var = Var0,
+		ExtraGoals = ExtraGoals0
+	).
+
+:- pred make_new_exist_cast_var(prog_var::in, prog_var::out,
+	prog_varset::in, prog_varset::out) is det.
+
+make_new_exist_cast_var(InternalVar, ExternalVar, !VarSet) :-
+	svvarset__new_var(ExternalVar, !VarSet),
+	varset__lookup_name(!.VarSet, InternalVar, InternalName),
+	string__append("ExistQ", InternalName, ExternalName),
+	svvarset__name_var(ExternalVar, ExternalName, !VarSet).
+
 %---------------------------------------------------------------------------%
 
 :- pred polymorphism__process_pred(pred_id::in,
@@ -3534,4 +3720,11 @@
 poly_info_set_module_info(ModuleInfo, PI, PI ^ module_info := ModuleInfo).
 
 %---------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "polymorphism.m".
+
+%---------------------------------------------------------------------------%
+:- end_module check_hlds__polymorphism.
 %---------------------------------------------------------------------------%
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.35
diff -u -r1.35 prog_rep.m
--- compiler/prog_rep.m	12 Apr 2005 01:53:55 -0000	1.35
+++ compiler/prog_rep.m	5 Aug 2005 10:54:16 -0000
@@ -220,14 +220,14 @@
 			vars_to_byte_list(Info, Args) ++
 			AtomicBytes
 	;
-		GenericCall = unsafe_cast,
+		GenericCall = cast(_),
 		( Args = [InputArg, OutputArg] ->
 			Bytes = [goal_type_to_byte(goal_unsafe_cast)] ++
 				var_to_byte_list(Info, OutputArg) ++
 				var_to_byte_list(Info, InputArg) ++
 				AtomicBytes
 		;
-			error("goal_expr_to_byte_list: unsafe_cast arity != 2")
+			error("goal_expr_to_byte_list: cast arity != 2")
 		)
 	;
 		GenericCall = aditi_builtin(_, _),
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.75
diff -u -r1.75 purity.m
--- compiler/purity.m	23 May 2005 03:15:40 -0000	1.75
+++ compiler/purity.m	5 Aug 2005 08:39:43 -0000
@@ -512,12 +512,12 @@
             ModuleInfo, Name0, Name, PredId0, PredId),
         (
             % Convert any calls to private_builtin.unsafe_type_cast
-            % into unsafe_cast goals.
+            % into unsafe_type_cast generic calls.
             Name = qualified(mercury_private_builtin_module,
                 "unsafe_type_cast"),
             Vars = [InputArg, OutputArg]
         ->
-            Goal = generic_call(unsafe_cast, [InputArg, OutputArg],
+            Goal = generic_call(cast(unsafe_type_cast), [InputArg, OutputArg],
                 [in_mode, out_mode], det)
         ;
             Goal = call(PredId, ProcId, Vars, BIState, UContext, Name)
@@ -541,7 +541,7 @@
         Purity = pure, % XXX this is wrong!
         GoalExpr = generic_call(GenericCall0, Args, Modes0, Det)
     ;
-        GenericCall0 = unsafe_cast,
+        GenericCall0 = cast(_),
         Purity = pure,
         GoalExpr = generic_call(GenericCall0, Args, Modes0, Det)
     ;
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.144
diff -u -r1.144 simplify.m
--- compiler/simplify.m	27 Jul 2005 13:21:42 -0000	1.144
+++ compiler/simplify.m	5 Aug 2005 08:40:09 -0000
@@ -2546,7 +2546,7 @@
         GenericCall = class_method(_, _, _, _),
 		WillFlush0 = yes
 	;
-        GenericCall = unsafe_cast,
+        GenericCall = cast(_),
 		WillFlush0 = no
 	;
         GenericCall = aditi_builtin(_, _),
Index: compiler/term_traversal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/term_traversal.m,v
retrieving revision 1.35
diff -u -r1.35 term_traversal.m
--- compiler/term_traversal.m	11 Jul 2005 16:11:12 -0000	1.35
+++ compiler/term_traversal.m	5 Aug 2005 08:54:27 -0000
@@ -273,7 +273,7 @@
 		%
 		add_error(Context, method_call, Params, !Info)
 	;
-		Details = unsafe_cast
+		Details = cast(_)
 	;
 		Details = aditi_builtin(_, _),
 		%	
Index: compiler/tupling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/tupling.m,v
retrieving revision 1.7
diff -u -r1.7 tupling.m
--- compiler/tupling.m	22 Jul 2005 12:32:00 -0000	1.7
+++ compiler/tupling.m	5 Aug 2005 08:54:45 -0000
@@ -1046,8 +1046,8 @@
 		ArgModes, ArgTypes, InputArgs, OutputArgs),
 	determinism_to_code_model(Detism, CodeModel),
 
-	% unsafe_casts are generated inline.
-	( GenericCall = unsafe_cast ->
+	% Casts are generated inline.
+	( GenericCall = cast(_) ->
 		cls_require_in_regs(CountInfo, InputArgs, !CountState),
 		cls_put_in_regs(OutputArgs, !CountState)
 	;
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.373
diff -u -r1.373 typecheck.m
--- compiler/typecheck.m	23 May 2005 03:15:41 -0000	1.373
+++ compiler/typecheck.m	10 Aug 2005 10:47:21 -0000
@@ -1351,7 +1351,7 @@
         GenericCall0 = class_method(_, _, _, _),
         error("typecheck_goal_2: unexpected class method call")
     ;
-        GenericCall0 = unsafe_cast,
+        GenericCall0 = cast(_),
         % A cast imposes no restrictions on its argument types,
         % so nothing needs to be done here.
         GenericCall = GenericCall0
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.146
diff -u -r1.146 unify_proc.m
--- compiler/unify_proc.m	22 Jul 2005 12:32:00 -0000	1.146
+++ compiler/unify_proc.m	5 Aug 2005 10:42:38 -0000
@@ -776,7 +776,8 @@
 		InitGoal = InitCall - GoalInfo,
 
 		Any = any(shared),
-		generate_unsafe_cast(X0, X, Any, Any, Context, CastGoal),
+		generate_cast(equiv_type_cast, X0, X, Any, Any, Context,
+			CastGoal),
 		Goal = conj([InitGoal, CastGoal]) - GoalInfo,
 		unify_proc__quantify_clauses_body([X], Goal, Context, Clauses,
 			!Info)
@@ -981,8 +982,8 @@
 		"Cast_HeadVar", 1, CastVar1, !Info),
 	unify_proc__make_fresh_named_var_from_type(EqvType,
 		"Cast_HeadVar", 2, CastVar2, !Info),
-	generate_unsafe_cast(H1, CastVar1, Context, Cast1Goal),
-	generate_unsafe_cast(H2, CastVar2, Context, Cast2Goal),
+	generate_cast(equiv_type_cast, H1, CastVar1, Context, Cast1Goal),
+	generate_cast(equiv_type_cast, H2, CastVar2, Context, Cast2Goal),
 	create_atomic_unification(CastVar1, var(CastVar2), Context,
 		explicit, [], UnifyGoal),
 
@@ -1082,10 +1083,10 @@
 				unify_proc__make_fresh_named_var_from_type(
 					IntType, "Cast_HeadVar", 2, CastVar2,
 					!Info),
-				generate_unsafe_cast(H1, CastVar1, Context,
-					Cast1Goal),
-				generate_unsafe_cast(H2, CastVar2, Context,
-					Cast2Goal),
+				generate_cast(unsafe_type_cast, H1, CastVar1,
+					Context, Cast1Goal),
+				generate_cast(unsafe_type_cast, H2, CastVar2,
+					Context, Cast2Goal),
 				unify_proc__build_call("builtin_compare_int",
 					[Res, CastVar1, CastVar2], Context,
 					CompareGoal, !Info),
@@ -1246,8 +1247,8 @@
 		"Cast_HeadVar", 1, CastVar1, !Info),
 	unify_proc__make_fresh_named_var_from_type(EqvType,
 		"Cast_HeadVar", 2, CastVar2, !Info),
-	generate_unsafe_cast(H1, CastVar1, Context, Cast1Goal),
-	generate_unsafe_cast(H2, CastVar2, Context, Cast2Goal),
+	generate_cast(equiv_type_cast, H1, CastVar1, Context, Cast1Goal),
+	generate_cast(equiv_type_cast, H2, CastVar2, Context, Cast2Goal),
 	unify_proc__build_call("compare", [Res, CastVar1, CastVar2],
 		Context, CompareGoal, !Info),
 
@@ -1352,8 +1353,8 @@
 			!Info),
 		unify_proc__info_new_named_var(int_type, "CastY", CastY,
 			!Info),
-		generate_unsafe_cast(X, CastX, Context, CastXGoal0),
-		generate_unsafe_cast(Y, CastY, Context, CastYGoal0),
+		generate_cast(unsafe_type_cast, X, CastX, Context, CastXGoal0),
+		generate_cast(unsafe_type_cast, Y, CastY, Context, CastYGoal0),
 		goal_add_feature(CastXGoal0, keep_constant_binding, CastXGoal),
 		goal_add_feature(CastYGoal0, keep_constant_binding, CastYGoal),
 		create_atomic_unification(CastY, var(CastX), Context,
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.91
diff -u -r1.91 unique_modes.m
--- compiler/unique_modes.m	3 Aug 2005 12:04:42 -0000	1.91
+++ compiler/unique_modes.m	5 Aug 2005 08:43:36 -0000
@@ -484,7 +484,7 @@
 	;
 		% Casts are introduced by the compiler
 		% and should be mode correct.
-		GenericCall = unsafe_cast,
+		GenericCall = cast(_),
 		ArgOffset = 0
 	;
 		GenericCall = aditi_builtin(_, _),
--------------------------------------------------------------------------
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