Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marginally better LUB for different instantiations of the same interface. #4204

Open
lrhn opened this issue Dec 12, 2024 · 0 comments
Open
Labels
feature Proposed language feature that solves one or more problems inference

Comments

@lrhn
Copy link
Member

lrhn commented Dec 12, 2024

Currently Up(T1, T2) recognizes if T1 is C<S1,..,Sn> and T2 is C<R1,...,Rn>, with some Si != Ri, and tries to unify the type parameters.
However if T1 implements C<S1,...,Sn> and T2 implements C<R1,...,Rn>, then we may fall through to the old depth-based LUB algorithm, which only looks at common types between the two types, and C<S1,...,Sn> is a different type than C<R1,...,Rn>, so neither gets included in the comparison.

I suggest that we reconsider that approach. When looking for common supertypes, we'll find C1<S1,...,Sn> and C1<R1,...,Rn> has the same depth, but are not equal. We should then realize that they are related, and if one is a supertype of the other (and not vice versa), then we do include the supertype in the set of common supertypes. (It can still fail to be the LUB if there are other candidates at that depth. Which means that this change may break existing code that relied on another supertype of the same depth being the only one.)

That is, in the step where we collect all common superinterface of two types and group them by depth, and then intersect the sets, the intersection should not just do "same type" checks, but retain an interface if the other set contains an instantiation of the same generic interface with an instantiation that is a proper subtype.

Concretely I'm trying to add a type parameter to Pattern, so that Pattern<M extends Match> has methods returning M, and then RegExp implements Pattern<RegExpMatch>.
My problem is that ["a", RegExp("b")] used to be inferred as List<Pattern>, but with the type parameter, it is inferred as List<Object> because Pattern<Match> and Pattern<RegExpMatch> are considered completely unrelated.

(We can probably do much better if we built a LUB from scratch, but this particular change seems within reach and still able to do something good in some cases.)

@stereotype441

@lrhn lrhn added feature Proposed language feature that solves one or more problems inference labels Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems inference
Projects
None yet
Development

No branches or pull requests

1 participant