You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Avoid inference getting stuck when the expected type contains a union/intersection
When we type a method call, we infer constraints based on its expected
type before typing its arguments. This way, we can type these arguments
with a precise expected type. This works fine as long as the constraints
we infer based on the expected type are _necessary_ constraints, but in
general type inference can go further and infer _sufficient_
constraints, meaning that we might get stuck with a set of constraints
which does not allow the method arguments to be typed at all.
Since 8067b95 we work around the
problem by simply not propagating any constraint when the expected type
is a union, but this solution is incomplete:
- It only handles unions at the top-level, but the same problem can
happen with unions in any covariant position (method b of or-inf.scala)
as well as intersections in contravariant positions (and-inf.scala,
i8378.scala)
- Even when a union appear at the top-level, there might be constraints
we can propagate, for example if only one branch can possibly match
(method c of or-inf.scala)
Thankfully, we already have a solution that works for all these
problems: `TypeComparer#either` is capable of inferring only necessary
constraints. So far, this was only done when inferring GADT bounds to
preserve soundness, this commit extends this to use the same logic when
constraining a method based on its expected type (as determined by the
ConstrainResult mode). Additionally, `ConstraintHandling#addConstraint`
needs to also be taught to only keep necessary constraints under this
mode.
Fixes#8378 which I previously thought was unfixable :).
0 commit comments