diff options
| author | bors <bors@rust-lang.org> | 2023-02-15 20:56:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-02-15 20:56:07 +0000 |
| commit | c5283576ec18937d98889679a54aa8f2dee2b875 (patch) | |
| tree | 950ca5fd9d874fa9f7c990eee71df8a14e5ee58c /compiler/rustc_mir_transform/src | |
| parent | 2d14db321b043ffc579a7461464c88d7e3f54f83 (diff) | |
| parent | b096f0e0f01f9cc1f13d4d664fda93f9efe95485 (diff) | |
| download | rust-c5283576ec18937d98889679a54aa8f2dee2b875.tar.gz rust-c5283576ec18937d98889679a54aa8f2dee2b875.zip | |
Auto merge of #108012 - compiler-errors:issue-107999, r=oli-obk
Don't ICE in `might_permit_raw_init` if reference is polymorphic Emitting optimized MIR for a polymorphic function may require computing layout of a type that isn't (yet) known. This happens in the instcombine pass, for example. Let's fail gracefully in that condition. cc `@saethlin` fixes #107999
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/instcombine.rs | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index e1faa7a08d9..1079377fbac 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -6,7 +6,8 @@ use rustc_middle::mir::{ BinOp, Body, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnOp, }; -use rustc_middle::ty::{self, layout::TyAndLayout, ParamEnv, ParamEnvAnd, SubstsRef, Ty, TyCtxt}; +use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::{self, ParamEnv, ParamEnvAnd, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; pub struct InstCombine; @@ -230,38 +231,41 @@ impl<'tcx> InstCombineContext<'tcx, '_> { // Check this is a foldable intrinsic before we query the layout of our generic parameter let Some(assert_panics) = intrinsic_assert_panics(intrinsic_name) else { return; }; - let Ok(layout) = self.tcx.layout_of(self.param_env.and(ty)) else { return; }; - if assert_panics(self.tcx, self.param_env.and(layout)) { - // If we know the assert panics, indicate to later opts that the call diverges - *target = None; - } else { - // If we know the assert does not panic, turn the call into a Goto - terminator.kind = TerminatorKind::Goto { target: *target_block }; + match assert_panics(self.tcx, self.param_env.and(ty)) { + // We don't know the layout, don't touch the assertion + Err(_) => {} + Ok(true) => { + // If we know the assert panics, indicate to later opts that the call diverges + *target = None; + } + Ok(false) => { + // If we know the assert does not panic, turn the call into a Goto + terminator.kind = TerminatorKind::Goto { target: *target_block }; + } } } } fn intrinsic_assert_panics<'tcx>( intrinsic_name: Symbol, -) -> Option<fn(TyCtxt<'tcx>, ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool> { +) -> Option<fn(TyCtxt<'tcx>, ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result<bool, LayoutError<'tcx>>> { fn inhabited_predicate<'tcx>( - _tcx: TyCtxt<'tcx>, - param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>, - ) -> bool { - let (_param_env, layout) = param_env_and_layout.into_parts(); - layout.abi.is_uninhabited() + tcx: TyCtxt<'tcx>, + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result<bool, LayoutError<'tcx>> { + Ok(tcx.layout_of(param_env_and_ty)?.abi.is_uninhabited()) } fn zero_valid_predicate<'tcx>( tcx: TyCtxt<'tcx>, - param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>, - ) -> bool { - !tcx.permits_zero_init(param_env_and_layout) + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result<bool, LayoutError<'tcx>> { + Ok(!tcx.permits_zero_init(param_env_and_ty)?) } fn mem_uninitialized_valid_predicate<'tcx>( tcx: TyCtxt<'tcx>, - param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>, - ) -> bool { - !tcx.permits_uninit_init(param_env_and_layout) + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result<bool, LayoutError<'tcx>> { + Ok(!tcx.permits_uninit_init(param_env_and_ty)?) } match intrinsic_name { |
