[m-rev.] for review: check bound insts in coerce ops more systematically

Peter Wang novalazy at gmail.com
Thu May 30 15:53:09 AEST 2024


On Wed, 29 May 2024 18:17:10 +1000 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> Report coerce inst errors more systematically.
> 
> compiler/modecheck_coerce.m:
>     When checking the bound_insts occurring in the initial inst of the
>     coerced term, use the same mechanism to handle
>     
>     - any cons_ids they contain that do not occur in the input type,
>     - any cons_ids they contain that do occur in the input type but are
>       used in the bound_inst with the wrong arity, and
>     - any cons_ids they contain that do not occur in the result type.
> 
>     The new mechanism allows us to catch any combination of these kinds
>     of errors in the same list of bound insts. The old mechanism could not
>     do this, partially because it only ever tried collect at most one
>     error of some of the above kinds.
> 
>     Use more standard variable names.
> 
> compiler/mode_errors.m:
>     Change the representation of coerce mode errors to accommodate
>     the new capability in modecheck_coerce.m, and change the code
>     that reports such mode errors accordingly.
> 
> tests/invalid/coerce_int.m:
>     Make this case just a bit tougher.
> 
> tests/invalid/coerce_int.err_exp:
> tests/invalid/coerce_mode_error2.err_exp:
> tests/invalid/coerce_recursive_type.err_exp:
>     Expect updated diagnostics.

> diff --git a/compiler/mode_errors.m b/compiler/mode_errors.m
> index 2bbe89cd2..8f97c924b 100644
> --- a/compiler/mode_errors.m
> +++ b/compiler/mode_errors.m
> @@ -314,17 +314,28 @@
>  
>  :- type coerce_error_reason
>      --->    input_inst_not_ground(mer_inst)
> -    ;       invalid_inst_for_input_type(mer_inst)
> -    ;       invalid_cons_ids_for_result_type(list(cons_id))
> +    ;       cons_id_errors(mer_inst,
> +                bound_inst_cons_id_error, list(bound_inst_cons_id_error))
>      ;       has_inst_expect_upcast(mer_inst).
>  
> +:- type bound_inst_cons_id_error
> +    --->    bad_cons_id_input(cons_id)
> +            % The cons_id does not exists in the input type.

does not exist

> +    ;       bad_cons_id_input_inst_arity(cons_id, arity, arity)
> +            % The cons_id exists in the input type, but the inst specifies
> +            % the wrong arity for it. XXX How?
> +            % The cons_id, its arity in the inst of X, and the expected arity.

I wasn't able to (quickly) construct a test case which triggers this
error.

I may have just have put that arity check in
modecheck_coerce_from_bound_make_bound_functor out of caution,
since as the comment says:

    % The user may have provided an inst that does not make sense for the type.
    % The compiler does not check for that elsewhere (probably it should)
    % so we try to be careful about that here.

You may want to merge bad_cons_id_input_inst_arity into
bad_cons_id_input.

> +    ;       bad_cons_id_result(cons_id).
> +            % The cons_id does not exists in the result type.

does not exist

> diff --git a/compiler/modecheck_coerce.m b/compiler/modecheck_coerce.m
> index 5b21b1b05..524dffed8 100644
> --- a/compiler/modecheck_coerce.m
> +++ b/compiler/modecheck_coerce.m
...
> @@ -354,14 +354,15 @@ is_user_inst(InstName) :-
>      list(bound_inst)::in, maybe_coerce_error(mer_inst)::out) is det.
>  
>  modecheck_coerce_from_bound_make_bound_inst(ModuleInfo, TVarSet, LiveX, UniqX,
> -        RevTermPath0, TypeX, TypeY, ExpandedInsts0, InstX, FunctorsX, Res) :-
> +        RevTermPath0, TypeX, TypeY, ExpandedInsts0, InstX, BoundInstsX,
> +        Result) :-
>      modecheck_coerce_from_bound_make_bound_functors(ModuleInfo, TVarSet, LiveX,
> -        RevTermPath0, TypeX, TypeY, ExpandedInsts0, InstX,
> -        FunctorsX, FunctorsY, BadConsIds, no, MaybeError0),
> +        RevTermPath0, TypeX, TypeY, ExpandedInsts0, BoundInstsX, BoundInstsY,
> +        BadConsIdErrors, [], DeeperErrors),
>      (
> -        BadConsIds = [],
> +        BadConsIdErrors = [],
>          (
> -            MaybeError0 = no,
> +            DeeperErrors = [],
>              UniqY = uniqueness_for_coerce_result(LiveX, UniqX),
>              % XXX A better approximation of InstResults is probably possible.
>              InstResults = inst_test_results(
> @@ -372,75 +373,76 @@ modecheck_coerce_from_bound_make_bound_inst(ModuleInfo, TVarSet, LiveX, UniqX,
>                  inst_result_contains_types_unknown,
>                  inst_result_no_type_ctor_propagated
>              ),
> -            InstY = bound(UniqY, InstResults, FunctorsY),
> -            Res = ok(InstY)
> +            InstY = bound(UniqY, InstResults, BoundInstsY),
> +            Result = ok1(InstY)
>          ;
> -            MaybeError0 = yes(Error),
> -            Res = coerce_error(Error)
> +            DeeperErrors = [_ | _],
> +            Result = error1(DeeperErrors)
>          )
>      ;
> -        BadConsIds = [_ | _],
> +        BadConsIdErrors = [HeadBadConsIdError | TailBadConsIdErrors],
>          % This will prefer to report any invalid functors in the current
>          % `bound()' inst over an error found deeper in the inst tree
>          % (in MaybeError0).

Update or delete this comment (MaybeError0 to DeeperErrors).

>          list.reverse(RevTermPath0, TermPath),
> -        Reason = invalid_cons_ids_for_result_type(BadConsIds),
> -        Error = coerce_error(TermPath, TypeX, TypeY, Reason),
> -        Res = coerce_error(Error)
> +        Reason = cons_id_errors(InstX,
> +            HeadBadConsIdError, TailBadConsIdErrors),
> +        ConsIdError = coerce_error(TermPath, TypeX, TypeY, Reason),
> +        Result = error1([ConsIdError | DeeperErrors])
>      ).
>  

That looks fine.

Peter


More information about the reviews mailing list