[m-rev.] [PATCH] Fix writing of coerce casts in .opt files.

Peter Wang novalazy at gmail.com
Wed Feb 16 16:13:16 AEDT 2022


This also belongs on the release branch.
----

We inadventently wrote out 'coerce' casts in .opt files as:

    V_2 = 'coerce expression'(V_3).

In commit 233874403fc1cdd70b8c92b121a07335f6c5436f, cast_type_to_string
was changed to return "coerce expression" instead of simply "coerce"
for a slight improvement in mode errors.

compiler/hlds_out_goal.m:
    Don't use the result of cast_type_to_string when when writing out
    coerce casts.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/coerce_opt.exp:
tests/hard_coded/coerce_opt.m:
tests/hard_coded/coerce_opt_2.m:
    Add test case.

diff --git a/compiler/hlds_out_goal.m b/compiler/hlds_out_goal.m
index a9d6cfa4f..eaf0150a7 100644
--- a/compiler/hlds_out_goal.m
+++ b/compiler/hlds_out_goal.m
@@ -1527,7 +1527,13 @@ write_goal_generic_call(Info, Stream, _ModuleInfo, VarSet, _TypeQual,
         io.write_string(Stream, Follow, !IO)
     ;
         GenericCall = cast(CastType),
-        CastTypeString = cast_type_to_string(CastType),
+        ( if CastType = subtype_coerce then
+            % We must produce valid Mercury code for coerce casts that are
+            % written to .opt files.
+            CastTypeString = "coerce"
+        else
+            CastTypeString = cast_type_to_string(CastType)
+        ),
         ( if string.contains_char(DumpOptions, 'l') then
             write_indent(Stream, Indent, !IO),
             io.write_strings(Stream, ["% ", CastTypeString, "\n"], !IO),
diff --git a/tests/hard_coded/Mercury.options b/tests/hard_coded/Mercury.options
index d776123c1..202f12592 100644
--- a/tests/hard_coded/Mercury.options
+++ b/tests/hard_coded/Mercury.options
@@ -21,6 +21,7 @@ MCFLAGS-checked_nondet_tailcall_noinline = --checked-nondet-tailcalls --no-inlin
 MCFLAGS-cc_and_non_cc_test = 	--no-inlining
 MCFLAGS-constraint	=	--constraint-propagation --enable-termination
 MCFLAGS-constraint_order =	--constraint-propagation --enable-termination
+MCFLAGS-coerce_opt =		--intermodule-optimization
 MCFLAGS-deforest_cc_bug =	--deforestation
 MCFLAGS-delay_partial_test =    --delay-partial-instantiations
 MCFLAGS-delay_partial_test2 =   --delay-partial-instantiations
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 4e162cea2..d197ec01e 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -63,6 +63,7 @@ ORDINARY_PROGS = \
 	checked_nondet_tailcall_noinline \
 	closeable_channel_test \
 	closure_extension \
+	coerce_opt \
 	common_type_cast \
 	compare_spec \
 	comparison \
diff --git a/tests/hard_coded/coerce_opt.exp b/tests/hard_coded/coerce_opt.exp
new file mode 100644
index 000000000..446c001e7
--- /dev/null
+++ b/tests/hard_coded/coerce_opt.exp
@@ -0,0 +1,4 @@
+coerce_opt_2.non_empty_list(int)
+[1, 2, 3]
+list.list(int)
+[1, 2, 3]
diff --git a/tests/hard_coded/coerce_opt.m b/tests/hard_coded/coerce_opt.m
new file mode 100644
index 000000000..1e07822ec
--- /dev/null
+++ b/tests/hard_coded/coerce_opt.m
@@ -0,0 +1,28 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module coerce_opt.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+:- import_module type_desc.
+
+:- import_module coerce_opt_2.
+
+main(!IO) :-
+    Xs = [1, 2, 3],
+    io.print_line(type_of(Xs), !IO),
+    io.print_line(Xs, !IO),
+
+    Ys = to_list(Xs),
+    io.print_line(type_of(Ys), !IO),
+    io.print_line(Ys, !IO).
diff --git a/tests/hard_coded/coerce_opt_2.m b/tests/hard_coded/coerce_opt_2.m
new file mode 100644
index 000000000..4ec630417
--- /dev/null
+++ b/tests/hard_coded/coerce_opt_2.m
@@ -0,0 +1,21 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module coerce_opt_2.
+:- interface.
+
+:- import_module list.
+
+:- type non_empty_list(T) =< list(T)
+    --->    [T | list(T)].
+
+:- func to_list(non_empty_list(T)) = list(T).
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- pragma inline(func(to_list/1)).
+
+to_list(Xs) = coerce(Xs).
-- 
2.31.0



More information about the reviews mailing list