Files
mercury/tests/invalid/mode_error_arg_number.m
Zoltan Somogyi 2028df3f20 Fix references to func results in a mode error.
compiler/mode_errors.m:
    If the argument whose instantiation we are complaining about is
    the result of a function, say so.

tests/invalid/mode_error_arg_number.{m,err_exp}:
    Add a test of this message.

tests/invalid/bug117.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/html.err_exp:
tests/invalid/inst_matches_final_bug.err_exp:
    Expect the correct reference to function results in these test cases.
2022-10-01 13:06:20 +10:00

62 lines
2.1 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% This code is from a bug report in m-users on 2022 sep 23.
%---------------------------------------------------------------------------%
:- module mode_error_arg_number.
:- interface.
:- import_module list.
:- pred split_into_fragments(
pred(list(P), list(P), list(P))::
pred(in(non_empty_list), out(non_empty_list), out) is det,
list(P)::in(non_empty_list),
list(list(P))::in, list(list(P))::out(non_empty_list)) is det.
:- func split_into_fragments_func(
pred(list(P), list(P), list(P))::
pred(in(non_empty_list), out(non_empty_list), out) is det,
list(P)::in(non_empty_list),
list(list(P))::in) = (list(list(P))::out(non_empty_list)) is det.
:- implementation.
split_into_fragments(Pred, Paras @ [_ | _], Akku, Frags) :-
Pred(Paras, Frag, Rest),
append(Akku, [Frag], Akku1),
(
Rest = [],
Frags = Akku1
;
Rest = [_ | _],
% The following call used to get an error message about
% argument five not getting sufficiently instantiated, even though
% it has only four arguments. The problem was that the code generating
% the error message was counting compiler-visible arguments, which
% include the type_info argument for P added by polymorphism, when
% it should have been counting only the user-visible arguments.
split_into_fragments(Pred, Rest, Akku1, Frags)
).
split_into_fragments_func(Pred, Paras @ [_ | _], Akku) = Frags :-
Pred(Paras, Frag, Rest),
append(Akku, [Frag], Akku1),
(
Rest = [],
Frags = Akku1
;
Rest = [_ | _],
% Test whether, when we report the mode error, the compiler
% refers to "argument 4" or "function result".
Frags = split_into_fragments_func(Pred, Rest, Akku1)
).
:- pred append1(list(T), list(T), list(T)).
:- mode append1(in(I), in(non_empty_list), out(non_empty_list)) is det.
append1([], Ys, Ys).
append1([X | Xs], Ys, [X | Zs]) :-
append1(Xs, Ys, Zs).