Files
mercury/tests/invalid/bind_var_errors.err_exp
Zoltan Somogyi 0c162fb50e Improve diagnostics for higher-order mode errors.
In case of a problem with an argument of a higher order call,
we used to generate diagnostics containing text such as

    in argument 2 (i.e. argument 1 of the called function)
    of impure higher-order function call:

This clumsy construction was needed because the HLDS did not contain
enough info. Specifically, it did not specify whether in the source code,
the higher order call was written as e.g. call(P, A, B, C) or as P(A, B, C).
If the former, then then a problem with e.g. A occurs in argument 2
of the call to the 'call' builtin; if the latter, then it occurs
in argument 1 of the call to 'P'.

This diff fixes that. It adds to the HLDS representation of higher order
calls a record of the original form of the call in the source code

compiler/hlds_goal.m:
    Add this field, the higher_order_syntax field, to the representation
    of higher order calls.

compiler/goal_expr_to_goal.m:
    Fill the higher_order_syntax field for higher order predicate calls.

compiler/resolve_unify_functor.m:
    Fill the higher_order_syntax field for higher order function calls.

compiler/hlds_pred.m:
    Change the representation of generic calls in call_ids, which we use
    to identify callees for diagnostics, to include both the variable
    specifying the callee in higher order calls (by changing from a
    generic_call_id to the generic_call from which it would be derived
    by throwing out that info), and the var_name_source needed to
    look up its name.

compiler/hlds_out_util.m:
    Use the new higher_order_syntax field to generate text that

    - identifies the higher order call as using either call(P, A, B, C)
      syntax or P(A, B, C) syntax, and likewise for function, and

    - specifies the exact argument number (which will depend on the above
      distinction).

    This should result in more easily understandable diagnostics.

    Add a version of this predicate that generates text that specifically
    describes the higher order callee, not the higher order call as a whole.

    Add an option to suppress the printing of variable names.
    We use this to *not* refer to e.g. "the predicate P" when reporting
    an error about P actually being a function, not a predicate.

compiler/mode_info.m:
    Rename mode_context_call to mode_context_call_arg, because
    the context it describes is one argument of a call.

    Add a new mode context, mode_context_call, which now describes
    a call as a whole.

compiler/mode_errors.m:
    Use the new facilies described above to generate better diagnostics
    for higher order calls.

compiler/modecheck_util.m:
    Document the reason why we handle argument numbers for higher order calls
    the way we do.

    When generating an error that relates the whole of a higher order call,
    use the new mechanism in mode_info.m to record the fact that the error
    is not specific to any one argument of the call. Not doing this would
    include the argument number in the context of the error, which would be
    misleading.

    Add a utility function that is needed by more than one module below.

compiler/*.m:
    Conform to the changes above.

tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/bind_var_errors.err_exp:
tests/invalid/constrained_poly_insts_2.err_exp:
tests/invalid/det_errors_cc.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/functor_ho_inst_bad_2.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_any_inst.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/ho_unique_error.err_exp:
tests/invalid/mode_error_arg_number_ho.err_exp:
tests/invalid/no_ho_inst.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid_purity/impure_func_t5_fixed.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense_1.err_exp:
tests/invalid_purity/purity_nonsense_2.err_exp:
    Expect updated error messages.
2024-11-01 13:56:55 +11:00

2.0 KiB

bind_var_errors.m:035: In clause for `bind_var_in_negation':
bind_var_errors.m:035: scope error: attempt to bind a non-local variable
bind_var_errors.m:035: inside a negation.
bind_var_errors.m:035: Variable `X' has instantiatedness `free',
bind_var_errors.m:035: expected instantiatedness was `unique(42)'.
bind_var_errors.m:041: In clause for `bind_var_in_ite_cond(in)':
bind_var_errors.m:041: scope error: attempt to bind a non-local variable
bind_var_errors.m:041: inside the condition of an if-then-else.
bind_var_errors.m:041: Variable `Y' has instantiatedness `free',
bind_var_errors.m:041: expected instantiatedness was `unique(42)'.
bind_var_errors.m:050: In clause for `bind_var_in_lambda':
bind_var_errors.m:050: in argument 1 of the call to the `call' builtin
bind_var_errors.m:050: predicate:
bind_var_errors.m:050: mode error: variable `Y' has instantiatedness `free',
bind_var_errors.m:050: expected instantiatedness for non-local variables of
bind_var_errors.m:050: lambda goals is `ground'.
bind_var_errors.m:055: In clause for `share_var_in_lambda(di)':
bind_var_errors.m:055: in argument 1 of call to predicate
bind_var_errors.m:055: `bind_var_errors.destroy'/1:
bind_var_errors.m:055: mode error: variable `X' has instantiatedness
bind_var_errors.m:055: `ground',
bind_var_errors.m:055: expected instantiatedness was `unique'.
bind_var_errors.m:062: In clause for `clobber_var_in_lambda(di)':
bind_var_errors.m:062: in argument 1 of call to predicate
bind_var_errors.m:062: `bind_var_errors.destroy'/1:
bind_var_errors.m:062: unique-mode error: the called procedure would clobber
bind_var_errors.m:062: its argument, but variable `X' is still live.
For more information, recompile with `-E'.