Description
The language specification says that
Let
i
be a property extraction expression of the forme?.id
,
e.id
, orsuper.id
, which is statically resolved to denote an instance
method namedid
, and letG
be the static type ofi
. Consider the
situation whereG
is a function type of the form
T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)
withs > 0
(that is,G
is
a generic function type), and the context type is a non-generic function
typeF
. In this situation a compile-time error occurs, except when generic
function type instantiation succeeds, that is:Type inference is applied to
G
with context typeF
, and it succeeds,
yielding the actual type argument listT1, ..., Ts
.
However, we have a somewhat peculiar behavior in a case where the instantiation fails to produce a function whose type is assignable to the given context type:
List<X> f<X>(X x) => [x];
void main() {
Object o = (int i) => i;
if (o is int Function(int)) {
o = f; // Demotes `o`.
o.est<E<Object>>(); // Confirms that `o` has static type `Object`.
print(o.runtimeType); // '(dynamic) => List<dynamic>', i.e., `f` _was_ instantiated.
}
}
typedef E<X> = X Function(X);
extension<X> on X {
X est<Y extends E<X>>() => this;
}
It could be claimed that the generic function instantiation that implicitly turns f
into f<dynamic>
isn't useful (or meaningful), and perhaps it shouldn't have been performed. However, this does match the specified behavior.
We could consider whether we'd want to say that the generic function instantiation should only take place if the resulting function type is assignable to the context type.
This doesn't matter in the typical case because neither the original generic type nor the instantiated non-generic type is assignable to the context type, which means that it is typically a compile-time error, but in the case where the context type is "not mandatory" it does matter, and it will change the behavior of program executions.
We don't have a matching context type and hence the instantiation will most likely use dynamic
as the actual type arguments. This may be useful, but most likely it will be less safe, confusing, and not even useful. Hence, I'd recommend that we specify that this generic function instantiation should not be performed after all.