[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