[m-rev.] for review: Parse and check coerce expressions.

Peter Wang novalazy at gmail.com
Fri Mar 12 14:25:06 AEDT 2021


On Wed, 10 Mar 2021 14:40:33 +1100 Peter Wang <novalazy at gmail.com> wrote:
> This change implements parsing, typechecking, and modechecking of
> "coerce" expressions from my subtypes proposal, i.e. coerce(Term).
> Backends currently will abort if asked to generate code for coercions,
> as subtypes do not yet share data representations with their base types,
> so most coercions would lead to crashes at runtime anyway.

Here's a couple more changes to the mode checker.

Peter

diff --git a/compiler/modecheck_coerce.m b/compiler/modecheck_coerce.m
index f445003a0..853c28254 100644
--- a/compiler/modecheck_coerce.m
+++ b/compiler/modecheck_coerce.m
@@ -70,7 +70,10 @@ modecheck_coerce(Args0, Args, Modes0, Modes, Det, ExtraGoals, !ModeInfo) :-
         ( if instmap_is_reachable(InstMap) then
             instmap_lookup_var(InstMap, X, InstX),
             instmap_lookup_var(InstMap, Y, InstY),
-            ( if inst_is_ground(ModuleInfo0, InstX) then
+            ( if
+                inst_is_ground(ModuleInfo0, InstX),
+                not inst_is_clobbered(ModuleInfo0, InstX)
+            then
                 modecheck_coerce_vars(ModuleInfo0, X, Y, InstX, InstY, Res,
                     !ModeInfo),
                 (
@@ -110,11 +113,19 @@ modecheck_coerce_vars(ModuleInfo0, X, Y, InstX, InstY, Res, !ModeInfo) :-
     mode_info_get_var_types(!.ModeInfo, VarTypes),
     lookup_var_type(VarTypes, X, TypeX),
     lookup_var_type(VarTypes, Y, TypeY),
+
+    mode_info_var_is_live(!.ModeInfo, X, LiveX),
+    mode_info_var_is_live(!.ModeInfo, Y, LiveY),
+    ( if LiveX = is_live, LiveY = is_live then
+        BothLive = is_live
+    else
+        BothLive = is_dead
+    ),
+
     set.init(Seen0),
     make_bound_inst_for_type(ModuleInfo0, Seen0, TypeX, BoundInstForTypeX),
     ( if
-        % XXX would we ever want to pass is_dead here?
-        abstractly_unify_inst(is_live, BoundInstForTypeX, InstX, fake_unify,
+        abstractly_unify_inst(BothLive, BoundInstForTypeX, InstX, real_unify,
             UnifyInstForTypeX, _Det, ModuleInfo0, ModuleInfo)
     then
         ( if
diff --git a/tests/invalid/Mmakefile b/tests/invalid/Mmakefile
index a44eb7bdd..1ffc5be83 100644
--- a/tests/invalid/Mmakefile
+++ b/tests/invalid/Mmakefile
@@ -117,6 +117,7 @@ SINGLEMODULE= \
 	circ_type3 \
 	circ_type5 \
 	coerce_ambig \
+	coerce_clobbered \
 	coerce_disambig \
 	coerce_implied_mode \
 	coerce_infer \
diff --git a/tests/invalid/coerce_clobbered.err_exp b/tests/invalid/coerce_clobbered.err_exp
new file mode 100644
index 000000000..2bc874620
--- /dev/null
+++ b/tests/invalid/coerce_clobbered.err_exp
@@ -0,0 +1,4 @@
+coerce_clobbered.m:021: In clause for `bad(in(clobbered), out)':
+coerce_clobbered.m:021:   in coerce:
+coerce_clobbered.m:021:   mode error: `X' has instantiatedness `clobbered',
+coerce_clobbered.m:021:   but it must be ground.
diff --git a/tests/invalid/coerce_clobbered.m b/tests/invalid/coerce_clobbered.m
new file mode 100644
index 000000000..66ce64766
--- /dev/null
+++ b/tests/invalid/coerce_clobbered.m
@@ -0,0 +1,23 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module coerce_clobbered.
+:- interface.
+
+:- type fruit
+    --->    apple
+    ;       orange
+    ;       lemon.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- pred bad(fruit, fruit).
+:- mode bad(clobbered >> clobbered, out) is det.
+
+bad(X, Y) :-
+    Y = coerce(X).
+
+%---------------------------------------------------------------------------%


More information about the reviews mailing list