@@ -120,6 +120,7 @@ enum EnumCheckType<'tcx> {
120
120
} ,
121
121
}
122
122
123
+ #[ derive( Debug ) ]
123
124
struct TyAndSize < ' tcx > {
124
125
pub ty : Ty < ' tcx > ,
125
126
pub size : Size ,
@@ -349,13 +350,41 @@ fn insert_direct_enum_check<'tcx>(
349
350
source_info,
350
351
) ;
351
352
353
+ // Mask out the bits of the discriminant type.
354
+ let mask = match op_size. bytes ( ) {
355
+ 1 => u8:: MAX as u128 ,
356
+ 2 => u16:: MAX as u128 ,
357
+ 4 => u32:: MAX as u128 ,
358
+ 8 => u64:: MAX as u128 ,
359
+ 16 => u128:: MAX as u128 ,
360
+ invalid => bug ! ( "Found discriminant with invalid size, has {} bytes" , invalid) ,
361
+ } ;
362
+
363
+ let discr_masked =
364
+ local_decls. push ( LocalDecl :: with_source_info ( tcx. types . u128 , source_info) ) . into ( ) ;
365
+ let rvalue = Rvalue :: BinaryOp (
366
+ BinOp :: BitAnd ,
367
+ Box :: new ( (
368
+ Operand :: Copy ( discr) ,
369
+ Operand :: Constant ( Box :: new ( ConstOperand {
370
+ span : source_info. span ,
371
+ user_ty : None ,
372
+ const_ : Const :: Val ( ConstValue :: from_u128 ( mask) , tcx. types . u128 ) ,
373
+ } ) ) ,
374
+ ) ) ,
375
+ ) ;
376
+ block_data. statements . push ( Statement {
377
+ source_info,
378
+ kind : StatementKind :: Assign ( Box :: new ( ( discr_masked, rvalue) ) ) ,
379
+ } ) ;
380
+
352
381
// Branch based on the discriminant value.
353
382
block_data. terminator = Some ( Terminator {
354
383
source_info,
355
384
kind : TerminatorKind :: SwitchInt {
356
- discr : Operand :: Copy ( discr ) ,
385
+ discr : Operand :: Copy ( discr_masked ) ,
357
386
targets : SwitchTargets :: new (
358
- discriminants. into_iter ( ) . map ( |discr| ( discr, new_block) ) ,
387
+ discriminants. into_iter ( ) . map ( |discr| ( discr & mask , new_block) ) ,
359
388
invalid_discr_block,
360
389
) ,
361
390
} ,
0 commit comments