Use bottom-up type inference for invocations of generic functions with non-covariant parameter types #3212
Labels
small-feature
A small feature which is relatively cheap to implement.
type-inference
Type inference, issues or improvements
See dart-lang/sdk#52850 for background information, including a detailed analysis from @stereotype441.
Consider the following example:
This library causes a compile-time error to be reported at
f(d)
, but there is no error if we usef<W>(d)
.The context type
List<Object?>
is used during downwards inference to choose the type argument passed tof
, so we make itf<Object?>(d)
before we even consider whether that choice of type argument makesd
a type correct actual argument.This normally fine: The context type is usually an upper bound (so if we can't use an actual type argument
A
which is taken from the context type, or a subtype ofA
, then the entire expression is a type error). Conversely, if we could have used a subtype of the type from the context then it is usually no problem that we use a subtype.The reason for this is that most parameter types are covariant in the type parameters of the enclosing generic function. In other words, if
f<T>(d)
is type correct andT <: S
thenf<S>(d)
is also type correct. Based on the context type, we'd choose the most general type which is allowed by the context, which is again the type that allows for the greatest possible set of types for the actual arguments.However, in this particular case we can't use a supertype, because the type parameter
U
occurs both covariantly and contravariantly in the parameter type off
. So when we chooseObject?
as the actual type argument passed tof
in the body ofg
, the corresponding instantiated parameter type off
isObject? Function(Object?)
, and that's unrelated to the type ofd
which isW Function(W)
, and hence we get a type error (or a type inference failure).I think we might want to use the current approach (based on the context type whenever possible) in all cases where we are inferring actual type arguments for a generic function invocation where the parameter types are covariant in all type parameters, but in the case where some parameter types are non-covariant in some type parameters we could use bottom-up inference.
The text was updated successfully, but these errors were encountered: