[m-rev.] for review: symmetric coerce_fails for unrelated du types
Peter Wang
novalazy at gmail.com
Tue Aug 4 15:29:17 AEST 2026
On Tue, 04 Aug 2026 01:59:37 +0200 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> For review by Peter. Note: this diff is what I wanted those two
> questions answered for.
>
> Zoltan.
> Use {must_be,need_not_be}_invariant comparisons.
>
> compiler/typecheck_coerce.m:
> Stop trying to check both FromType =< ToType and ToType =< FromType.
> Instead, compare them just once,
>
> To make this work, when comparing two du types, don't try to lift
> just one type towards its base type; lift *both*.
>
> Add an XXX about a possible improvement.
>
> compiler/type_assign.m:
> Change the representation of the failure of comparing two du types
> to reflect the now-symmetric nature of the failure.
>
> compiler/typecheck_errors.m:
> Generate a symmetric message for this new symmetric failure.
>
> Since we no longer generate the repeated-in-mirror-image-form
> coerce_fails involving at least one non-du type, stop trying
> to get rid of them.
>
> Fix a typo in a the diagnostic for a (so far untested) coerce_fail.
>
> tests/invalid/coerce_type_error.err_exp:
> Expect the new symmetric diagnostic for unrelated-by-subtyping
> du types.
> diff --git a/compiler/typecheck_coerce.m b/compiler/typecheck_coerce.m
> index cca6377c4..62b0c9582 100644
> --- a/compiler/typecheck_coerce.m
> +++ b/compiler/typecheck_coerce.m
> du_types_compare_as_given(TypeTable, TVarSet, BaseTypeCtor, ArgNum, Comparison,
> - TypeA, TypeCtorA, ArgTypesA, DuTypeInfoA,
> - TypeB, _TypeCtorB, _ArgTypesB, _DuTypeInfoB,
> + TypeA, DuTypeInfoA, TypeB, DuTypeInfoB,
> !TypeAssign, !CoerceFails) :-
> (
> - Comparison = compare_equal(Reason),
> - CoerceFail = should_be_invariant_arg(BaseTypeCtor,
> - ArgNum, Reason, TypeA, TypeB),
> + Comparison = must_be_invariant(Reason),
> + % Even if TypeA and/or TypeB contain type variables,
> + % no possible types being bound to those variables
> + % can fix the mismatch between TypeCtorA amd TypeCtorB.
and
> + CoerceFail = should_be_invariant_arg(BaseTypeCtor, ArgNum,
> + Reason, TypeA, TypeB),
> !:CoerceFails = [CoerceFail | !.CoerceFails]
> ;
> - Comparison = compare_equal_lt,
> - DuTypeInfoA = du_type_info(_, _, TypeDefnA, TypeBodyDuA),
> - MaybeSuperTypeA = TypeBodyDuA ^ du_type_supertype,
> - (
> - MaybeSuperTypeA = subtype_of(SuperTypeA0),
> - get_supertype_of_subtype(TVarSet,
> - TypeCtorA, ArgTypesA, TypeDefnA,
> - SuperTypeA0, SuperTypeA),
> - types_compare_as_given(TypeTable, TVarSet,
> + Comparison = need_not_be_invariant,
> + % XXX If TypeA and TypeB have a common "ancestor" that is
> + % NOT their common supertype, we could use the nearest
> + % such common ancestor instead of the base type.
> + % This would allow us to check the coercability of
> + % any phantom type parameters that don't make it
> + % all the way up to the common base type.
(If we decide we want to allow that after all.)
That looks fine.
Peter
More information about the reviews
mailing list