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 infers promoted type on locals #40413

Closed
johnniwinther opened this issue Jan 31, 2020 · 7 comments
Closed

Analyzer infers promoted type on locals #40413

johnniwinther opened this issue Jan 31, 2020 · 7 comments
Assignees
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion.

Comments

@johnniwinther
Copy link
Member

The analyzer wrongfully infers promoted types on locals.

Consider this example:

method<T>(T a, T b) {
  if (a is String) {
    var o = a;
    o = b;
    o.length; // Missing error
  }
}

The inferred type for o is T & String which leads to a missing error in the o.length access.

This issue was only recently fixed in the CFE: https://dart-review.googlesource.com/c/sdk/+/133588

cc @stereotype441, @lrhn, @eernstg

@johnniwinther johnniwinther added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label Jan 31, 2020
@stereotype441
Copy link
Member

Interesting corner case! Even though it's not strictly speaking a null safety issue, I'm adding it to the analyzer team's null safety epic, since null safety causes type promotion to happen more frequently, so it's likely to crop up more often in opted in libraries.

@eernstg
Copy link
Member

eernstg commented Feb 5, 2020

Extra info which may be helpful for others: @johnniwinther just mentioned that the difficulty is demotion of the variable, and also that a promising approach is the following:

Allow the local variable o to get an inferred type which is taken from the intersection type by stripping off the intersection (in the example the inferred type of o would then be T, not T & String), and then o is immediately promoted based on a step where the initialization is considered as a promoting assignment. Then o can have type T & String until the assignment o = b, which will demote it to T (which is now possible), and then o.length will be an error.

@sigmundch
Copy link
Member

Just wanted to point to code that started breaking because of this change: #40485

The local variable with the promoted type seems to be final and only assigned in that initialization. Should that be allowed? (I believe it would follow from the alternative approach suggested by @eernstg in the comment above)

@eernstg
Copy link
Member

eernstg commented Feb 7, 2020

I think the alternative approach would work just as well for a final variable. It might seem slightly convoluted in that case, and maybe we could get away with a rule that says that the inferred type of a final variable can be an intersection type. But as long as it's consistent with the treatment of non-final variables the complexity of the approach in general doesn't grow, so we might as well use this approach for final variables as well.

PS: The alternative approach came from @johnniwinter, but I think it's a good idea. ;)

@stereotype441
Copy link
Member

Note: since this is a breaking change, it needs to be pre-announced and pre-tested internally before it's landed.

@johnniwinther
Copy link
Member Author

Also note: the change has already been landed by the CFE seeing only one problem internally.

@scheglov scheglov self-assigned this Feb 19, 2020
@scheglov
Copy link
Contributor

dart-bot pushed a commit that referenced this issue Feb 26, 2020
Internal presubmit looks green.
https://test.corp.google.com/ui#id=OCL:295832949:BASE:295984425:1582132722046:8eaca57b

Bug: #40413
Change-Id: I8514f6e1a99c4b02098cc649607cf31c5daf350f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136360
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
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.
Projects
None yet
Development

No branches or pull requests

5 participants