Files
mercury/tests/invalid/coerce_mode_error2.m
Peter Wang 233874403f Improve coerce mode error messages.
compiler/mode_errors.m:
    Replace the two existing options for coerce mode errors with one
    that includes:
    - the path to the input subterm where the error was detected
    - the type of the input subterm
    - the target type that the subterm should be converted to
    - the reason for the error

compiler/modecheck_coerce.m:
    Modify the code to produce the above information.
    Semidet predicates that previously failed when an error is detected
    are changed to det predicates that return the error information.

    In a couple of places where predicates previously would fail,
    we now abort because the conditions should not occur.

compiler/hlds_out_util.m:
    Describe coerce as "coerce expression" (shows up in mode errors).

tests/invalid/Mmakefile:
tests/invalid/coerce_mode_error2.err_exp:
tests/invalid/coerce_mode_error2.m:
    Add test case.

tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_recursive_inst.err_exp:
tests/invalid/coerce_recursive_type.err_exp:
tests/invalid/coerce_unreachable.err_exp:
    Update expected error messages.
2021-05-17 12:55:58 +10:00

53 lines
1.2 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module coerce_mode_error2.
:- interface.
:- type fruit
---> apple
; orange
; lemon
; banana.
:- type citrus =< fruit
---> orange
; lemon.
:- type foo(T)
---> nil
; foo(int, T).
:- type foo_citrus =< foo(citrus)
---> foo(int, citrus).
%---------------------------------------------------------------------------%
:- implementation.
:- pred test1(foo_citrus::out) is multi.
test1(Y) :-
(
X = foo(1, apple) % apple cannot be converted
;
X = foo(2, banana) % banana cannot be converted
;
X = foo(3, orange)
),
Y = coerce(X).
:- pred test2(foo_citrus::out) is multi.
test2(Y) :-
(
X = foo(1, apple) % apple cannot be converted
;
X = nil % nil cannot be converted either
% and will be reported preferentially
),
Y = coerce(X).
%---------------------------------------------------------------------------%