[m-rev.] for review: fix unification type_info bug
Simon Taylor
stayl at cs.mu.OZ.AU
Tue Jun 11 18:40:44 AEST 2002
Estimated hours taken: 3
compiler/polymorphism.m:
Make sure the type-infos needed for complicated argument
unifications of var-functor unifications are included in
the non-locals set of the unification.
This bug caused an MLDS code generator abort when compiling
library/set_bbbtree.m with `--target asm'.
tests/hard_coded/Mmakefile:
tests/hard_coded/unify_typeinfo_bug.{m,exp}:
Test case.
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.223
diff -u -u -r1.223 polymorphism.m
--- compiler/polymorphism.m 17 Apr 2002 00:52:39 -0000 1.223
+++ compiler/polymorphism.m 10 Jun 2002 17:43:02 -0000
@@ -1197,11 +1197,10 @@
% quantification.m uses when requantifying things.
%
=(Info0),
- { poly_info_get_type_info_map(Info0, TypeInfoMap) },
{ poly_info_get_var_types(Info0, VarTypes) },
{ map__lookup(VarTypes, XVar, Type) },
- { polymorphism__unification_typeinfos(Type, TypeInfoMap,
- Unification0, GoalInfo0, Unification, GoalInfo) },
+ polymorphism__unification_typeinfos(Type,
+ Unification0, GoalInfo0, Unification, GoalInfo),
{ Goal = unify(XVar, Y, Mode, Unification,
UnifyContext) - GoalInfo }
;
@@ -1230,10 +1229,38 @@
{ goal_info_get_nonlocals(GoalInfo0, NonLocals0) },
{ set__union(NonLocals0, NonLocalTypeInfos, NonLocals) },
{ goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo) },
+
+ %
+ % Complicated (in-in) argument unifications are impossible
+ % for lambda expressions, so we don't need to worry about
+ % adding the type-infos that would be required for such
+ % unifications.
+ %
{ Goal = unify(XVar, Y1, Mode, Unification0, UnifyContext)
- GoalInfo }
).
+:- pred polymorphism__unification_typeinfos(type, unification,
+ hlds_goal_info, unification, hlds_goal_info, poly_info, poly_info).
+:- mode polymorphism__unification_typeinfos(in, in, in,
+ out, out, in, out) is det.
+
+polymorphism__unification_typeinfos(Type, Unification0, GoalInfo0,
+ Unification, GoalInfo, Info0, Info) :-
+ %
+ % Compute the type_info/type_class_info variables that would be
+ % used if this unification ends up being a complicated_unify.
+ %
+ type_util__vars(Type, TypeVars),
+ list__map_foldl(get_type_info_locn, TypeVars, TypeInfoLocns,
+ Info0, Info),
+
+ polymorphism__add_unification_typeinfos(TypeInfoLocns,
+ Unification0, GoalInfo0, Unification, GoalInfo).
+
+ % This variant is for use by modecheck_unify.m.
+ % During mode-checking all the type-infos should appear in
+ % the type_info_varmap.
polymorphism__unification_typeinfos(Type, TypeInfoMap,
Unification0, GoalInfo0, Unification, GoalInfo) :-
%
@@ -1242,6 +1269,16 @@
%
type_util__vars(Type, TypeVars),
map__apply_to_list(TypeVars, TypeInfoMap, TypeInfoLocns),
+
+ polymorphism__add_unification_typeinfos(TypeInfoLocns,
+ Unification0, GoalInfo0, Unification, GoalInfo).
+
+:- pred polymorphism__add_unification_typeinfos(list(type_info_locn)::in,
+ unification::in, hlds_goal_info::in,
+ unification::out, hlds_goal_info::out) is det.
+
+polymorphism__add_unification_typeinfos(TypeInfoLocns,
+ Unification0, GoalInfo0, Unification, GoalInfo) :-
list__map(type_info_locn_var, TypeInfoLocns, TypeInfoVars0),
list__remove_dups(TypeInfoVars0, TypeInfoVars),
@@ -1366,23 +1403,33 @@
goal_info_get_context(GoalInfo0, Context),
polymorphism__process_existq_unify_functor(ConsDefn,
IsConstruction, ActualArgTypes, TypeOfX, Context,
- ExtraVars, ExtraGoals, PolyInfo0, PolyInfo),
+ ExtraVars, ExtraGoals, PolyInfo0, PolyInfo1),
list__append(ExtraVars, ArgVars0, ArgVars),
goal_info_get_nonlocals(GoalInfo0, NonLocals0),
set__insert_list(NonLocals0, ExtraVars, NonLocals),
- goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo),
+ goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo1),
+
+ %
+ % Some of the argument unifications may be complicated
+ % unifications, which may need type-infos.
+ %
+ polymorphism__unification_typeinfos(TypeOfX, Unification0,
+ GoalInfo1, Unification, GoalInfo, PolyInfo1, PolyInfo),
+
Unify = unify(X0, functor(ConsId, ArgVars), Mode0,
- Unification0, UnifyContext) - GoalInfo,
+ Unification, UnifyContext) - GoalInfo,
list__append(ExtraGoals, [Unify], GoalList),
conj_list_to_goal(GoalList, GoalInfo0, Goal)
;
%
- % ordinary construction/deconstruction unifications
- % we leave alone
+ % We leave construction/deconstruction unifications alone.
+ % Some of the argument unifications may be complicated
+ % unifications, which may need type-infos.
%
+ polymorphism__unification_typeinfos(TypeOfX, Unification0,
+ GoalInfo0, Unification, GoalInfo, PolyInfo0, PolyInfo),
Goal = unify(X0, functor(ConsId0, ArgVars0), Mode0,
- Unification0, UnifyContext) - GoalInfo0,
- PolyInfo = PolyInfo0
+ Unification, UnifyContext) - GoalInfo
).
convert_pred_to_lambda_goal(EvalMethod, X0, PredId, ProcId,
@@ -2631,30 +2678,46 @@
%
Type = term__variable(TypeVar)
->
- poly_info_get_type_info_map(Info0, TypeInfoMap0),
- %
- % If we have already allocated a location for this type_info,
- % then all we need to do is to extract the type_info variable
- % from its location.
- %
- ( map__search(TypeInfoMap0, TypeVar, TypeInfoLocn) ->
- get_type_info(TypeInfoLocn, TypeVar, ExtraGoals, Var,
- Info0, Info)
- ;
- %
- % Otherwise, we need to create a new type_info
- % variable, and set the location for this type
- % variable to be that type_info variable.
- %
- polymorphism__new_type_info_var(Type, "type_info",
- typeinfo_prefix, Var, Info0, Info1),
- map__det_insert(TypeInfoMap0, TypeVar, type_info(Var),
- TypeInfoMap),
- poly_info_set_type_info_map(TypeInfoMap, Info1, Info),
- ExtraGoals = []
- )
+ get_type_info_locn(TypeVar, TypeInfoLocn, Info0, Info1),
+ get_type_info(TypeInfoLocn, TypeVar, ExtraGoals, Var,
+ Info1, Info)
;
error("polymorphism__make_var: unknown type")
+ ).
+
+:- pred get_type_info_locn(tvar, type_info_locn, poly_info, poly_info).
+:- mode get_type_info_locn(in, out, in, out) is det.
+
+get_type_info_locn(TypeVar, TypeInfoLocn, Info0, Info) :-
+ %
+ % If we have already allocated a location for this type_info,
+ % then all we need to do is to extract the type_info variable
+ % from its location.
+ %
+ poly_info_get_type_info_map(Info0, TypeInfoMap0),
+ ( map__search(TypeInfoMap0, TypeVar, TypeInfoLocn0) ->
+ TypeInfoLocn = TypeInfoLocn0,
+ Info = Info0
+ ;
+ %
+ % Otherwise, we need to create a new type_info
+ % variable, and set the location for this type
+ % variable to be that type_info variable.
+ %
+ % XXX This is wrong if the type variable is one of
+ % the existentially quantified variables of a called
+ % predicate and the variable occurs in an existential
+ % type-class constraint. In that case the type-info
+ % will be stored in the typeclass_info variable produced
+ % by the predicate, not in a type_info variable.
+ %
+ type_util__var(Type, TypeVar),
+ polymorphism__new_type_info_var(Type, "type_info",
+ typeinfo_prefix, Var, Info0, Info1),
+ TypeInfoLocn = type_info(Var),
+ map__det_insert(TypeInfoMap0, TypeVar, TypeInfoLocn,
+ TypeInfoMap),
+ poly_info_set_type_info_map(TypeInfoMap, Info1, Info)
).
:- pred polymorphism__construct_type_info(type, type_ctor, list(type),
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.152
diff -u -u -r1.152 Mmakefile
--- tests/hard_coded/Mmakefile 10 Jun 2002 10:05:54 -0000 1.152
+++ tests/hard_coded/Mmakefile 10 Jun 2002 18:36:14 -0000
@@ -139,6 +139,7 @@
type_spec_modes \
type_to_term_bug \
unify_expression \
+ unify_typeinfo_bug \
unused_float_box_test \
user_defined_equality2 \
write \
Index: tests/hard_coded/unify_typeinfo_bug.exp
===================================================================
RCS file: tests/hard_coded/unify_typeinfo_bug.exp
diff -N tests/hard_coded/unify_typeinfo_bug.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/unify_typeinfo_bug.exp 10 Jun 2002 18:35:51 -0000
@@ -0,0 +1,4 @@
+Succeeded
+Succeeded
+Succeeded
+Succeeded
Index: tests/hard_coded/unify_typeinfo_bug.m
===================================================================
RCS file: tests/hard_coded/unify_typeinfo_bug.m
diff -N tests/hard_coded/unify_typeinfo_bug.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/unify_typeinfo_bug.m 10 Jun 2002 18:35:31 -0000
@@ -0,0 +1,57 @@
+:- module unify_typeinfo_bug.
+:- interface.
+
+:- import_module io, list.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- pred unify_bug(list(T)::in, list(T)::in) is semidet.
+
+:- pred exist_unify_bug(list(T)::in, list(T)::in) is semidet.
+
+:- type set_bbbtree(T).
+
+:- pred singleton_set(set_bbbtree(T), T).
+:- mode singleton_set(in, in) is semidet.
+
+:- implementation.
+
+main -->
+ ( { unify_bug([1], [1]) } ->
+ io__write_string("Succeeded\n")
+ ;
+ io__write_string("Failed\n")
+ ),
+ ( { exist_unify_bug([1], [1]) } ->
+ io__write_string("Succeeded\n")
+ ;
+ io__write_string("Failed\n")
+ ),
+ ( { exist_unify_bug([1], [1]) } ->
+ io__write_string("Succeeded\n")
+ ;
+ io__write_string("Failed\n")
+ ),
+ ( { singleton_set(tree([1], 1, empty, empty), [1]) } ->
+ io__write_string("Succeeded\n")
+ ;
+ io__write_string("Failed\n")
+ ).
+
+unify_bug(A, B) :-
+ A = [H | _],
+ B = [H | _].
+
+exist_unify_bug(A, B) :-
+ C = D,
+ exist_id(A, B, C, D).
+
+:- some [U] pred exist_id(T::in, T::in, U::out, U::out) is det.
+
+exist_id(A, B, A, B).
+
+:- type set_bbbtree(T)
+ ---> empty
+ ; tree(T, int, set_bbbtree(T), set_bbbtree(T)).
+
+singleton_set(tree(V, 1, empty, empty), V).
--------------------------------------------------------------------------
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