diff: inlining and unbound typevars

Tyson Richard DOWD trd at cs.mu.oz.au
Fri May 30 16:20:35 AEST 1997


Hi,

Fergus, can you please review this - in particular the renaming of
variables when actually doing inlining. I'm not sure that I have got
this right (it does fix the bug, however).

===================================================================

Estimated hours taken: 5

Fix another bug triggered by compilation for accurate gc.

The compiler was not correctly handling the unbound type variables when
doing inlining.

compiler/inlining.m:
	Update TypeVarSet and TypeInfoVarMap when inlining - unbound
	type variables can occur in the callee which need to be migrated
	to the caller when inlined.
	Introduce new inline_info type, which stores information
	threaded through inling. This should make future changes to
	inlining much easier.

compiler/type_util.m:
	Add `apply_substitutions_to_var_map' which will update a
	map(tvar, var) given a type substitution and a variable
	substitution.

tests/valid/Mmake:
tests/valid/agc_unbound_typevars2.m:
	Test case for this bug.

Index: compiler/inlining.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/inlining.m,v
retrieving revision 1.62
diff -u -r1.62 inlining.m
--- inlining.m	1997/05/21 02:13:27	1.62
+++ inlining.m	1997/05/30 05:25:28
@@ -289,6 +289,32 @@
 
 %-----------------------------------------------------------------------------%
 
+		% inline_info contains the information that is changed
+		% as a result of inlining. It is threaded through the
+		% inlining process, and when finished, contains the
+		% updated information associated with the new goal.
+		%
+		% It also stores some necessary information that is not
+		% updated.
+
+:- type inline_info	--->
+
+	inline_info(
+		int,			% variable threshold for inlining
+		set(pred_proc_id),	% inlined procs
+		module_info,		% module_info
+
+			% the following fields are updated as a result
+			% of inlining
+		varset,			% varset
+		map(var, type),		% variable types
+		tvarset,		% type variables
+		map(tvar, var)		% type_info varset, a mapping from 
+					% type variables to variables
+					% where their type_info is
+					% stored.
+		).
+
 :- pred inlining__in_predproc(pred_proc_id, set(pred_proc_id),
 		inline_params, module_info, module_info).
 :- mode inlining__in_predproc(in, in, in, in, out) is det.
@@ -304,90 +330,81 @@
 	pred_info_procedures(PredInfo0, ProcTable0),
 	map__lookup(ProcTable0, ProcId, ProcInfo0),
 
-	pred_info_typevarset(PredInfo0, TypeVarSet),
+	pred_info_typevarset(PredInfo0, TypeVarSet0),
+
 	proc_info_goal(ProcInfo0, Goal0),
-	proc_info_variables(ProcInfo0, Varset0),
+	proc_info_variables(ProcInfo0, VarSet0),
 	proc_info_vartypes(ProcInfo0, VarTypes0),
+	proc_info_typeinfo_varmap(ProcInfo0, TypeInfoVarMap0),
+
+	InlineInfo0 = inline_info(VarThresh, InlinedProcs, ModuleInfo0,
+		VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0),
+
+	inlining__inlining_in_goal(Goal0, InlineInfo0, Goal, InlineInfo),
 
-	inlining__inlining_in_goal(Goal0, Varset0, VarTypes0, TypeVarSet,
-		ModuleInfo0, InlinedProcs, VarThresh, Goal,
-		Varset, VarTypes),
+	InlineInfo = inline_info(_, _, _, VarSet, VarTypes, TypeVarSet, 
+		TypeInfoVarMap),
 
-	proc_info_set_variables(ProcInfo0, Varset, ProcInfo1),
+	pred_info_set_typevarset(PredInfo0, TypeVarSet, PredInfo1),
+
+	proc_info_set_variables(ProcInfo0, VarSet, ProcInfo1),
 	proc_info_set_vartypes(ProcInfo1, VarTypes, ProcInfo2),
-	proc_info_set_goal(ProcInfo2, Goal, ProcInfo),
+	proc_info_set_typeinfo_varmap(ProcInfo2, TypeInfoVarMap, ProcInfo3),
+	proc_info_set_goal(ProcInfo3, Goal, ProcInfo),
 
 	map__det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
-	pred_info_set_procedures(PredInfo0, ProcTable, PredInfo),
+	pred_info_set_procedures(PredInfo1, ProcTable, PredInfo),
 	map__det_update(PredTable0, PredId, PredInfo, PredTable),
 	module_info_set_preds(ModuleInfo0, PredTable, ModuleInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred inlining__inlining_in_goal(hlds_goal, varset, map(var, type),
-	tvarset, module_info, set(pred_proc_id), int, hlds_goal,
-	varset, map(var, type)).
-:- mode inlining__inlining_in_goal(in, in, in, in, in, in, in, out, out, out)
-	is det.
-
-inlining__inlining_in_goal(Goal0 - GoalInfo, Varset0, VarTypes0, TypeVarSet,
-		ModuleInfo, InlinedProcs, VarThresh,
-			Goal - GoalInfo, Varset, VarTypes) :-
-	inlining__inlining_in_goal_2(Goal0, Varset0, VarTypes0, TypeVarSet,
-		ModuleInfo, InlinedProcs, VarThresh, Goal, Varset, VarTypes).
+:- pred inlining__inlining_in_goal(hlds_goal, inline_info, hlds_goal, 
+		inline_info).
+:- mode inlining__inlining_in_goal(in, in, out, out) is det.
+
+inlining__inlining_in_goal(Goal0 - GoalInfo, InlineInfo0, Goal - GoalInfo, 
+		InlineInfo) :-
+	inlining__inlining_in_goal_2(Goal0, InlineInfo0, Goal, InlineInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred inlining__inlining_in_goal_2(hlds_goal_expr, varset, map(var, type),
-	tvarset, module_info, set(pred_proc_id), int, hlds_goal_expr,
-	varset, map(var, type)).
-:- mode inlining__inlining_in_goal_2(in, in, in, in, in, in, in, out, out, out)
-	is det.
-
-inlining__inlining_in_goal_2(conj(Goals0), Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh,
-		conj(Goals), Varset, VarTypes) :-
-	inlining__inlining_in_conj(Goals0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Goals, Varset, VarTypes).
-
-inlining__inlining_in_goal_2(disj(Goals0, SM), Varset0, VarTypes0, TVarset,
-		ModuleInfo, InlinedProcs, Thresh,
-		disj(Goals, SM), Varset, VarTypes) :-
-	inlining__inlining_in_disj(Goals0, Varset0, VarTypes0, TVarset,
-		ModuleInfo, InlinedProcs, Thresh, Goals, Varset, VarTypes).
-
-inlining__inlining_in_goal_2(switch(Var, Det, Cases0, SM),
-		Varset0, VarTypes0, TVarset, ModuleInfo, InlinedProcs, Thresh,
-		switch(Var, Det, Cases, SM), Varset, VarTypes) :-
-	inlining__inlining_in_cases(Cases0, Varset0, VarTypes0, TVarset,
-		ModuleInfo, InlinedProcs, Thresh, Cases, Varset, VarTypes).
+:- pred inlining__inlining_in_goal_2(hlds_goal_expr, inline_info,
+		hlds_goal_expr, inline_info).
+:- mode inlining__inlining_in_goal_2(in, in, out, out) is det.
+
+inlining__inlining_in_goal_2(conj(Goals0), InlineInfo0, conj(Goals), 
+		InlineInfo) :-
+	inlining__inlining_in_conj(Goals0, InlineInfo0, Goals, InlineInfo).
+
+inlining__inlining_in_goal_2(disj(Goals0, SM), InlineInfo0, disj(Goals, SM),
+		InlineInfo) :-
+	inlining__inlining_in_disj(Goals0, InlineInfo0, Goals, InlineInfo).
+
+inlining__inlining_in_goal_2(switch(Var, Det, Cases0, SM), InlineInfo0,
+		switch(Var, Det, Cases, SM), InlineInfo) :-
+	inlining__inlining_in_cases(Cases0, InlineInfo0, Cases, InlineInfo).
 
 inlining__inlining_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM),
-		Varset0, VarTypes0, TVarSet, ModuleInfo, InlinedProcs, Thresh,
-		if_then_else(Vars, Cond, Then, Else, SM), Varset, VarTypes) :-
-	inlining__inlining_in_goal(Cond0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Cond, Varset1, VarTypes1),
-	inlining__inlining_in_goal(Then0, Varset1, VarTypes1, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Then, Varset2, VarTypes2),
-	inlining__inlining_in_goal(Else0, Varset2, VarTypes2, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Else, Varset, VarTypes).
-
-inlining__inlining_in_goal_2(not(Goal0), Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh,
-		not(Goal), Varset, VarTypes) :-
-	inlining__inlining_in_goal(Goal0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Goal, Varset, VarTypes).
-
-inlining__inlining_in_goal_2(some(Vars, Goal0), Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh,
-		some(Vars, Goal), Varset, VarTypes) :-
-	inlining__inlining_in_goal(Goal0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Goal, Varset, VarTypes).
+		InlineInfo0, if_then_else(Vars, Cond, Then, Else, SM), 
+		InlineInfo) :-
+	inlining__inlining_in_goal(Cond0, InlineInfo0, Cond, InlineInfo1),
+	inlining__inlining_in_goal(Then0, InlineInfo1, Then, InlineInfo2),
+	inlining__inlining_in_goal(Else0, InlineInfo2, Else, InlineInfo).
+
+inlining__inlining_in_goal_2(not(Goal0), InlineInfo0, not(Goal), InlineInfo) :-
+	inlining__inlining_in_goal(Goal0, InlineInfo0, Goal, InlineInfo).
+
+inlining__inlining_in_goal_2(some(Vars, Goal0), InlineInfo0, some(Vars, Goal),
+		InlineInfo) :-
+	inlining__inlining_in_goal(Goal0, InlineInfo0, Goal, InlineInfo).
 
 inlining__inlining_in_goal_2(
 		call(PredId, ProcId, ArgVars, Builtin, Context, Sym),
-		Varset0, VarTypes0, TypeVarSet,
-		ModuleInfo, InlinedProcs, Thresh, Goal, Varset, VarTypes) :-
+		InlineInfo0, Goal, InlineInfo) :-
+
+	InlineInfo0 = inline_info(VarThresh, InlinedProcs, ModuleInfo,
+		VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0),
 
 	% should we inline this call?
 	(
@@ -395,7 +412,7 @@
 				InlinedProcs, ModuleInfo),
 			% okay, but will we exceed the number-of-variables
 			% threshold?
-		varset__vars(Varset0, ListOfVars),
+		varset__vars(VarSet0, ListOfVars),
 		list__length(ListOfVars, ThisMany),
 			% We need to find out how many variables the
 			% Callee has
@@ -405,7 +422,7 @@
 		varset__vars(CalleeVarset, CalleeListOfVars),
 		list__length(CalleeListOfVars, CalleeThisMany),
 		TotalVars is ThisMany + CalleeThisMany,
-		TotalVars =< Thresh
+		TotalVars =< VarThresh
 	->
 		% Yes.  So look up the rest of the info for the
 		% called procedure.
@@ -414,6 +431,7 @@
 		proc_info_headvars(ProcInfo, HeadVars),
 		proc_info_goal(ProcInfo, CalledGoal),
 		proc_info_vartypes(ProcInfo, CalleeVarTypes0),
+		proc_info_typeinfo_varmap(ProcInfo, CalledTypeInfoVarMap0),
 
 		% Substitute the appropriate types into the type
 		% mapping of the called procedure.  For example, if we
@@ -422,11 +440,13 @@
 		% type `T' with type `int' when we inline it.
 
 		% first, rename apart the type variables in the callee.
-		% (we can throw away the new typevarset, since
-		% we are about to substitute away any new type variables)
+		% (we can almost throw away the new typevarset, since we
+		% are about to substitute away any new type variables,
+		% but any unbound type variables in the callee will not
+		% be substituted away)
 
-		varset__merge_subst(TypeVarSet, CalleeTypeVarSet,
-			_NewTypeVarSet, TypeRenaming),
+		varset__merge_subst(TypeVarSet0, CalleeTypeVarSet,
+			TypeVarSet, TypeRenaming),
 		apply_substitution_to_type_map(CalleeVarTypes0, TypeRenaming,
 			CalleeVarTypes1),
 
@@ -455,83 +475,72 @@
 		% Now rename apart the variables in the called goal.
 
 		map__from_corresponding_lists(HeadVars, ArgVars, Subn0),
-		goal_util__create_variables(CalleeListOfVars, Varset0,
+		goal_util__create_variables(CalleeListOfVars, VarSet0,
 			VarTypes0, Subn0, CalleeVarTypes, CalleeVarset,
-				Varset, VarTypes, Subn),
+				VarSet, VarTypes, Subn),
 		goal_util__must_rename_vars_in_goal(CalledGoal, Subn,
-			Goal - _GInfo)
+			Goal - _GInfo),
+		apply_substitutions_to_var_map(CalledTypeInfoVarMap0, 
+			TypeRenaming, Subn, CalledTypeInfoVarMap1),
+		map__merge(TypeInfoVarMap0, CalledTypeInfoVarMap1,
+			TypeInfoVarMap)
 	;
 		Goal = call(PredId, ProcId, ArgVars, Builtin, Context, Sym),
-		Varset = Varset0,
-		VarTypes = VarTypes0
-	).
-
-inlining__inlining_in_goal_2(higher_order_call(A, B, C, D, E),
-		Varset, VarTypes, _, _, _, _,
-		higher_order_call(A, B, C, D, E), Varset, VarTypes).
+		VarSet = VarSet0,
+		VarTypes = VarTypes0,
+		TypeVarSet = TypeVarSet0,
+		TypeInfoVarMap = TypeInfoVarMap0
+	),
+	InlineInfo = inline_info(VarThresh, InlinedProcs, ModuleInfo,
+		VarSet, VarTypes, TypeVarSet, TypeInfoVarMap).
+
+inlining__inlining_in_goal_2(higher_order_call(A, B, C, D, E), InlineInfo,
+		higher_order_call(A, B, C, D, E), InlineInfo).
 
-inlining__inlining_in_goal_2(unify(A, B, C, D, E), Varset, VarTypes,
-		_, _, _, _, unify(A, B, C, D, E), Varset, VarTypes).
+inlining__inlining_in_goal_2(unify(A, B, C, D, E), InlineInfo,
+		unify(A, B, C, D, E), InlineInfo).
 
-inlining__inlining_in_goal_2(pragma_c_code(A,B,C,D,E,F,G,H), Varset, VarTypes,
-		_, _, _, _, pragma_c_code(A,B,C,D,E,F,G,H), Varset, VarTypes).
+inlining__inlining_in_goal_2(pragma_c_code(A,B,C,D,E,F,G,H), InlineInfo,
+		pragma_c_code(A,B,C,D,E,F,G,H), InlineInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred inlining__inlining_in_disj(list(hlds_goal), varset, map(var, type),
-	tvarset, module_info, set(pred_proc_id), int, list(hlds_goal),
-	varset, map(var, type)).
-:- mode inlining__inlining_in_disj(in, in, in, in, in, in, in, out, out, out)
-	is det.
-
-inlining__inlining_in_disj([], Varset, VarTypes, _, _, _, _,
-		[], Varset, VarTypes).
-inlining__inlining_in_disj([Goal0 | Goals0], Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, [Goal | Goals],
-		Varset, VarTypes) :-
-	inlining__inlining_in_goal(Goal0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goal, Varset1, VarTypes1),
-	inlining__inlining_in_disj(Goals0, Varset1, VarTypes1, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goals, Varset, VarTypes).
+:- pred inlining__inlining_in_disj(list(hlds_goal), inline_info, 
+		list(hlds_goal), inline_info).
+:- mode inlining__inlining_in_disj(in, in, out, out) is det.
+
+inlining__inlining_in_disj([], InlineInfo, [], InlineInfo).
+inlining__inlining_in_disj([Goal0 | Goals0], InlineInfo0,
+		[Goal | Goals], InlineInfo) :-
+	inlining__inlining_in_goal(Goal0, InlineInfo0, Goal, InlineInfo1),
+	inlining__inlining_in_disj(Goals0, InlineInfo1, Goals, InlineInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred inlining__inlining_in_cases(list(case), varset, map(var, type),
-	tvarset, module_info, set(pred_proc_id), int, list(case),
-	varset, map(var, type)).
-:- mode inlining__inlining_in_cases(in, in, in, in, in, in, in, out, out, out)
-	is det.
+:- pred inlining__inlining_in_cases(list(case), inline_info, list(case), 
+		inline_info).
+:- mode inlining__inlining_in_cases(in, in, out, out) is det.
 
-inlining__inlining_in_cases([], Varset, VarTypes, _, _, _, _,
-				[], Varset, VarTypes).
+inlining__inlining_in_cases([], InlineInfo, [], InlineInfo).
 inlining__inlining_in_cases([case(Cons, Goal0) | Goals0],
-		Varset0, VarTypes0, TVarSet, ModuleInfo, InlinedProcs,
-		Threshold, [case(Cons, Goal) | Goals], Varset, VarTypes) :-
-	inlining__inlining_in_goal(Goal0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goal, Varset1, VarTypes1),
-	inlining__inlining_in_cases(Goals0, Varset1, VarTypes1, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goals, Varset, VarTypes).
+		InlineInfo0, [case(Cons, Goal) | Goals], InlineInfo) :-
+	inlining__inlining_in_goal(Goal0, InlineInfo0, Goal, InlineInfo1),
+	inlining__inlining_in_cases(Goals0, InlineInfo1, Goals, InlineInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred inlining__inlining_in_conj(list(hlds_goal), varset, map(var, type),
-	tvarset, module_info, set(pred_proc_id), int, list(hlds_goal),
-	varset, map(var, type)).
-:- mode inlining__inlining_in_conj(in, in, in, in, in, in, in, out, out, out)
-	is det.
+:- pred inlining__inlining_in_conj(list(hlds_goal), inline_info,
+	list(hlds_goal), inline_info).
+:- mode inlining__inlining_in_conj(in, in, out, out) is det.
 
 	% Since a single goal may become a conjunction,
 	% we flatten the conjunction as we go.
 
-inlining__inlining_in_conj([], Varset, VarTypes, _, _, _, _,
-		[], Varset, VarTypes).
-inlining__inlining_in_conj([Goal0 | Goals0], Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goals, Varset, VarTypes) :-
-	inlining__inlining_in_goal(Goal0, Varset0, VarTypes0, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goal1, Varset1, VarTypes1),
+inlining__inlining_in_conj([], InlineInfo, [], InlineInfo).
+inlining__inlining_in_conj([Goal0 | Goals0], InlineInfo0, Goals, InlineInfo) :-
+	inlining__inlining_in_goal(Goal0, InlineInfo0, Goal1, InlineInfo1),
 	goal_to_conj_list(Goal1, Goal1List),
-	inlining__inlining_in_conj(Goals0, Varset1, VarTypes1, TVarSet,
-		ModuleInfo, InlinedProcs, Threshold, Goals1, Varset, VarTypes),
+	inlining__inlining_in_conj(Goals0, InlineInfo1, Goals1, InlineInfo),
 	list__append(Goal1List, Goals1, Goals).
 
 %-----------------------------------------------------------------------------%
Index: compiler/type_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/type_util.m,v
retrieving revision 1.42
diff -u -r1.42 type_util.m
--- type_util.m	1997/04/08 05:57:21	1.42
+++ type_util.m	1997/05/30 05:14:59
@@ -65,6 +65,7 @@
 	
 :- pred type_util__var(type, var).
 :- mode type_util__var(in, out) is semidet.
+:- mode type_util__var(out, in) is det.
 
 	% Given a type_id, a list of argument types and maybe a context,
 	% construct a type.
@@ -148,6 +149,15 @@
 						 map(var, type)).
 :- mode apply_rec_substitution_to_type_map(in, in, out) is det.
 
+	% Update a map from tvar to var, using the type substititon to
+	% rename tvars and a variable substition to rename vars.
+	%
+	% If tvar maps to a another type variable, we keep the new
+	% variable, if it maps to a type, we remove it from the map.
+
+:- pred apply_substitutions_to_var_map(map(tvar, var), tsubst, map(var, var), 
+		map(tvar, var)).
+:- mode apply_substitutions_to_var_map(in, in, in, out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -617,7 +627,53 @@
 	map__det_update(VarTypes0, Var, VarType, VarTypes1),
 	apply_rec_substitution_to_type_map_2(Vars, VarTypes1, Subst, VarTypes).
 
+%-----------------------------------------------------------------------------%
+
+apply_substitutions_to_var_map(VarMap0, TSubst, Subst, VarMap) :-
+	% optimize the common case of empty substitutions
+	( map__is_empty(Subst) ->
+		VarMap = VarMap0
+	;
+		map__keys(VarMap0, TVars),
+		map__init(NewVarMap),
+		apply_substitutions_to_var_map_2(TVars, VarMap0, TSubst,
+			Subst, NewVarMap, VarMap)
+	).
+
+
+:- pred apply_substitutions_to_var_map_2(list(var)::in, map(tvar, var)::in,
+		tsubst::in, map(var, var)::in, map(tvar, var)::in, 
+		map(tvar, var)::out) is det.
 
+apply_substitutions_to_var_map_2([], _VarMap0, _, _, NewVarMap, NewVarMap).
+apply_substitutions_to_var_map_2([TVar | TVars], VarMap0, TSubst, Subst, 
+		NewVarMap0, NewVarMap) :-
+	map__lookup(VarMap0, TVar, Var),
+
+		% find the new tvar, if there is one, otherwise just
+		% create the old var as a type variable.
+	( map__search(TSubst, TVar, NewTerm0) ->
+		NewTerm = NewTerm0 
+	; 
+		type_util__var(NewTerm, TVar)
+	),
+
+		% find the new var, if there is one
+	( map__search(Subst, Var, NewVar0) ->
+		NewVar = NewVar0
+	;
+		NewVar = Var
+	),
+
+		% if the tvar is still a variable, insert it into the
+		% map with the new var.
+	( type_util__var(NewTerm, NewTVar) ->
+		map__det_insert(NewVarMap0, NewTVar, NewVar, NewVarMap1)
+	;
+		NewVarMap1 = NewVarMap0
+	),
+	apply_substitutions_to_var_map_2(TVars, VarMap0, TSubst, Subst, 
+		NewVarMap1, NewVarMap).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: tests/valid/Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/Mmake,v
retrieving revision 1.37
diff -u -r1.37 Mmake
--- Mmake	1997/05/15 06:55:30	1.37
+++ Mmake	1997/05/30 05:29:29
@@ -9,6 +9,7 @@
 # please keep this list sorted
 SOURCES= \
 	agc_unbound_typevars.m \
+	agc_unbound_typevars2.m \
 	agc_unused_in.m \
 	compl_unify_bug.m \
 	complicated_unify.m \
@@ -76,6 +77,7 @@
 # some regression tests only failed with particular options enabled
 # (please keep this list sorted)
 GRADE-agc_unbound_typevars	= asm_fast.agc
+GRADE-agc_unbound_typevars2	= asm_fast.agc
 GRADE-agc_unused_in		= asm_fast.agc
 MCFLAGS-compl_unify_bug		= -O3
 MCFLAGS-middle_rec_labels	= --middle-rec --no-follow-vars 

New File: tests/valid/agc_unbound_typevars2.m
===================================================================
% Regression test.
%
% Name: agc_unbound_typevars2.m
%
% Description of bug:
% 	This module uses code that contains unbound type variables. The
% 	compiler was not correctly handling the unbound type variables
% 	when doing inlining. All type variables need to be mapped to a 
% 	corresponding type_info variable for accurate GC compilation.
%
% Symptom(s) of bug:
% 	Map lookups fail when looking up unbound type variables.
%
% Date bug existed: 29-May-1997
%
% Author: trd

:- module agc_unbound_typevars2.
:- interface.
:- import_module io.

:- pred write_it(io__state::di, io__state::uo) is det.

:- implementation.

:- import_module list, std_util.


:- pred test_all(T::in, io__state::di, io__state::uo) is det.

:- type poly(A, B)	--->	poly_one(A) ; poly_two(B) ; 
				poly_three(B, A, poly(B, A));
				poly_four(A, B).

%----------------------------------------------------------------------------%

write_it -->
	test_all(3).

%----------------------------------------------------------------------------%

test_all(_T) -->
	{ TypeInfo = type_of(poly_one([2399.3])) },
	{ N = num_functors(TypeInfo) },
	io__write_int(N).


-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't eveyone's cup of
     trd at cs.mu.oz.au        #  fur.
http://www.cs.mu.oz.au/~trd #



More information about the developers mailing list