-
Notifications
You must be signed in to change notification settings - Fork 205
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
Type inference starts to fail to infer argument type when making return type of method more precise #3478
Comments
Inference for the class A<X> {}
class B<X> implements A<X> {}
void main() {
Object o = B<int>();
if (o is A<int>) {
o = B(); // Infer `B()` with context type `A<int>`.
print(o.runtimeType); // `B<int>`.
}
if (o is B<int>) {
o = A(); // Infer `A()` with context type `B<int>`.
print(o.runtimeType); // `A<dynamic>`.
}
} So I'd say that it is expected. It may or may not be an appropriate choice to transfer information about the type arguments from the context type in the case where that context type will not be a supertype of the type of the target expression after inference. In the situation with context type Also, perhaps you have some additional comments on this, @stereotype441 or @leafpetersen? |
For more context, we discovered this while rolling google/protobuf.dart#903 to g3. In that PR I updated return types of some generated methods from The roll CL shows the breakage: cl/584816240. Another related issue is that giving local types in this case sometimes generates |
This is a language issue so I am going to transfer this to dart-sdk/language repo. |
As an example, if I add type to void main() {
final obj = foo<int>() ?? A();
final A<int> obj2 = fooMorePreciseReturn<int>() ?? A(); // generates warning
print(obj.runtimeType);
print(obj2.runtimeType);
} |
The "unnecessary type annotation" - and "unnecessary cast" - warnings are fairly naive. They check whether the static type of the expression is the same as the type of the variable, or if the cast is an up-cast with the currently inferred types, but do not take into account whether removing the type annotation or cast would change that static type. (Because it doesn't run a second type inference on the same expression, which is what it would require to know the effect of removing the context type, or adding one in the case of removing a Be ready to ignore "unnecessary type/cast..." warnings when they're wrong. |
Could there be some kind of provenance on the It does seem useful to avoid all these false positives, especially if it introduces bugs much later in the code (rather than just compile-time errors in the enclosing scope). |
See this example
This will print surprisingly
So when making functions like
foo
return a more precise type, the type inference stops inferring thatA()
should be anA<int>()
. Though it knows the class relationship fromB<T>
toA<T>
and could infer it to beint
.(reported by @osa1 )
@chloestefantsova @lrhn @eernstg Is this expected behavior?
The text was updated successfully, but these errors were encountered: