-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
bad type inference #40856
Comments
Dart type inference does not work by general constraint solving. It uses an algorithm where context type information, if available, is pushed down into expressions, then the types of sub-expressions are combined to find type of the expression itself. This case is equivalent to: T max<T>(Iterable<T> items, Comparator<T> compare) => null;
FutureOr<A> returnValue = max([A()], (a1, a2) => a1.x - a2.x); The type inference pushes the ... = max<FutureOr<A>>(<FutureOr<A>>[A()], (FutureOr<A> a1, FutureOr<A> s2) => a1.x - a2.x)); Since The reason that var m = max([A()], (a1, a2) => a1.x - a2.x);
return a ?? m; works is that it infers dynamic m = max<dynamic>(<A>[A()], (dynamic a1, dynamic a2) => a1.x - a2.x); for you. With no context type, the parameters are inferred in a vacuum. The (The choice to allow you to directly return futures in |
Working as intended, and not a library issue. We are aware of the shortcomings of the type inference algorithm, and are considering that in the language repository. |
in the following program
clearly
T
ought to be bound toA
, but the compiler doesn't do this. instead it tries to bindT
toFutureOr<A>
, which yields this error:one way to work around this is
but it's pretty counterintuitive why inlining an expression should cause a program to break. another workaround would be to explicitly bind T:
but why are these workarounds needed? part of the problem seems to be that in an async context, one is allowed to return a
Future
or a non-Future
, which will automatically be wrapped in aFuture
. for some reason, this causes the compiler to gravitate toward guessing that the type of a returned value is aFutureOr
, which makes using the dot operator on such a value nearly useless.is there any way to make the compiler a bit smarter about these cases? e.g. here, it has at least 2 clues about how to bind T (the return type and the type of the param to
max
), one of which is ambiguous (the return type) and the other much less ambiguous (the type of the param tomax
). why doesn't it prefer to use the less ambiguous clue? another option would be to try both possibilities for binding T:A
andFuture<A>
.Dart VM version: 2.5.2 (Tue Oct 8 16:17:11 2019 +0200) on "macos_x64"
The text was updated successfully, but these errors were encountered: