dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.04k stars 1.55k forks source link

Surprising type inference failure #55307

Open eernstg opened 4 months ago

eernstg commented 4 months ago

Consider the following program:

void f<X>(List<X> xs, X Function(X) g) {}
void main() => f([], (int i) => i);

Both the analyzer and the CFE reject this program, reporting that "X couldn't be inferred" respectively "'int Function(int)' can't be assigned to the parameter type 'dynamic Function(dynamic)'".

The horizontal inference rules do not give rise to any separation of the actual arguments into phases, so I'd expect the declared parameter type int as well as the return type int of the second argument to suffice to conclude that X must be int.

chloestefantsova commented 4 months ago

As we discussed offline, the problem seems to arise from the inference having to separate sets of constraints: one for X, the type variable of f, and E, the type variable of the list literal <E>[]. Solving for E happens first, yielding E = dynamic in the absence of type information, and then List<dynamic> informs the inference on X from the constraint List<dynamic> <: List<X>.

A possible solution for this situation is to allow joined constraint sets for the nested expressions.