mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
compiler/cse_detection.m:
When considering whether a variable's unifications can be pulled
out of disjunctions (or if-then-elses), require only that the
*arguments* of the function symbols it may be unified with are
free of uniqueness, but allow the top level memory cell itself
to be unique (which it will be by default immediately after its
construction). This is sufficient to avoid github issue 64.
This fixes mantis bug 480 in *almost* all cases.
tests/valid/bug480.m:
A modified version of the mantis test case.
tests/valid/Mmakefile:
Enable the new test case.
48 lines
1.5 KiB
Mathematica
48 lines
1.5 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This is a regression test for Mantis bug #480.
|
|
%
|
|
% Versions of the Mercury compiler between 2019 Jun 30 and 2019 Aug 5
|
|
% could not compile the correct code of to_bool below. The reason was that
|
|
% (a) the construction of Struct leaves it with a unique inst for its
|
|
% top level cell, and (b) a fix for github issue 64 applied on Jun 30
|
|
% prevented cse_detection.m from pulling the "Struct = struct(Foo, _Bar)"
|
|
% unifications out of the disjunction, preventing the compiler from
|
|
% recognizing the disjunction as a switch on Foo. The fix was intending
|
|
% to avoid problems with unique insts inside the *arguments* of the
|
|
% structure, but it incorrectly paid attention to the inst of the
|
|
% *top level memory cell* as well.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module bug480.
|
|
:- interface.
|
|
|
|
:- import_module bool.
|
|
:- import_module maybe.
|
|
|
|
:- type struct
|
|
---> struct(
|
|
foo :: maybe(int),
|
|
bar :: int
|
|
).
|
|
|
|
:- func to_bool(struct) = bool.
|
|
|
|
:- implementation.
|
|
|
|
to_bool(Struct0) = Bool :-
|
|
Struct0 = struct(Foo0, Bar0),
|
|
Struct = struct(Foo0, Bar0),
|
|
(
|
|
Struct = struct(Foo, _Bar),
|
|
Foo = yes(_),
|
|
Bool = yes
|
|
;
|
|
Struct = struct(Foo, _Bar),
|
|
Foo = no,
|
|
Bool = no
|
|
).
|