[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