Skip to content
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

Evaluating Enum constructors should be a compile time error #48350

Closed
bkonyi opened this issue Feb 8, 2022 · 3 comments
Closed

Evaluating Enum constructors should be a compile time error #48350

bkonyi opened this issue Feb 8, 2022 · 3 comments
Assignees
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues.

Comments

@bkonyi
Copy link
Contributor

bkonyi commented Feb 8, 2022

Given the following enum declaration:

import 'dart:developer';                                                                                                                     
                                                                                                                                             
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
                                                                      
import 'common/service_test_common.dart';       
import 'common/test_helper.dart';                              
                                                                                                                                                                                                                                                                                           
class I1 {
  int interfaceMethod1() => 0;                              
  int get interfaceGetter1 => 0; 
  void set interfaceSetter1(int value) {}
}   
                                                                      
abstract class I2 {                                             
  int interfaceMethod2();                                                                                                                    
  int get interfaceGetter2;
  void set interfaceSetter2(int value);                                                                                                      
}                                                                                                                                            
                                                                      
mixin M on Object {             
  int mixedInMethod() => 42;                                                                                                                 
}                                      
                                                                      
enum E with M implements I1, I2 {
  e1,                                                           
  e2,                                  
  e3;                                 

  int interfaceMethod1() => 42;                                 
  int get interfaceGetter1 => 42;      
  void set interfaceSetter1(int value) {}
  int interfaceMethod2() => 42;
  int get interfaceGetter2 => 42;
  void set interfaceSetter2(int value) {}
}

Evaluating E(123, 'foo') via the VM service results in a valid instance of E being returned. I haven't tested with a simpler Enum declaration, but this is likely still an issue with simpler enums.

FYI @chloestefantsova @johnniwinther

Related to #47849 and #47870.

@bkonyi bkonyi added the area-front-end Use area-front-end for front end / CFE / kernel format related issues. label Feb 8, 2022
@johnniwinther
Copy link
Member

I don't know what "Evaluating E(123, 'foo') via the VM service" means. Is this expression evaluation or something internal to the VM?

@lrhn
Copy link
Member

lrhn commented Feb 10, 2022

I believe the VM's debugger uses the VM service to evaluate expressions, so this is probably something you can write in a debugger, or send directly to the VM service.

So, likely, the front-end enum implementation desugars enum declarations into class declarations and introduces a constructor, but doesn't let anyone reference it during compilation.
The VM service's expression evaluator then compiles and runs code against the desugared program, which allows it to see the synthetic constructor.

That can allow any number of weird things to happen, because it breaks the desugaring abstraction.
I'd say that the VM is to blame here, not the front-end. They get a desugared program, with but they treat it as if it was the original program.

I'm tempted to say "then don't do that", mainly to the people using the VM service to do such things. A debugger can do things to your program that the compiler didn't predict, so using it may break assumptions and crash the program.

Alternatively, the desugaring could make the constructor private, or mark it with some kind of internal metadata to say that it's supposed to be inaccessible.

@johnniwinther
Copy link
Member

There seems to be a missing check in the CFE when the enum is precompiled.

@johnniwinther johnniwinther self-assigned this Feb 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues.
Projects
None yet
Development

No branches or pull requests

3 participants