Skip to content

ARGUMENT_TYPE_NOT_ASSIGNABLE although preceded by a not-null condition #46897

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

Closed
asashour opened this issue Aug 13, 2021 · 3 comments
Closed
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).

Comments

@asashour
Copy link
Contributor

For the below case, there is a compiler error

The argument type 'TypeAnnotation?' can't be assigned to the parameter type 'AstNode'

I believe this shouldn't happen, since there is a check for returnType != null, also the error is removed if the returnType is declared as

var returnType = function?.returnType;
void fun(FunctionDeclaration? function, ChangeBuilder builder, String file) async {
  TypeAnnotation? returnType;
  returnType = function?.returnType;
  // var returnType = function?.returnType; // this doesn't give an error

  if (returnType != null) {
    await builder.addDartFileEdit(file, (builder) {
      builder.addReplacement(range.node(returnType), (builder) {
        //                              ^^^^^^^^^^ error is here
      });
    });
  }
}

Dart SDK version: 2.15.0-6.0.dev (dev) (Wed Aug 11 14:48:30 2021 -0700) on "windows_x64"

@lrhn
Copy link
Member

lrhn commented Aug 13, 2021

Since returnType is captured by a closure, it gets much harder for the compiler to ensure that the execuction really happens after the test, and not after any other change to returnType.
If there is any assignment to a variable inside any closure, all promotion of that variable is turned off. If a variable occurs in a closure, that occurrence may or may not have promotion turned off depending on how clever the compiler manages to be.

In this case, it should be technically possible to retain the promotion (the closure is created after the last assignment to returnType in the function's control flow, and returnType is promoted to non-null at the time), but there are limits to how clever the compiler can be and how far ahead it can look to see that nothing bad happens. Even in cases that look very clear-cut, the edges of those cases might not always be as clearly delimited.

@stereotype441 should know whether this is intended or accidental.

I'd recommend working around this by creating a new variable:

  if (returnType != null) {
    var nonNullReturnType = returnType;
    .....  
             range.node(nonNullReturnType);

@vsmenon vsmenon added the legacy-area-analyzer Use area-devexp instead. label Aug 13, 2021
@stereotype441
Copy link
Member

Yes, this is a known area where flow analysis could be improved. The primary place we're tracking it is here: dart-lang/language#1536.

@stereotype441 stereotype441 added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). and removed legacy-area-analyzer Use area-devexp instead. labels Aug 13, 2021
@srawlins
Copy link
Member

srawlins commented Oct 7, 2021

Closing in favor of the language issue.

@srawlins srawlins closed this as completed Oct 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).
Projects
None yet
Development

No branches or pull requests

5 participants