Skip to content

Type promotion issue with nullable functions #60632

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
nielsenko opened this issue Apr 28, 2025 · 3 comments
Closed

Type promotion issue with nullable functions #60632

nielsenko opened this issue Apr 28, 2025 · 3 comments
Labels
area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. model-flow Implementation of flow analysis in analyzer/cfe

Comments

@nielsenko
Copy link

nielsenko commented Apr 28, 2025

Here is a condensed example of the problem.

typedef Func = int Function(int);
Func weird(Func? functor) {
  functor ??= (_) => 42; // functor cannot be null hereafter
  return (int i) {
    return functor!(i); // yet, why is ! needed here?
  };
}

Even moving the promotion inside the returned function fails:

typedef Func = int Function(int);
Func weird(Func? functor) {
  return (int i) {
    functor ??= (_) => 42; // functor cannot be null hereafter
    return functor!(i); // yet, why is ! needed here?
  };
}

But this works:

Func weird(Func? functor) {
  functor ??= (_) => 42; // functor cannot be null hereafter
  return functor; // <-- this works;
  // return functor!; // <-- this correctly warns that ! will have no effect
}

and this as well:

Func weird(Func? functor) {
  final f = functor ?? (_) => 42; // f cannot be null
  return (int i) {
    return f(i); // Tada 🎉 
  };
}

dart info

#### General info

- Dart 3.7.2 (stable) (Tue Mar 11 04:27:50 2025 -0700) on "macos_x64"
- on macos / Version 15.4 (Build 24E248)
- locale is en-DK

#### Project info

- sdk constraint: '^3.7.2'
- dependencies: 
- dev_dependencies: lints, test
@nielsenko nielsenko added the area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. label Apr 28, 2025
@alexmarkov
Copy link
Contributor

This is a language / front-end question, not specific to the VM.

/cc @stereotype441

@alexmarkov alexmarkov added area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. and removed area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. labels Apr 28, 2025
@eernstg
Copy link
Member

eernstg commented Apr 28, 2025

Note that this is not tied to function types:

Function foo(int? x) {
  x ??= 1;
  return () => x.isEven; // Error: .. the receiver can be null.
}

The reason why x isn't known to be non-null is probably that the expression occurs in the body of a function literal (also known as a lambda or a closure), and the flow analysis basically has to assume that the function literal can be executed at any time (so we can't know whether or not x ??= 1 has already occurred).

@stereotype441 would know whether there's an opportunity to reach a stronger conclusion, based on the location where that function literal occurs (that is, we might be able to know that x ??= 1 has occurred when () => x.isEven is invoked).

@johnniwinther johnniwinther added the model-flow Implementation of flow analysis in analyzer/cfe label Apr 29, 2025
@stereotype441
Copy link
Member

This is a known issue that comes up fairly frequently. I would love to work on fixing it, but it's a fairly big task and it hasn't yet become a high enough priority to tackle. The canonical issue is dart-lang/language#1536.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. model-flow Implementation of flow analysis in analyzer/cfe
Projects
None yet
Development

No branches or pull requests

5 participants