Files
mercury/tests/invalid/currying_multimode_func.m
Zoltan Somogyi 72fdbec2fd Improve diagnostics for currying multi-mode predicates.
The improvements take two forms.

The first is that when the mode checker tries to schedule a unification
of the form X = curried_pred(A1, ... An), but fails, perhaps because
curried_pred has more than one declared mode matching the current insts
of the Ai, we record this fact in the mode_info. Then, if later we find
that X is insufficiently instantiated, we print the message we originally
generated for the X = curried_pred(A1, ... An) unification (but which we
threw away when the scheduling attempt failed) as a possible explanation
of this insufficient instantiation.

The second is that when scheduling X = curried_pred(A1, ... An) but fails,
we record more information about the reason, to print it later in the hope that
it may help the user diagnose the problem.

compiler/mode_errors.m:
    Change the representation of the errors resulting for not being able
    to schedule rhs_lambda unifications of the form X = curried_pred(Ai).
    Merge the previous two separate errors into one, and add a parameter
    that that distinguishes the three (not two) possible different causes
    of the error. Print better diagnostics for all three, based on a common
    template.

    Change the representation of the errors that say a variable is not
    sufficiently instantiated, to make it possible (but of course not
    compulsory) to record what error of the X = curried_pred(Ai) kind
    may be responsible for it. Include the error message for this cause
    in the error message about the insufficiently instantiated variable.

compiler/mode_info.m:
    Add a field to the mode_info that allows a failed attempt to schedule
    X = curried_pred(Ai) to record the error it generates as a possible
    cause of the later insufficient instantiation of X.

compiler/modecheck_unify.m:
    Gather the extra information now needed by the representation of mode
    errors for failed attempts to schedule X = curried_pred(Ai).
    Record the errors for such attempts in the new mode_info field.

compiler/modecheck_util.m:
    When generating "variable is not sufficiently instantiated" errors,
    see if the new mode_info field say that the insufficiently instantiated
    variable was, in a previous conjunct, involved in a failed
    X = curried_pred(Ai) unification, and if yes, record this fact
    as a possible cause of the error.

compiler/modecheck_goal.m:
    Reset the new field at the start of every branched control structure,
    to prevent us from using information about X = curried_pred(Ai)
    unifications in one branch in other, parallel branches.

    Avoid allocating a context at every goal.

library/term.m:
    Add a utility predicate to enable that avoidance.

NEWS:
    Mention the new utility predicate.

    Fix some no-longer-valid entries.

compiler/modecheck_call.m:
    Make some code need less stack space.

    Fix some comments.

compiler/modecheck_conj.m:
    Clarify some code.

tests/invalid/uint_bitwise_xor_mode.{m,err_exp}:
    A new test case for both improvements. It is a version of
    tests/hard_coded/uint_bitwise.m cut down to contain just the bug
    that previously we generate only a misleading error message for.

tests/invalid/Mmakefile:
    Enable the new test.

tests/invalid/multimode_addr_problems.err_exp:
    Update this expected output to account for the second improvement.
2017-06-08 14:52:46 +02:00

33 lines
1016 B
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
:- module currying_multimode_func.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module uint.
%---------------------------------------------------------------------------%
main(!IO) :-
run_binop_test(uint.(xor), !IO).
%---------------------------------------------------------------------------%
:- pred run_binop_test((func(uint, uint) = uint)::in, io::di, io::uo) is det.
run_binop_test(_BinOpFunc, !IO).
%---------------------------------------------------------------------------%
:- end_module currying_multimode_func.
%---------------------------------------------------------------------------%