diff --git a/compiler/rustc_mir_transform/src/check_niches.rs b/compiler/rustc_mir_transform/src/check_niches.rs index 4462ebbfea76..b740e5251efa 100644 --- a/compiler/rustc_mir_transform/src/check_niches.rs +++ b/compiler/rustc_mir_transform/src/check_niches.rs @@ -92,7 +92,8 @@ impl<'a, 'tcx> Visitor<'tcx> for NicheFinder<'a, 'tcx> { if let Rvalue::Cast(CastKind::Transmute, op, ty) = rvalue { if let Some(niche) = self.get_niche(*ty) { with_no_trimmed_paths!(debug!( - "Found place {op:?}: {ty:?} with niche due to Transmute" + "Found place {op:?}: {ty:?} with niche {niche:?} due to Transmute: {:?}", + self.body.stmt_at(location) )); self.places.push((op.clone(), niche)); } @@ -114,9 +115,8 @@ impl<'a, 'tcx> Visitor<'tcx> for NicheFinder<'a, 'tcx> { } let ty = place.ty(self.body, self.tcx).ty; - if ty == self.tcx.types.bool { - // LLVM defeats our attempts to insert niche checks for bools by truncating all our - // loads to an i1. + // bool is actually an i1 to LLVM which means a bool local can never be invalid. + if ty == self.tcx.types.bool && place.projection.is_empty() { return; } let Some(niche) = self.get_niche(ty) else { @@ -136,7 +136,8 @@ impl<'a, 'tcx> Visitor<'tcx> for NicheFinder<'a, 'tcx> { } with_no_trimmed_paths!(debug!( - "Found place {place:?}: {ty:?} with niche due to {context:?}" + "Found place {place:?}: {ty:?} with niche {niche:?} due to {:?}", + self.body.stmt_at(location) )); self.places.push((Operand::Copy(*place), niche)); @@ -153,6 +154,10 @@ impl<'a, 'tcx> NicheFinder<'a, 'tcx> { let niche = layout.largest_niche?; + if niche.offset == Size::ZERO { + return None; + } + if niche.size(self.tcx) == layout.size { Some(NicheKind::Full(niche)) } else { @@ -295,7 +300,7 @@ impl<'a, 'tcx> NicheChecker<'a, 'tcx> { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum NicheKind { Full(Niche), // We need the full Size of the type in order to do the transmute-to-MU approach