@@ -120,6 +120,7 @@ enum EnumCheckType<'tcx> {
120120 } ,
121121}
122122
123+ #[ derive( Debug ) ]
123124struct TyAndSize < ' tcx > {
124125 pub ty : Ty < ' tcx > ,
125126 pub size : Size ,
@@ -349,13 +350,41 @@ fn insert_direct_enum_check<'tcx>(
349350 source_info,
350351 ) ;
351352
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+
352381 // Branch based on the discriminant value.
353382 block_data. terminator = Some ( Terminator {
354383 source_info,
355384 kind : TerminatorKind :: SwitchInt {
356- discr : Operand :: Copy ( discr ) ,
385+ discr : Operand :: Copy ( discr_masked ) ,
357386 targets : SwitchTargets :: new (
358- discriminants. into_iter ( ) . map ( |discr| ( discr, new_block) ) ,
387+ discriminants. into_iter ( ) . map ( |discr| ( discr & mask , new_block) ) ,
359388 invalid_discr_block,
360389 ) ,
361390 } ,
0 commit comments