File tree Expand file tree Collapse file tree 4 files changed +37
-14
lines changed
compiler/rustc_middle/src/ty Expand file tree Collapse file tree 4 files changed +37
-14
lines changed Original file line number Diff line number Diff line change @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashMap;
88use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
99use rustc_errors:: ErrorReported ;
1010use rustc_hir as hir;
11- use rustc_hir:: def:: { DefKind , Res } ;
11+ use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
1212use rustc_hir:: def_id:: DefId ;
1313use rustc_index:: vec:: { Idx , IndexVec } ;
1414use rustc_serialize:: { self , Encodable , Encoder } ;
@@ -314,6 +314,22 @@ impl<'tcx> AdtDef {
314314 /// Whether the ADT lacks fields. Note that this includes uninhabited enums,
315315 /// e.g., `enum Void {}` is considered payload free as well.
316316 pub fn is_payloadfree ( & self ) -> bool {
317+ // Treat the ADT as not payload-free if arbitrary_enum_discriminant is used (#88621).
318+ // This would disallow the following kind of enum from being casted into integer.
319+ // ```
320+ // enum Enum {
321+ // Foo() = 1,
322+ // Bar{} = 2,
323+ // Baz = 3,
324+ // }
325+ // ```
326+ if self
327+ . variants
328+ . iter ( )
329+ . any ( |v| matches ! ( v. discr, VariantDiscr :: Explicit ( _) ) && v. ctor_kind != CtorKind :: Const )
330+ {
331+ return false ;
332+ }
317333 self . variants . iter ( ) . all ( |v| v. fields . is_empty ( ) )
318334 }
319335
Original file line number Diff line number Diff line change 1+ #[ repr( u8 ) ]
2+ enum Kind2 {
3+ Foo ( ) = 1 ,
4+ Bar { } = 2 ,
5+ Baz = 3 ,
6+ }
7+
8+ fn main ( ) {
9+ let _ = Kind2 :: Foo ( ) as u8 ;
10+ //~^ ERROR non-primitive cast
11+ }
Original file line number Diff line number Diff line change 1+ error[E0605]: non-primitive cast: `Kind2` as `u8`
2+ --> $DIR/issue-88621.rs:9:13
3+ |
4+ LL | let _ = Kind2::Foo() as u8;
5+ | ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
6+
7+ error: aborting due to previous error
8+
9+ For more information about this error, try `rustc --explain E0605`.
Original file line number Diff line number Diff line change @@ -22,14 +22,6 @@ impl Enum {
2222 }
2323}
2424
25- #[ allow( dead_code) ]
26- #[ repr( u8 ) ]
27- enum FieldlessEnum {
28- Unit = 3 ,
29- Tuple ( ) = 2 ,
30- Struct { } = 1 ,
31- }
32-
3325fn main ( ) {
3426 const UNIT : Enum = Enum :: Unit ;
3527 const TUPLE : Enum = Enum :: Tuple ( 5 ) ;
@@ -48,9 +40,4 @@ fn main() {
4840 assert_eq ! ( 3 , UNIT_TAG ) ;
4941 assert_eq ! ( 2 , TUPLE_TAG ) ;
5042 assert_eq ! ( 1 , STRUCT_TAG ) ;
51-
52- // Ensure `as` conversions are correct
53- assert_eq ! ( 3 , FieldlessEnum :: Unit as u8 ) ;
54- assert_eq ! ( 2 , FieldlessEnum :: Tuple ( ) as u8 ) ;
55- assert_eq ! ( 1 , FieldlessEnum :: Struct { } as u8 ) ;
5643}
You can’t perform that action at this time.
0 commit comments