File tree 4 files changed +37
-14
lines changed
compiler/rustc_middle/src/ty
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;
8
8
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
9
9
use rustc_errors:: ErrorReported ;
10
10
use rustc_hir as hir;
11
- use rustc_hir:: def:: { DefKind , Res } ;
11
+ use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
12
12
use rustc_hir:: def_id:: DefId ;
13
13
use rustc_index:: vec:: { Idx , IndexVec } ;
14
14
use rustc_serialize:: { self , Encodable , Encoder } ;
@@ -314,6 +314,22 @@ impl<'tcx> AdtDef {
314
314
/// Whether the ADT lacks fields. Note that this includes uninhabited enums,
315
315
/// e.g., `enum Void {}` is considered payload free as well.
316
316
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
+ }
317
333
self . variants . iter ( ) . all ( |v| v. fields . is_empty ( ) )
318
334
}
319
335
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 {
22
22
}
23
23
}
24
24
25
- #[ allow( dead_code) ]
26
- #[ repr( u8 ) ]
27
- enum FieldlessEnum {
28
- Unit = 3 ,
29
- Tuple ( ) = 2 ,
30
- Struct { } = 1 ,
31
- }
32
-
33
25
fn main ( ) {
34
26
const UNIT : Enum = Enum :: Unit ;
35
27
const TUPLE : Enum = Enum :: Tuple ( 5 ) ;
@@ -48,9 +40,4 @@ fn main() {
48
40
assert_eq ! ( 3 , UNIT_TAG ) ;
49
41
assert_eq ! ( 2 , TUPLE_TAG ) ;
50
42
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 ) ;
56
43
}
You can’t perform that action at this time.
0 commit comments