Skip to content
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

Analyzer doesn't infer type from "is" check against abstract class #26576

Closed
lexaknyazev opened this issue May 31, 2016 · 7 comments
Closed

Analyzer doesn't infer type from "is" check against abstract class #26576

lexaknyazev opened this issue May 31, 2016 · 7 comments
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@lexaknyazev
Copy link
Contributor

Analyzer doesn't infer type from is check against abstract class if variable was annotated with explicit type.
https://dartpad.dartlang.org/c6d0fee76a4986d8be05e1288d288e1c

@bwilkerson bwilkerson added area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels May 31, 2016
@bwilkerson
Copy link
Member

It doesn't actually have anything to do with the fact that I is an abstract class, it has to do with the way type promotion is defined in the spec (section 16.34):

Let v be a local variable or a formal parameter. An is-expression of the form v is T shows that v has type T iff T is more specific than the type S of the expression v and both T != dynamic and S != dynamic.

But I is not more specific than A (as defined in section 19.4). Hence, we cannot promote the type here and this is working as expected.

@lexaknyazev
Copy link
Contributor Author

So why in the code snippet above a1 is I evaluates to true, if I is not more specific than A?

@bwilkerson
Copy link
Member

Because of the difference between analysis-time (equivalent to compile-time) and run-time semantics. When we're performing a static analysis of the code we don't try to do full flow analysis. You told us that a1 could be any kind of A and we don't try to figure out that it will always be a B at this point in the code. But at run time the VM knows that the value of a1 it's an instance of B and hence also an instance of I.

@lexaknyazev
Copy link
Contributor Author

Thanks. Is it a correct way to suppress such analyzer warnings?

 if (a1 is I) (a1 as Object/*=I*/).foo();

@bwilkerson
Copy link
Member

Nope. Try putting that into DartPad; you'll see two errors rather than one.

There are three ways to disable the warning. The best is to add an explicit cast to the tested for type:

if (a1 is I) (a1 as I).foo();

The other two involve telling analyzer not to type check your code (which I don't recommend). One is to replace the line with the warning with:

if (a1 is I) (a1 as dynamic).foo();

The other is to change the declaration to:

var a1 = new B();

@lexaknyazev
Copy link
Contributor Author

Try putting that into DartPad; you'll see two errors rather than one.

DartPad and IntelliJ don't give any errors with strong mode enabled. Ctrl-click on foo() in IntelliJ navigates correctly to I.foo().

@bwilkerson
Copy link
Member

Correct. That's because, with strong mode enabled, the code is effectively rewritten to

if (a1 is I) (a1 as I).foo();

Without strong mode the content of the comment is ignored. But there's no reason to make the code valid only when strong mode is enabled :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

2 participants