mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
tests/invalid/*.m:
Rename modules as mentioned above.
In two cases where the main module name is a Mercury keyword (to the
extent that Mercury has keywords), add a "test_" prefix to the
module name.
Reorganize the ho_default_func_2 test case. The original code
of this test had three modules, a parent and two children,
with the module being tested being one of the *child* modules
(ho_default_func_2.sub). This does not work; the .log file
from the successful execution of this test case showed that
there was no actual compilation involved; the test stopped
after invoking "mmc --generate-dependencies" on that child module.
The new version of this test makes that child module the main module,
and moves the relevant parts of the other two original modules
into a single new child module.
Rename ii_parent to instance_pc (pc being short for parent-child).
This test case still has the child module listed as the target
in Mmakefile, so it still does not progress past generating its
dependencies.
Rename the imported_mode test case as bad_exported_mode,
because this is what it was testing.
exported_mode.m was used both as the main module of a test,
and as a helper module in the imported_mode test (now renamed
to bad_exported_mode). Make a copy of it as a helper module
for bad_exported_mode.
Update all references to the moved modules.
General updates to programming style, such as
- replacing DCG notation with state var notation
- adding lines around vim modelines
- fixing indentation
- fixing grammar errors in comments
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
Update all references to the moved modules and/or moved lines.
113 lines
3.8 KiB
Mathematica
113 lines
3.8 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This is a regression test. Versions of the compiler before 2023 april 19
|
|
% generated a quite misleading error message for the bug in test_pred.
|
|
%
|
|
% The bug is that the switch on Str has an arm that is explicitly for
|
|
% "Str = k", but this test is *also* present in the first switch arm,
|
|
% which is now for a, b and k. This can come about naturally when
|
|
%
|
|
% - k used to be treated the same way as a and b;
|
|
% - the programmer decides to give k its own switch arm, but
|
|
% - then forgets to delete the "Str = k" from its original switch arm.
|
|
%
|
|
% (That is exactly what happened with the original code that inspired
|
|
% this cut-down test case.)
|
|
%
|
|
% The original version of the compiler generated two errors for this bug:
|
|
%
|
|
% Warning: this disjunct will never have any solutions.
|
|
% Error: the goal inside the require_complete_switch [Str] scope is
|
|
% not a switch on `Str'.
|
|
%
|
|
% The contexts were the position of the first Str = k in the code
|
|
% (the line marked below as THE PROBLEM LINE), and the position of the
|
|
% first require_complete_switch scope respectively. These are confusing
|
|
% because
|
|
%
|
|
% - there is not supposed to be a disjunct at THE PROBLEM LINE, since
|
|
% switch detection is supposed to transform that disjunct into a switch arm,
|
|
% and
|
|
% - the body of the require_complete_switch [Str] scope IS in fact a switch
|
|
% on Str.
|
|
%
|
|
% The reason why these error messages are misleading is that despite
|
|
% the contexts, they do not refer to that piece of code at all. They refer
|
|
% to a *copy* of that code. When switch detection sees that there are
|
|
% *two* switch arms for Str = k, it creates a separate arm of the switch
|
|
% on Str for the Str = k case, and sets the code of this arm to be
|
|
% a two-way disjunction containing the code that came after the two
|
|
% occurrences of Str = k. This meant that the second disjunct was
|
|
% "Msg = arg_k", and the first disjunct was this:
|
|
%
|
|
% BaseMsg = "arm_ab_",
|
|
% require_complete_switch [Str]
|
|
% (
|
|
% Str = "a",
|
|
% Msg = BaseMsg ++ "arm_a"
|
|
% ;
|
|
% Str = "b",
|
|
% Msg = BaseMsg ++ "arm_b"
|
|
% )
|
|
%
|
|
% The compiler recognized that *none* of those two switch arms of this *inner*
|
|
% switch is actually reachable in the Str = k branch of the *outer* switch
|
|
% on Str, so it replaced this switch with fail, which meant that this disjunct
|
|
% couldn't succeed (hence the first error message). The fact that it replaced
|
|
% the switch with fail but kept the require_complete_switch scope led to the
|
|
% second error message.
|
|
%
|
|
% So both the error messages the compiler generates are justified, including
|
|
% the line numbers attached to them. What made them misleading was the lack
|
|
% of any reference to the fact that the error occurs only inside the Str = k
|
|
% arm of the outer switch. The fix for that is to print this context.
|
|
|
|
:- module require_complete_nested_switch.
|
|
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
main(!IO) :-
|
|
( if test_pred("abc", Msg) then
|
|
io.format("Success: %s\n", [s(Msg)], !IO)
|
|
else
|
|
io.format("Failure\n", [], !IO)
|
|
).
|
|
|
|
:- pred test_pred(string::in, string::out) is semidet.
|
|
|
|
test_pred(Str, Msg) :-
|
|
(
|
|
( Str = "a"
|
|
; Str = "b"
|
|
; Str = "k" % THE PROBLEM LINE
|
|
),
|
|
BaseMsg = "arm_ab_",
|
|
require_complete_switch [Str]
|
|
(
|
|
Str = "a",
|
|
Msg = BaseMsg ++ "arm_a"
|
|
;
|
|
Str = "b",
|
|
Msg = BaseMsg ++ "arm_b"
|
|
)
|
|
;
|
|
Str = "k",
|
|
Msg = "arg_k"
|
|
;
|
|
( Str = "x"
|
|
; Str = "y"
|
|
),
|
|
Msg = "arg_x_y"
|
|
).
|