[m-rev.] for review: fix compiler abort after unresolved overloading

Julien Fischer jfischer at opturion.com
Sun Aug 21 13:59:49 AEST 2022



On Sun, 21 Aug 2022, Zoltan Somogyi wrote:

> This bug fix is relatively straighforward. The part most worth
> looking at are the error message and the additions to list.m.
> If anyone has better names for the new predicates there, speak up.
> I will add a blurb the NEWS about them once we have settled
> on a name.


> Don't abort compilation for unresolved overloading.

...

> diff --git a/compiler/pred_table.m b/compiler/pred_table.m

...

> @@ -1171,9 +1174,71 @@ resolve_pred_overloading(ModuleInfo, CallerMarkers, TVarSet, ExistQTVars,
>
>  %---------------------------------------------------------------------------%
> 
> -find_matching_pred_id(ModuleInfo, [PredId | PredIds], TVarSet, ExistQTVars,
> +find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ExistQTVars,
>          ArgTypes, ExternalTypeParams, MaybeConstraintSearch, Context,
> -        ThePredId, PredName) :-
> +        ThePredId, ThePredSymName, Specs) :-
> +    find_matching_pred_ids(ModuleInfo, TVarSet, ExistQTVars,
> +        ArgTypes, ExternalTypeParams, MaybeConstraintSearch, Context,
> +        PredIds, MatchingPredIdsInfos),
> +    (
> +        MatchingPredIdsInfos = [],
> +        fail
> +    ;
> +        MatchingPredIdsInfos =
> +            [ThePredId - ThePredInfo | TailMatchingPredIdsInfos],
> +        % We have found a matching predicate.
> +        pred_info_get_sym_name(ThePredInfo, ThePredSymName),
> +        % Was there was more than one matching predicate/function?
> +        (
> +            TailMatchingPredIdsInfos = [],
> +            Specs = []
> +        ;
> +            TailMatchingPredIdsInfos = [_ | _],
> +            GetPredDesc =
> +                ( func(_ - PI) = Piece :-
> +                    pred_info_get_pf_sym_name_arity(PI, PFSNA),
> +                    Piece = qual_pf_sym_name_orig_arity(PFSNA)
> +                ),
> +            PredDescPieces = list.map(GetPredDesc, MatchingPredIdsInfos),
> +            add_sep_separators([suffix(","), nl],
> +                [suffix(","), words("and"), nl], PredDescPieces,
> +                PredDescSepPieces),
> +            Pieces = [words("Error: unresolved predicate overloading."), nl,
> +                words("The matches are"), nl_indent_delta(1)] ++
> +                PredDescSepPieces ++ [suffix("."), nl_indent_delta(-1),
> +                words("You need to use an explicit module qualifier"),
> +                words("to select the one you intend to refer to."), nl,
> +                words("Proceeding on the assumption that"),
> +                words("the intended match is the first."),
> +                words("If this assumption is incorrect, other error messages"),
> +                words("may be reported for this predicate or function"),
> +                words("solely because of this wrong assumption."), nl],
> +            % In the frequent case (for us, at least) where the ambiguity
> +            % is caused by moving a predicate from one module of the standard

     standard _library_

> +            % to another but leaving a forwarding predicate behind,
> +            % the choices will be equivalent, and there will be *no* avalanche
> +            % errors caused by our assumption. However, it is better to warn
> +            % about avalanche errors that won't happen than to not warn
> +            % about avalanche errors that *do* happen.
> +            Spec = simplest_spec($pred, severity_error, phase_type_check,
> +                Context, Pieces),
> +            Specs = [Spec]
> +        )
> +    ).

...

> diff --git a/library/list.m b/library/list.m
> index 5942c6c30..69a029de1 100644
> --- a/library/list.m
> +++ b/library/list.m
> @@ -585,6 +585,42 @@
>      %
>  :- pred det_split_last(list(T)::in, list(T)::out, T::out) is det.
> 
> +    % add_separator(Sep, List, ListWithSep):
> +    %
> +    % Insert Sep between each pair of elements in List, and return
> +    % the result as ListWithSep.
> +    %
> +    % For example, add_separator("and", ["jan", "feb", "mar"], ListWithSep)
> +    % will bind ListWithSep to ["jan", "and", "feb", "and", "mar"].
> +    %
> +:- pred add_separator(T::in, list(T)::in, list(T)::out) is det.
> +
> +    % add_separators(Seps, List, ListWithSeps):
> +    %
> +    % Insert Seps between each pair of elements in List, and return
> +    % the result as ListWithSeps.
> +    %
> +    % For example, add_separators(["and", "then"], ["jan", "feb", "mar"],
> +    % ListWithSeps) will bind ListWithSeps to
> +    % ["jan", "and", "then", "feb", "and", "then", "mar"].
> +    %
> +:- pred add_separators(list(T)::in, list(T)::in, list(T)::out) is det.
> +
> +    % add_sep_separators(NonLastSeps, LastSeps, List, ListWithSeps):
> +    %
> +    % Insert NonLastSeps between each pair of elements in List except
> +    % the last pair, insert LastSeps between the last pair of elements,
> +    % and return the result as ListWithSeps. The middle "sep" in the name
> +    % is for the fact that are separate separators with non-last and last
> +    % pairs of elements.
> +    %
> +    % For example, add_separators(["and", "then"], ["and", "finally"],
> +    % ["jan", "feb", "mar"], ListWithSeps) will bind ListWithSeps to
> +    % ["jan", "and", "then", "feb", "and", "finaly", "mar"].
> +    %
> +:- pred add_sep_separators(list(T)::in, list(T)::in, list(T)::in,
> +    list(T)::out) is det.

Some alterantive suggestions for the names of these new predicates:

     interleave
     interleave_list
     interleave_list_last

or:

     add_between
     add_between_list
     add_between_list_last

My own preference would be the the interleave* naming.

The diff looks fine otherwise.

Julien.


More information about the reviews mailing list