Skip to content

Non-null inference with closures is confusing #51452

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
liamappelbe opened this issue Feb 18, 2023 · 1 comment
Closed

Non-null inference with closures is confusing #51452

liamappelbe opened this issue Feb 18, 2023 · 1 comment

Comments

@liamappelbe
Copy link
Contributor

This works:

int foo(int x) {
  int? y;
  if (x == 10) y = x;
  if (y == null) return -1;
  return y;  // y is correctly promoted to be non-nullable, due to null check above.
}

But this doesn't work:

int foo(int x) {
  int? y;
  final bar = () {
    if (x == 10) y = x;
  };
  bar();
  if (y == null) return -1;
  return y;  // y is not promoted, and is still nullable. Compile error.
}

I think this is happening because in the second case, bar is a closure, which is implemented internally by creating an anonymous class and storing x and y as fields on the class. So since class fields can't be type promoted, y is still int? at the end of foo. This is a very confusing behavior, since many users wouldn't realize that bar is actually a class.

My understanding is that class fields can't be promoted in this way because elsewhere in the code someone might write a subclass that overrides the getter to return null on the second access. However, in this case the class is anonymous, so can't be subclassed. So I think this instance could be safely special cased by allowing promotion for fields of anonymous classes.

@mraleph
Copy link
Member

mraleph commented Feb 18, 2023

See dart-lang/language#1536

I think this is happening because in the second case, bar is a closure, which is implemented internally by creating an anonymous class ...

It's just how promotion rules are specified - nothing to do with any particular implementation of closures.

@mraleph mraleph closed this as completed Feb 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants