[m-rev.] diff: alternative fix for bug 264 test case
Mark Brown
mark at mercurylang.org
Sun Nov 22 17:11:58 AEDT 2015
On Sat, Nov 21, 2015 at 1:59 PM, Mark Brown <mark at mercurylang.org> wrote:
> While this fixes the test case for the bug, but there may be similar
> cases that still fail. I think the abstract merge and unify algorithms
> in inst_util.m need to be checked to ensure that they are properly
> adhering to the meaning of the ho_inst_info values.
I've now checked these. Abstract unify is not a problem, but merge had
a similar bug to the ones in inst matching; see the attached diff,
which has been committed.
With the existing workaround, the test case in this diff gives the
following output:
default_ho_inst_2.m:033: In clause for `main(di, uo)':
default_ho_inst_2.m:033: mode mismatch in disjunction.
default_ho_inst_2.m:033: The variable `F' has these instantiation states:
default_ho_inst_2.m:033: line 31: unique(default_ho_inst_2.foo(/* unique
default_ho_inst_2.m:033: */(func((ground >> ground)) = (free >> ground) is
default_ho_inst_2.m:033: semidet)))
default_ho_inst_2.m:033: line 33: ground
Mark
-------------- next part --------------
commit 4b640dd74d744040831bac471476370c0df92a6f
Author: Mark Brown <mark at mercurylang.org>
Date: Sun Nov 22 16:42:21 2015 +1100
Fix default func modes in the inst merge operation
compiler/inst_util.m:
When merging bound with ground, ensure that all functions in the
bound match the default function mode.
tests/invalid/Mmakefile:
tests/invalid/default_ho_inst_2.{m,err_exp}:
Test case for this bug. This test currently passes due to the
workaround for bug 264; the above fix means that the workaround
is not needed in this case.
diff --git a/compiler/inst_util.m b/compiler/inst_util.m
index 905923e..0d76fd0 100644
--- a/compiler/inst_util.m
+++ b/compiler/inst_util.m
@@ -1942,12 +1942,14 @@ inst_merge_4(InstA, InstB, MaybeType, Inst, !ModuleInfo) :-
InstA = bound(UniqA, InstResultsA, BoundInstsA),
InstB = ground(UniqB, _),
inst_merge_bound_ground(UniqA, InstResultsA, BoundInstsA, UniqB,
- MaybeType, Inst, !ModuleInfo)
+ MaybeType, Inst, !ModuleInfo),
+ not inst_contains_nondefault_func_mode(!.ModuleInfo, InstA)
;
InstA = ground(UniqA, _),
InstB = bound(UniqB, InstResultsB, BoundInstsB),
inst_merge_bound_ground(UniqB, InstResultsB, BoundInstsB, UniqA,
- MaybeType, Inst, !ModuleInfo)
+ MaybeType, Inst, !ModuleInfo),
+ not inst_contains_nondefault_func_mode(!.ModuleInfo, InstB)
;
InstA = ground(UniqA, HOInstInfoA),
InstB = ground(UniqB, HOInstInfoB),
diff --git a/tests/invalid/Mmakefile b/tests/invalid/Mmakefile
index 42ed197..58a88fe 100644
--- a/tests/invalid/Mmakefile
+++ b/tests/invalid/Mmakefile
@@ -95,6 +95,7 @@ SINGLEMODULE= \
cyclic_typeclass_2 \
cyclic_typeclass_3 \
default_ho_inst \
+ default_ho_inst_2 \
det_atomic_goal_msgs \
det_errors \
det_errors_cc \
diff --git a/tests/invalid/default_ho_inst_2.err_exp b/tests/invalid/default_ho_inst_2.err_exp
new file mode 100644
index 0000000..1a77a2f
--- /dev/null
+++ b/tests/invalid/default_ho_inst_2.err_exp
@@ -0,0 +1,10 @@
+default_ho_inst_2.m:031: In clause for `main(di, uo)':
+default_ho_inst_2.m:031: mode error in unification of `F' and
+default_ho_inst_2.m:031: `default_ho_inst_2.foo(V_8)'.
+default_ho_inst_2.m:031: Argument `V_8' is a function whose argument modes
+default_ho_inst_2.m:031: and/or determinism differ from the default function
+default_ho_inst_2.m:031: signature (f(in, ..., in) = out is det). This is not
+default_ho_inst_2.m:031: allowed, because taking such arguments out of the
+default_ho_inst_2.m:031: term being constructed would lose their mode and
+default_ho_inst_2.m:031: determinism information.
+For more information, recompile with `-E'.
diff --git a/tests/invalid/default_ho_inst_2.m b/tests/invalid/default_ho_inst_2.m
new file mode 100644
index 0000000..a7f02eb
--- /dev/null
+++ b/tests/invalid/default_ho_inst_2.m
@@ -0,0 +1,39 @@
+:- module default_ho_inst_2.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+
+:- type foo
+ ---> foo(func(string) = string).
+
+:- pred makefoo(foo::out) is det.
+
+makefoo(foo(detfoo)).
+
+:- pred callfoo(foo::in, string::in, string::out) is det.
+
+callfoo(foo(F), X, F(X)).
+
+:- func detfoo(string) = string.
+
+detfoo(X) = X.
+
+:- func semifoo(string::in) = (string::out) is semidet.
+
+semifoo(X) = X :- semidet_true.
+
+main(!IO) :-
+ (
+ F = foo(semifoo)
+ ;
+ makefoo(F)
+ ),
+ callfoo(F, "X", X),
+ io.write_string(X, !IO),
+ io.nl(!IO).
+
+% vim: ft=mercury ts=4 sts=4 sw=4 et
More information about the reviews
mailing list