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

omit_local_variable_types has spurious diagnostics when the variable type impacts inference #59317

Open
natebosch opened this issue Oct 5, 2023 · 8 comments
Labels
analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. linter-false-positive P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@natebosch
Copy link
Member

void main() async {
  final String s1 = await someGeneric(['']); // omit_local_variable_types
  print(typeOf(s1)); // String
  // Removing the annotation results in a static type change:
  final s2 = await someGeneric(['']);
  print(typeOf(s2)); // dynamic
}

Future<T> someGeneric<T, S extends List<T>>(S v) async => v.first;

Type typeOf<T>(T arg) => T;

The lint fires and asks for the local variable type to be removed, but doing so changes the static type of the variable. We don't correctly check when the variable impacts inference, because we only check whether the return type is a type variable.

if (element.returnType is TypeParameterType) {

Once the type is more complicated, like Future<T>, the lint misfires.

cc @pq @yanok

@pq pq transferred this issue from dart-lang/sdk Oct 5, 2023
@pq pq added linter-false-positive P1 A high priority bug; for example, a single project is unusable or has many test failures labels Oct 5, 2023
@srawlins
Copy link
Member

srawlins commented Oct 6, 2023

Sigh, yeah I think we have to file this in the bucket of "in order to implement this perfectly correctly, the lint rule needs to run during inference" (or at least have knowledge of context types). ☹️

@yanok
Copy link
Contributor

yanok commented Oct 6, 2023

To be perfectly correct, right, lint needs to be able to re-run inference for the expression without a context type. But to just exclude false positives, we could simple modify the check from "is a type variable" to "contains a type variable". This is a conservative check, so there will be false negatives. But at least it will be more consistent than it is now, since now we can get both false negatives and false positives.

@bwilkerson
Copy link
Member

... the lint rule needs to run during inference ...

For what it's worth, I'm not convinced that even that would be enough. I think it's the case that we would need to be able to ask "what if" questions. Things like "what would the (inferred) type of this variable be if we were to remove the type annotation. Yes, that requires running inference over the modified code, but I don't think we'd be able to answer that question while running inference over the unmodified code.

@srawlins
Copy link
Member

srawlins commented Oct 6, 2023

But to just exclude false positives, we could simple modify the check from "is a type variable" to "contains a type variable".

I think this is very pragmatic! 👍

I think it's the case that we would need to be able to ask "what if" questions.

Oh I think you're right. Yeah this might need to include flow analysis of statements and expressions that follow the variable declaration, with a "hypothetical" type. This is the same conundrum as the unnecessary_cast false positives.

@srawlins
Copy link
Member

@pq as a P1, this ticket should be actively worked on. Is this one you are planning to take, or should I assign to someone else?

@pq
Copy link
Member

pq commented Oct 10, 2023

Agreed. I'm not actively on this one so if anyone is game, they're welcome to jump on it!

@eernstg
Copy link
Member

eernstg commented Oct 11, 2023

There is a way to simplify the "false positives are complex" issue with omit_local_variable_types: If we milden this lint such that it only asks developers to remove a declared type when the initializing expression has an 'obvious' type (as proposed in #58773) then we would probably have very few false positives in the first place.

@pq
Copy link
Member

pq commented Oct 11, 2023

@stereotype441: more fodder for the flow analysis conversation

@pq pq added P3 A lower priority bug or feature request and removed P1 A high priority bug; for example, a single project is unusable or has many test failures labels Oct 12, 2023
@srawlins srawlins added the type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) label Apr 3, 2024
@devoncarew devoncarew added analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. labels Nov 20, 2024
@devoncarew devoncarew transferred this issue from dart-lang/linter Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. linter-false-positive P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

7 participants