Files
mercury/tests/invalid/det_errors.m
Zoltan Somogyi 7f39b321b2 Improve the compiler's ability to deal with determinism errors, in three ways.
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.
2011-04-08 07:25:55 +00:00

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").