-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
if case
with type check turns values to null if not covered in the first if case
and the assigned name is the same as the local variable
#59613
Comments
Summary: |
The following variant behaves as expected: void main() {
for (final thing in [42.42, 'foo', Object()]) {
if (thing case final double t1) {
print('$t1 is double');
} else if (thing case final String t2) {
print('$t2 is String');
} else if (thing case final Object t3) {
print('$t3 is Object');
} else {
// analyzer warns this is dead code
print('$thing is unknown ${thing.runtimeType}');
}
// accessing thing here is still the original value
}
} Sounds like a code generation bug in the common front end. I think there was an issue with some of the same elements: The use of several variables with the same name around patterns gave rise to wrong code generation in some cases. @johnniwinther, WDYT? |
This definitely looks like a bug in the compiler. The scope of the new if (thing case final double thing) {
print('$thing is double');
} else ... should be the void main() {
test(42);
}
void test(Object o) {
late ({Object Function() get, void Function(Object) set}) closures;
if (o case 37 && final num o && final num z) {
print("Wat?");
o == 87; // Not an error?
} else {
print(o); // Prints null.
// print(z); // Error: Undefined name 'z'.
print([o].runtimeType); // Prints (effectively) `List<Object>`, so unsound to have value `null`!
o = "a";
print(o); // Prints a
closures = (get: () => o, set: (v) => o = v);
}
print(o); // Prints 42
closures.set(false);
print(o); // Prints 42
print(closures.get()); // Prints false
} The |
BTW, I only tested on DartPad, but now that I did further testing, the error only occurs when compiling using ddc. It works as expected with |
The CFE encoding is technically correct since it doesn't rely on the names of variables but instead references to variable declarations in its encoding. Unfortunately DDC assumes that names can be used, so because the generated code introduces shadowing, using the names fails. I'm working on a fix. cc @nshahan |
This code:
Outputs:
Expected output:
The output is correct if I don't assign the loop variable to a variable with the same name in the
if case
.A loop isn't required for this bug, something like
final thing = ['foo', 1].first;
has the same problem.Simply using
final thing = 'foo';
before theif case
is even worse:Tested on DartPad, stable and main:
Dart SDK 3.5.4 and Flutter SDK 3.24.5
Dart SDK 3.7.0-183.0.dev and Flutter SDK 3.27.0-1.0.pre.623
The text was updated successfully, but these errors were encountered: