[m-rev.] diff: Revert a fix for constrained polymorphic modes.
Peter Wang
novalazy at gmail.com
Thu Oct 2 18:10:55 AEST 2014
Commit 338b5cb98e8abd320aac6d3619f8ab98f773c846 changed a call in
handle_inst_var_subs_2, essentially from
Recurse(InstA, SubInstB)
to
Recurse(InstA, abstractly_unify_inst(InstA, SubInstB))
Unfortunately, it results in infinite recursion on some cases.
compiler/inst_match.m:
Revert the change to handle_inst_var_subs_2.
tests/EXPECT_FAIL_TESTS.all_grades:
Expect constrained_poly_insts2 to fail now.
tests/invalid/constrained_poly_insts3.err_exp:
tests/invalid/constrained_poly_insts3.m:
tests/invalid/constrained_poly_insts4.err_exp:
tests/invalid/constrained_poly_insts4.m:
Add test cases.
diff --git a/compiler/inst_match.m b/compiler/inst_match.m
index 494df76..5cb8247 100644
--- a/compiler/inst_match.m
+++ b/compiler/inst_match.m
@@ -495,20 +495,35 @@ handle_inst_var_subs(Recurse, Continue, InstA, InstB, Type, !Info) :-
handle_inst_var_subs_2(Recurse, Continue, InstA, InstB, Type, !Info) :-
( InstB = constrained_inst_vars(InstVarsB, SubInstB) ->
- % Add the substitution InstVarsB => InstA `glb` SubInstB
- % (see get_subst_inst in dmo's thesis, page 78).
- %
+ % InstB is a constrained_inst_var with upper bound SubInstB.
+ % We need to check that InstA matches_initial SubInstB and add the
+ % appropriate inst_var substitution.
+ Recurse(InstA, SubInstB, Type, !Info),
+
+ % Call abstractly_unify_inst to calculate the uniqueness of the
+ % inst represented by the constrained_inst_var.
% We pass `Live = is_dead' because we want
% abstractly_unify(unique, unique) = unique, not shared.
+ Live = is_dead,
+ ModuleInfo0 = !.Info ^ imi_module_info,
+ abstractly_unify_inst(Live, InstA, SubInstB, fake_unify,
+ Inst, _Det, ModuleInfo0, ModuleInfo),
+ !Info ^ imi_module_info := ModuleInfo,
+ update_inst_var_sub(InstVarsB, Inst, Type, !Info)
+
+ % This accepts more code but some cases cause infinite recursion.
+ /*
+ % Add the substitution InstVarsB => InstA `glb` SubInstB
+ % (see get_subst_inst in dmo's thesis, page 78).
ModuleInfo0 = !.Info ^ imi_module_info,
abstractly_unify_inst(is_dead, InstA, SubInstB, fake_unify,
Inst, _Det, ModuleInfo0, ModuleInfo),
!Info ^ imi_module_info := ModuleInfo,
update_inst_var_sub(InstVarsB, Inst, Type, !Info),
-
% Check that InstA matches InstB after applying the substitution
% to InstB.
Recurse(InstA, Inst, Type, !Info)
+ */
; InstA = constrained_inst_vars(_InstVarsA, SubInstA) ->
Recurse(SubInstA, InstB, Type, !Info)
;
diff --git a/tests/EXPECT_FAIL_TESTS.all_grades b/tests/EXPECT_FAIL_TESTS.all_grades
index febbde7..ebcf18d 100644
--- a/tests/EXPECT_FAIL_TESTS.all_grades
+++ b/tests/EXPECT_FAIL_TESTS.all_grades
@@ -4,3 +4,4 @@ valid/bug85
valid/constraint_prop_bug
valid/csharp_hello
valid/ho_and_type_spec_bug2
+invalid/constrained_poly_insts2
diff --git a/tests/invalid/constrained_poly_insts3.err_exp b/tests/invalid/constrained_poly_insts3.err_exp
new file mode 100644
index 0000000..fb6d04f
--- /dev/null
+++ b/tests/invalid/constrained_poly_insts3.err_exp
@@ -0,0 +1,9 @@
+constrained_poly_insts3.m:020: In clause for `p1(in((I =< ground)), out((I =<
+constrained_poly_insts3.m:020: ground)))':
+constrained_poly_insts3.m:020: mode error: argument 2 became too
+constrained_poly_insts3.m:020: instantiated.
+constrained_poly_insts3.m:020: Final instantiatedness of `Y' was
+constrained_poly_insts3.m:020: `bound((list.[]) ; list.'[|]'(ground,
+constrained_poly_insts3.m:020: bound((list.[]) ; list.'[|]'(ground, ...))))',
+constrained_poly_insts3.m:020: expected final instantiatedness was `(I =<
+constrained_poly_insts3.m:020: ground)'.
diff --git a/tests/invalid/constrained_poly_insts3.m b/tests/invalid/constrained_poly_insts3.m
new file mode 100644
index 0000000..81118e2
--- /dev/null
+++ b/tests/invalid/constrained_poly_insts3.m
@@ -0,0 +1,28 @@
+%-----------------------------------------------------------------------------%
+
+:- module constrained_poly_insts3.
+:- interface.
+
+:- import_module list.
+
+:- type thing == list(list(int)).
+:- inst thing == list_skel(ground).
+
+:- pred p1(thing, thing).
+:- mode p1(in(I), out(I)) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+p1(X, Y) :-
+ q(X, Y).
+
+:- pred q(thing, thing).
+:- mode q(in(thing), out(thing)) is det.
+
+q(X, X).
+
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sts=4 sw=4 et
diff --git a/tests/invalid/constrained_poly_insts4.err_exp b/tests/invalid/constrained_poly_insts4.err_exp
new file mode 100644
index 0000000..f12d05f
--- /dev/null
+++ b/tests/invalid/constrained_poly_insts4.err_exp
@@ -0,0 +1,10 @@
+constrained_poly_insts4.m:020: In clause for `p2(in((I =<
+constrained_poly_insts4.m:020: (constrained_poly_insts4.thing))), out((I =<
+constrained_poly_insts4.m:020: (constrained_poly_insts4.thing))))':
+constrained_poly_insts4.m:020: mode error: argument 2 became too
+constrained_poly_insts4.m:020: instantiated.
+constrained_poly_insts4.m:020: Final instantiatedness of `Y' was
+constrained_poly_insts4.m:020: `bound((list.[]) ; list.'[|]'(ground,
+constrained_poly_insts4.m:020: bound((list.[]) ; list.'[|]'(ground, ...))))',
+constrained_poly_insts4.m:020: expected final instantiatedness was `(I =<
+constrained_poly_insts4.m:020: bound((list.[]) ; list.'[|]'(ground, ...)))'.
diff --git a/tests/invalid/constrained_poly_insts4.m b/tests/invalid/constrained_poly_insts4.m
new file mode 100644
index 0000000..af0c2bf
--- /dev/null
+++ b/tests/invalid/constrained_poly_insts4.m
@@ -0,0 +1,28 @@
+%-----------------------------------------------------------------------------%
+
+:- module constrained_poly_insts4.
+:- interface.
+
+:- import_module list.
+
+:- type thing == list(list(int)).
+:- inst thing == list_skel(ground).
+
+:- pred p2(thing, thing).
+:- mode p2(in(I =< thing), out(I =< thing)) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+p2(X, Y) :-
+ q(X, Y).
+
+:- pred q(thing, thing).
+:- mode q(in(thing), out(thing)) is det.
+
+q(X, X).
+
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sts=4 sw=4 et
More information about the reviews
mailing list