[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