mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-25 14:24:11 +00:00
Estimated hours taken: 4
Branches: main
Improve the compiler's ability to deal with determinism errors, in three ways.
1. Add a new pragma, no_determinism_warning, that suppresses the compiler's
warning about a determinism declaration that is not as tight as possible.
2. When printing determinism errors about disjunctions in supposed-to-be-det
code, print the list of switch arms that the disjunction is in. Without
this, it can be hard to find duplicated cases in a long list of switch
cases. (If the report tells you there is a disjunction in the arm for
f/1 in the switch on X, it tells you that you have duplicated the arm
for X = f(_).)
3. When the compiler prints a message about a switch on a variable not covering
some cases, sometimes the variable is an anonymous variable:
The switch on V_16 does not cover ...
These anonymous variables are created by common-structure elimination,
which groups disjuncts containing unifications such as A = f(a), A = f(b),
A = f(c) into a single arm of the switch on A, A = f(V_16), with a switch
inside that on V_16.
The third part of this diff gives the context of the error in the error
switch as not being the arm for f/1 in the switch on A, but as the arm for
f(V_16) in the switch on A, thus letting users know where the anonymous
variable comes from.
doc/reference_manual.texi:
Document the new pragma.
compiler/prog_item.m:
Add the new pragma to the list of pragmas we recognize.
compiler/hlds_pred.m:
Add the new kind of predicate marker whose presence indicates
that this pragma was given for this predicate.
compiler/prog_io_pragma.m:
Parse the new pragma.
compiler/add_pragma.m:
Process the new pragma: when found, set the marker on the named
predicate.
compiler/det_report.m:
Make all three changes listed above.
In addition, fix a problem that used to happen only rarely:
when printing switch contexts, we used to print them from the inside
out, not the outside in.
Capitalize only the first clause in a multi-clause error message.
compiler/hlds_out_util.m:
Add a function for printing a cons_id either with or without its
arguments, for use by det_report.m Let this function string module
qualifiers from cons_ids, since these are virtually always obvious,
and whose printing is therefore unnecessary clutter.
compiler/equiv_type.m:
compiler/hlds_out_pred.m:
compiler/make_hlds_passes.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/recompilation.version.m:
compiler/table_gen.m:
Conform to the changes above.
tests/invalid/det_errors.{m,err_exp}:
Add some predicates to this module to test the new functionality,
and update the expected output.
143 lines
2.0 KiB
Mathematica
143 lines
2.0 KiB
Mathematica
% vim: ts=4 sw=4 et ft=mercury
|
|
|
|
:- module det_errors.
|
|
|
|
:- interface.
|
|
|
|
:- pred p1(int::in) is det.
|
|
:- pred p2(int::in) is det.
|
|
:- pred p3(int::in) is det.
|
|
:- pred p4(int::in) is det.
|
|
:- pred p5(int::in) is det.
|
|
|
|
:- type t
|
|
---> a
|
|
; b
|
|
; c
|
|
; d
|
|
; e
|
|
; f
|
|
; g
|
|
; h(int)
|
|
; i(int).
|
|
|
|
:- pred q(t::in, int::out) is det.
|
|
|
|
:- type u
|
|
---> u1
|
|
; u2
|
|
; u3(t)
|
|
; u4(t).
|
|
|
|
:- pred r(u::in, int::out) is det.
|
|
:- pred s(u::in, int::out) is det.
|
|
:- pred t(int::out) is det.
|
|
|
|
:- implementation.
|
|
:- import_module int.
|
|
:- import_module require.
|
|
|
|
p1(42).
|
|
p2(X) :- X = 42.
|
|
p3(X) :- X = 42.
|
|
p4(X) :- X = 21 + 21.
|
|
p5(_) :- true.
|
|
|
|
q(a, 1).
|
|
q(b, 2).
|
|
q(c, 3).
|
|
|
|
r(U, X) :-
|
|
(
|
|
U = u1,
|
|
X = 11
|
|
;
|
|
U = u3(a),
|
|
X = 31
|
|
;
|
|
U = u3(b),
|
|
X = 32
|
|
;
|
|
U = u3(c),
|
|
X = 33
|
|
;
|
|
U = u4(a),
|
|
X = 41
|
|
;
|
|
U = u4(b),
|
|
X = 42
|
|
;
|
|
U = u4(c),
|
|
X = 43
|
|
;
|
|
U = u4(d),
|
|
X = 441
|
|
;
|
|
U = u4(d),
|
|
X = 442
|
|
;
|
|
U = u4(e),
|
|
X = 45
|
|
;
|
|
U = u4(f),
|
|
X = 46
|
|
;
|
|
U = u4(g),
|
|
X = 47
|
|
).
|
|
|
|
s(U, X) :-
|
|
(
|
|
U = u1,
|
|
X = 11
|
|
;
|
|
U = u3(a),
|
|
X = 31
|
|
;
|
|
U = u3(b),
|
|
X = 32
|
|
;
|
|
U = u3(c),
|
|
X = 33
|
|
;
|
|
U = u4(V),
|
|
(
|
|
V = a,
|
|
X = 41
|
|
;
|
|
V = b,
|
|
X = 42
|
|
;
|
|
V = c,
|
|
X = 43
|
|
;
|
|
V = d,
|
|
X = 441
|
|
;
|
|
V = d,
|
|
X = 442
|
|
;
|
|
( V = e
|
|
; V = f
|
|
),
|
|
( X = 461
|
|
; X = 462
|
|
)
|
|
;
|
|
V = g,
|
|
X = 47
|
|
;
|
|
( V = h(_)
|
|
; V = i(_)
|
|
),
|
|
( X = 481
|
|
; X = 482
|
|
)
|
|
)
|
|
).
|
|
|
|
:- pragma no_determinism_warning(t/1).
|
|
|
|
t(_) :-
|
|
error("t called").
|