-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Sound null safety not working correctly #53922
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
Comments
cc @lrhn |
I can't speak to potential changes here and I'm not super familiar, but I can try to help out and provide safer alternatives. I believe this is expected, since the type of the result of a ternary/conditional expression is the least upper bound of the types of both expressions. In this case Two potential solutions to catch the mistake before runtime:
|
This is indeed the upper-bound of the condtional expression ( Which means this is working as currently specified, and the problem comes from having The solution, I hope, in the long run, will be to make it an error if either branch of a conditional expression is not assignable to the context type, and doing any necessary downcasts from Until then, avoid This code can be rewritten as: class Foo {
final int number;
Foo({
required this.number,
});
factory Foo.fromMap(Map<String, dynamic>? json) {
if (json?['number'] case int n) {
return Foo(number: n);
} else {
// Do something here. Trying to use `null` will give a compile-time error.
throw "Badness";
}
}
}
class Bar {
Map<String, Object?>? firstMap;
void test() {
final foo = Foo.fromMap(firstMap); // Throws "Badness".
}
}
void main() {
final second = Bar();
second.test();
} |
@AmrAbdelmagid, you might want to get a heads up at compile time when the type analyzer:
language:
strict-raw-types: true
strict-inference: true
strict-casts: true
linter:
rules:
- avoid_dynamic_calls With this file in place, the analyzer reports the following issues on your example:
|
Oops, @parlough already mentioned strict-casts and its ilk, sorry about the unnecessary comment. |
Issue Description:
The following code compiles without any compile time errors, but results in a runtime error:
The runtime error occurs because the
number
field of theFoo
class is required and not nullable, but the factoryFoo.fromMap()
constructor allows to assign a null value in this case.I think this is a bug in the Dart compiler. The compiler should generate an error at compile time, indicating that type
int?
is not a subtype of typeint
.Steps to reproduce:
Or you can run this code snippet in DartPad.
Expected behavior:
The compiler should generate compile time error, indicating that type
int?
is not a subtype of typeint
.Actual behavior:
The program compiles without any warnings, but results in a runtime error.
Environment:
Flutter version: 3.13.9
Dart version: 3.1.5
OS: macOS Ventura 13.5.2
The text was updated successfully, but these errors were encountered: