@@ -6,8 +6,8 @@ use rustc_middle::mir::{
6
6
BinOp , Body , Constant , ConstantKind , LocalDecls , Operand , Place , ProjectionElem , Rvalue ,
7
7
SourceInfo , Statement , StatementKind , Terminator , TerminatorKind , UnOp ,
8
8
} ;
9
- use rustc_middle:: ty:: layout:: LayoutError ;
10
- use rustc_middle:: ty:: { self , ParamEnv , ParamEnvAnd , SubstsRef , Ty , TyCtxt } ;
9
+ use rustc_middle:: ty:: layout:: InitKind ;
10
+ use rustc_middle:: ty:: { self , ParamEnv , SubstsRef , Ty , TyCtxt } ;
11
11
use rustc_span:: symbol:: { sym, Symbol } ;
12
12
13
13
pub struct InstCombine ;
@@ -234,16 +234,15 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
234
234
}
235
235
let ty = substs. type_at ( 0 ) ;
236
236
237
- // Check this is a foldable intrinsic before we query the layout of our generic parameter
238
- let Some ( assert_panics) = intrinsic_assert_panics ( intrinsic_name) else { return ; } ;
239
- match assert_panics ( self . tcx , self . param_env . and ( ty) ) {
240
- // We don't know the layout, don't touch the assertion
241
- Err ( _) => { }
242
- Ok ( true ) => {
237
+ let known_is_valid = intrinsic_assert_panics ( self . tcx , self . param_env , ty, intrinsic_name) ;
238
+ match known_is_valid {
239
+ // We don't know the layout or it's not validity assertion at all, don't touch it
240
+ None => { }
241
+ Some ( true ) => {
243
242
// If we know the assert panics, indicate to later opts that the call diverges
244
243
* target = None ;
245
244
}
246
- Ok ( false ) => {
245
+ Some ( false ) => {
247
246
// If we know the assert does not panic, turn the call into a Goto
248
247
terminator. kind = TerminatorKind :: Goto { target : * target_block } ;
249
248
}
@@ -252,33 +251,21 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
252
251
}
253
252
254
253
fn intrinsic_assert_panics < ' tcx > (
254
+ tcx : TyCtxt < ' tcx > ,
255
+ param_env : ty:: ParamEnv < ' tcx > ,
256
+ ty : Ty < ' tcx > ,
255
257
intrinsic_name : Symbol ,
256
- ) -> Option < fn ( TyCtxt < ' tcx > , ParamEnvAnd < ' tcx , Ty < ' tcx > > ) -> Result < bool , LayoutError < ' tcx > > > {
257
- fn inhabited_predicate < ' tcx > (
258
- tcx : TyCtxt < ' tcx > ,
259
- param_env_and_ty : ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
260
- ) -> Result < bool , LayoutError < ' tcx > > {
261
- Ok ( tcx. layout_of ( param_env_and_ty) ?. abi . is_uninhabited ( ) )
262
- }
263
- fn zero_valid_predicate < ' tcx > (
264
- tcx : TyCtxt < ' tcx > ,
265
- param_env_and_ty : ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
266
- ) -> Result < bool , LayoutError < ' tcx > > {
267
- Ok ( !tcx. permits_zero_init ( param_env_and_ty) ?)
268
- }
269
- fn mem_uninitialized_valid_predicate < ' tcx > (
270
- tcx : TyCtxt < ' tcx > ,
271
- param_env_and_ty : ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
272
- ) -> Result < bool , LayoutError < ' tcx > > {
273
- Ok ( !tcx. permits_uninit_init ( param_env_and_ty) ?)
274
- }
275
-
276
- match intrinsic_name {
277
- sym:: assert_inhabited => Some ( inhabited_predicate) ,
278
- sym:: assert_zero_valid => Some ( zero_valid_predicate) ,
279
- sym:: assert_mem_uninitialized_valid => Some ( mem_uninitialized_valid_predicate) ,
280
- _ => None ,
281
- }
258
+ ) -> Option < bool > {
259
+ Some ( match intrinsic_name {
260
+ sym:: assert_inhabited => tcx. layout_of ( param_env. and ( ty) ) . ok ( ) ?. abi . is_uninhabited ( ) ,
261
+ sym:: assert_zero_valid => {
262
+ !tcx. check_validity_of_init ( ( InitKind :: Zero , param_env. and ( ty) ) ) . ok ( ) ?
263
+ }
264
+ sym:: assert_mem_uninitialized_valid => !tcx
265
+ . check_validity_of_init ( ( InitKind :: UninitMitigated0x01Fill , param_env. and ( ty) ) )
266
+ . ok ( ) ?,
267
+ _ => return None ,
268
+ } )
282
269
}
283
270
284
271
fn resolve_rust_intrinsic < ' tcx > (
0 commit comments