-
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
dart2wasm incorrectly uses identity comparison in switches over Type in language version < 3.0 #60375
Comments
Is this important, given that the specification says each expression should be a constant? It seems like VM is supporting what should be a compile-time error. Should const-ness of the expressions be checked by CFE? Is Dart 2.15 a version we want to support in dart2wasm? |
Yes, it is important. See 10.2.3 - it has two different rules: one for constants and the second for classes. These rules mean that
Yes, both CFE and analyzer are missing a compile time error for this case.
Yes, because it is a supported language version. |
To clarify: I think the bug is actually in CFE, not in dart2wasm. I don't think we can start emitting a compile time error here (not worth the trouble of going through breaking change), but CFE should at least change the lowering and not emit |
Any opinions @johnniwinther @eernstg ? |
Agreed, the switch in the OP should have been reported as a compile-time error because the class However, the class (This is not the same thing as inheriting I also suspect that switches on type literals have been used rather widely (perhaps very unevenly: many teams would never use it, a few would use it rather frequently). This could be taken as a strong hint that it would be helpful to change the behavior of dart2wasm such that it uses |
cc @mkustermann @osa1 @johnniwinther @eernstg
The code below does not work when compiled with
dart2wasm
, but works on the VM.You end up with a code which uses
identical()
for comparison - which does not work unless types are globally canonicalized andruntimeType
results are not canonicalized in dart2wasm.It seems dart2wasm assumes that CFE will lower any switch which requires calling
operator==
into a sequence ofif
-s, but CFE does not due to some legacy bug.Here is I think what happened here: I think we have been missing a compile time error for such
switch
in language versions prior to 3.01. Old specification for switch statement says:Note that the last requirement is imposed on the class
C
itself and not on the constants. This is very relevant distinction in this case because if we check 10.2.3 for rules we find these two:These rules mean that
int
andString
(as constants) have primitive equality but not classType
itself because it has an override of==
. Which in turn means that switch like the one above should have triggered a compile time error.However neither analyzer nor CFE emit a compile time error. CFE just produces
SwitchStatement
here if language version is below 3.02dart2wasm
then makes an assumption that this type ofSwitchStatement
can be lowered usingidentical(...)
, which leads to incorrectly behaving switch.VM on the other hand simply builds
operator==
calls3 for each case inSwitchStatement
- just like specification instructs us.Footnotes
Pattern specification lifted restrictions on user defined equality to align classical switches with patterns. See discussions here or search for primitive equality in the patterns feature spec ↩
with language versions >=3.0 CFE correctly lowers this switch into sequence of
if
s, because lowering correctly treatsType
as a class with non-primitive equality. ↩FWIW VM also canonicalizes
Type
objects globally so you would not be able to observe incorrectswitch
behavior on the VM even if VM usedidentical
. ↩The text was updated successfully, but these errors were encountered: