@@ -14,7 +14,7 @@ use rustc_middle::mir::{AggregateKind, BinOp, CastKind, NullOp, Operand, Place,
14
14
use rustc_middle:: ty:: adjustment:: PointerCast ;
15
15
use rustc_middle:: ty:: layout:: LayoutOf ;
16
16
use rustc_middle:: ty:: { self , Instance , IntTy , Ty , TyCtxt , UintTy , VtblEntry } ;
17
- use rustc_target:: abi:: { FieldsShape , Primitive , TagEncoding , Variants } ;
17
+ use rustc_target:: abi:: { FieldsShape , TagEncoding , Variants } ;
18
18
use tracing:: { debug, warn} ;
19
19
20
20
impl < ' tcx > GotocCtx < ' tcx > {
@@ -503,12 +503,14 @@ impl<'tcx> GotocCtx<'tcx> {
503
503
. map_or ( index. as_u32 ( ) as u128 , |discr| discr. val ) ;
504
504
Expr :: int_constant ( discr_val, self . codegen_ty ( res_ty) )
505
505
}
506
- Variants :: Multiple { tag , tag_encoding, .. } => match tag_encoding {
506
+ Variants :: Multiple { tag_encoding, .. } => match tag_encoding {
507
507
TagEncoding :: Direct => {
508
508
self . codegen_discriminant_field ( e, ty) . cast_to ( self . codegen_ty ( res_ty) )
509
509
}
510
510
TagEncoding :: Niche { dataful_variant, niche_variants, niche_start } => {
511
- // This code follows the logic in the cranelift codegen backend:
511
+ // This code follows the logic in the ssa codegen backend:
512
+ // https://github.com/rust-lang/rust/blob/fee75fbe11b1fad5d93c723234178b2a329a3c03/compiler/rustc_codegen_ssa/src/mir/place.rs#L247
513
+ // See also the cranelift backend:
512
514
// https://github.com/rust-lang/rust/blob/05d22212e89588e7c443cc6b9bc0e4e02fdfbc8d/compiler/rustc_codegen_cranelift/src/discriminant.rs#L116
513
515
let offset = match & layout. fields {
514
516
FieldsShape :: Arbitrary { offsets, .. } => offsets[ 0 ] ,
@@ -523,36 +525,35 @@ impl<'tcx> GotocCtx<'tcx> {
523
525
// https://github.com/rust-lang/rust/blob/fee75fbe11b1fad5d93c723234178b2a329a3c03/compiler/rustc_codegen_ssa/src/mir/place.rs#L247
524
526
//
525
527
// Note: niche_variants can only represent values that fit in a u32.
528
+ let result_type = self . codegen_ty ( res_ty) ;
526
529
let discr_mir_ty = self . codegen_enum_discr_typ ( ty) ;
527
530
let discr_type = self . codegen_ty ( discr_mir_ty) ;
528
- let niche_val = self . codegen_get_niche ( e, offset, discr_type. clone ( ) ) ;
531
+ let niche_val = self . codegen_get_niche ( e, offset, discr_type) ;
529
532
let relative_discr =
530
533
wrapping_sub ( & niche_val, u64:: try_from ( * niche_start) . unwrap ( ) ) ;
531
534
let relative_max =
532
535
niche_variants. end ( ) . as_u32 ( ) - niche_variants. start ( ) . as_u32 ( ) ;
533
- let is_niche = if tag. primitive ( ) == Primitive :: Pointer {
534
- tracing:: trace!( ?tag, "Primitive::Pointer" ) ;
535
- discr_type. null ( ) . eq ( relative_discr. clone ( ) )
536
+ let is_niche = if relative_max == 0 {
537
+ relative_discr. clone ( ) . is_zero ( )
536
538
} else {
537
- tracing:: trace!( ?tag, "Not Primitive::Pointer" ) ;
538
539
relative_discr
539
540
. clone ( )
540
541
. le ( Expr :: int_constant ( relative_max, relative_discr. typ ( ) . clone ( ) ) )
541
542
} ;
542
543
let niche_discr = {
543
544
let relative_discr = if relative_max == 0 {
544
- self . codegen_ty ( res_ty ) . zero ( )
545
+ result_type . zero ( )
545
546
} else {
546
- relative_discr. cast_to ( self . codegen_ty ( res_ty ) )
547
+ relative_discr. cast_to ( result_type . clone ( ) )
547
548
} ;
548
549
relative_discr. plus ( Expr :: int_constant (
549
550
niche_variants. start ( ) . as_u32 ( ) ,
550
- self . codegen_ty ( res_ty ) ,
551
+ result_type . clone ( ) ,
551
552
) )
552
553
} ;
553
554
is_niche. ternary (
554
555
niche_discr,
555
- Expr :: int_constant ( dataful_variant. as_u32 ( ) , self . codegen_ty ( res_ty ) ) ,
556
+ Expr :: int_constant ( dataful_variant. as_u32 ( ) , result_type ) ,
556
557
)
557
558
}
558
559
} ,
0 commit comments