[m-rev.] for review: fix bug #90
Peter Wang
novalazy at gmail.com
Thu Jun 4 17:02:03 AEST 2009
Branches: main
Fix bug #90. The compiler would abort on the given program when performing
higher order/type specialisation due to "inconsistent type_infos".
compiler/higher_order.m:
In interpret_typeclass_info_manipulator, when assigning to a variable
TypeInfoVar the extracted field of a type_info TypeInfoArg, duplicate
the TypeInfoArg rtti_var_info for TypeInfoVar.
On the test program the rtti_var_info for TypeInfoVar already existed
but was for the procedure *before* specialisation, which is what
lead to the inconsistent type_infos message.
compiler/hlds_rtti.m:
Add version of rtti_var_info_duplicate which doesn't abort if the
rtti_varmap already has an entry for the target variable.
tests/valid/Mercury.options:
tests/valid/Mmakefile:
tests/valid/tci_spec_varmap.m:
Add test case.
diff --git a/compiler/higher_order.m b/compiler/higher_order.m
index 68b7f86..d391f6a 100644
--- a/compiler/higher_order.m
+++ b/compiler/higher_order.m
@@ -2031,7 +2031,15 @@
interpret_typeclass_info_manipulator(Manipulator, Args, Goal0, Goal,
!Info) :-
Uni = assign(TypeInfoVar, TypeInfoArg),
Goal = unify(TypeInfoVar, rhs_var(TypeInfoArg), out_mode - in_mode,
Uni, unify_context(umc_explicit, [])),
- !:Info = !.Info ^ hoi_changed := ho_changed
+
+ ProcInfo0 = !.Info ^ hoi_proc_info,
+ proc_info_get_rtti_varmaps(ProcInfo0, RttiVarMaps0),
+ rtti_var_info_duplicate_replace(TypeInfoArg, TypeInfoVar,
+ RttiVarMaps0, RttiVarMaps),
+ proc_info_set_rtti_varmaps(RttiVarMaps, ProcInfo0, ProcInfo),
+ !Info ^ hoi_proc_info := ProcInfo,
+
+ !Info ^ hoi_changed := ho_changed
;
Goal = Goal0
).
diff --git a/compiler/hlds_rtti.m b/compiler/hlds_rtti.m
index f36c8c0..02163c2 100644
--- a/compiler/hlds_rtti.m
+++ b/compiler/hlds_rtti.m
@@ -249,6 +249,14 @@
:- pred rtti_var_info_duplicate(prog_var::in, prog_var::in,
rtti_varmaps::in, rtti_varmaps::out) is det.
+ % rtti_var_info_duplicate_replace(Var, NewVar, !RttiVarMaps)
+ %
+ % Duplicate the rtti_var_info we have about Var for NewVar.
+ % Replace old information about Var which already exists.
+ %
+:- pred rtti_var_info_duplicate_replace(prog_var::in, prog_var::in,
+ rtti_varmaps::in, rtti_varmaps::out) is det.
+
% Returns all of the tvars that we have information about in the
% rtti_varmaps structure.
%
@@ -524,6 +532,18 @@ rtti_var_info_duplicate(Var, NewVar, !VarMaps) :-
VarInfo = non_rtti_var
).
+rtti_var_info_duplicate_replace(Var, NewVar, !VarMaps) :-
+ rtti_varmaps_var_info(!.VarMaps, Var, VarInfo),
+ (
+ VarInfo = type_info_var(Type),
+ rtti_set_type_info_type(NewVar, Type, !VarMaps)
+ ;
+ VarInfo = typeclass_info_var(Constraint),
+ rtti_set_typeclass_info_var(Constraint, NewVar, !VarMaps)
+ ;
+ VarInfo = non_rtti_var
+ ).
+
rtti_varmaps_tvars(VarMaps, TVars) :-
map.keys(VarMaps ^ ti_varmap, TVars).
diff --git a/tests/valid/Mercury.options b/tests/valid/Mercury.options
index b7770f9..0fe580b 100644
--- a/tests/valid/Mercury.options
+++ b/tests/valid/Mercury.options
@@ -125,6 +125,7 @@ MCFLAGS-solv = --halt-at-warn
MCFLAGS-spurious_purity_warning = --halt-at-warn
MCFLAGS-stack_opt_simplify = --optimize-saved-vars
MCFLAGS-table_no_attr = --structure-sharing
+MCFLAGS-tci_spec_varmap = --deforestation --type-specialisation
MCFLAGS-time_yaowl = --allow-stubs
MCFLAGS-tuple_eqv = --smart-recompilation
MCFLAGS-two_way_unif = -O-1
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index 73838a3..76ea6ad 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -41,6 +41,7 @@ TYPECLASS_PROGS= \
superclass_bug \
superclass_improvement \
tc_map_lookup \
+ tci_spec_varmap \
time_yaowl \
typeclass_constraint_arity \
typeclass_constraint_no_var \
diff --git a/tests/valid/tci_spec_varmap.m b/tests/valid/tci_spec_varmap.m
new file mode 100644
index 0000000..fb34e3f
--- /dev/null
+++ b/tests/valid/tci_spec_varmap.m
@@ -0,0 +1,48 @@
+%-----------------------------------------------------------------------------%
+% Regression test.
+%
+% Software Error: hlds_rtti.m: Unexpected: inconsistent type_infos:
+% Type: type_variable(var(1), kind_star)
+% ExistingType: defined_type(qualified(unqualified("profdeep_rtti_varmap"),
+% "checked_out_task"), [type_variable(var(1), kind_star)], kind_star)
+%
+% The problem had to do with a missing rtti varmap entry after a type_info
+% was extracted from a typeclass_info.
+%-----------------------------------------------------------------------------%
+
+:- module tci_spec_varmap.
+:- interface.
+
+:- import_module io.
+
+:- pred something(T::in, io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+
+something(_, !IO) :-
+ _ = marking([] : list(checked_out_task(T))).
+
+:- type checked_out_task(T)
+ ---> checked_out_task.
+
+:- type marking
+ ---> mark.
+
+:- typeclass marking(T) where [
+ func marking(T) = marking
+].
+
+:- instance marking(list(T)) <= marking(T) where [
+ (marking([]) = mark),
+ (marking([_ | Cs]) = marking(Cs))
+].
+
+:- instance marking(checked_out_task(T)) where [
+ marking(checked_out_task) = mark
+].
+
+%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list