From b4b33df983b4badac5c2578756cd42a76236be8d Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 20 Jul 2023 21:01:27 +0200 Subject: Make `unconditional_recursion` warning detect recursive drops --- compiler/rustc_mir_transform/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'compiler/rustc_mir_transform/src') diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index d419329f2d6..abbac8f2554 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -446,6 +446,10 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & run_analysis_to_runtime_passes(tcx, &mut body); + // Now that drop elaboration has been performed, we can check for + // unconditional drop recursion. + rustc_mir_build::lints::check_drop_recursion(tcx, &body); + tcx.alloc_steal_mir(body) } -- cgit 1.4.1-3-g733a5 From e2230985b37981b87fd9f3c00199b70c3dfff95a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 4 Aug 2023 10:56:57 +0000 Subject: Do not run ConstProp on mir_for_ctfe. --- compiler/rustc_mir_transform/src/lib.rs | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'compiler/rustc_mir_transform/src') diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 734321e97d8..1ffc4597772 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -338,38 +338,9 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { return shim::build_adt_ctor(tcx, def.to_def_id()); } - let context = tcx - .hir() - .body_const_context(def) - .expect("mir_for_ctfe should not be used for runtime functions"); - let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone(); let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::Const); - - match context { - // Do not const prop functions, either they get executed at runtime or exported to metadata, - // so we run const prop on them, or they don't, in which case we const evaluate some control - // flow paths of the function and any errors in those paths will get emitted as const eval - // errors. - hir::ConstContext::ConstFn => {} - // Static items always get evaluated, so we can just let const eval see if any erroneous - // control flow paths get executed. - hir::ConstContext::Static(_) => {} - // Associated constants get const prop run so we detect common failure situations in the - // crate that defined the constant. - // Technically we want to not run on regular const items, but oli-obk doesn't know how to - // conveniently detect that at this point without looking at the HIR. - hir::ConstContext::Const => { - pm::run_passes( - tcx, - &mut body, - &[&const_prop::ConstProp], - Some(MirPhase::Runtime(RuntimePhase::Optimized)), - ); - } - } - pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None); body -- cgit 1.4.1-3-g733a5 From 02e10a054eb4b3d49dc9adf164a064e187654ad3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 5 Aug 2023 07:55:57 +0000 Subject: Steal MIR for CTFE when possible. --- compiler/rustc_mir_transform/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_mir_transform/src') diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 1ffc4597772..ccb67248822 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -338,7 +338,14 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { return shim::build_adt_ctor(tcx, def.to_def_id()); } - let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone(); + let body = tcx.mir_drops_elaborated_and_const_checked(def); + let body = match tcx.hir().body_const_context(def) { + // consts and statics do not have `optimized_mir`, so we can steal the body instead of + // cloning it. + Some(hir::ConstContext::Const | hir::ConstContext::Static(_)) => body.steal(), + Some(hir::ConstContext::ConstFn) => body.borrow().clone(), + None => bug!("`mir_for_ctfe` called on non-const {def:?}"), + }; let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::Const); pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None); -- cgit 1.4.1-3-g733a5 From 6df546281bf8ffc39df9430aa1717656dfbbcf7a Mon Sep 17 00:00:00 2001 From: ouz-a Date: Sat, 5 Aug 2023 12:02:39 +0300 Subject: cleanup misinformation regarding has_deref --- compiler/rustc_codegen_ssa/src/mir/place.rs | 2 +- compiler/rustc_const_eval/src/interpret/step.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 28 ++++++++++++++--------- compiler/rustc_mir_dataflow/src/value_analysis.rs | 2 +- compiler/rustc_mir_transform/src/add_retag.rs | 2 +- compiler/rustc_mir_transform/src/copy_prop.rs | 2 +- src/tools/clippy/clippy_lints/src/dereference.rs | 2 +- 7 files changed, 23 insertions(+), 17 deletions(-) (limited to 'compiler/rustc_mir_transform/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 64c6d17469b..e7c3906d977 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -441,7 +441,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::Place(place) => place, LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx), LocalRef::Operand(..) => { - if place_ref.has_deref() { + if place_ref.is_indirect_first_projection() { base = 1; let cg_base = self.codegen_consume( bx, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index ead172f04a3..9661caeded7 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -248,7 +248,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { AddressOf(_, place) => { // Figure out whether this is an addr_of of an already raw place. - let place_base_raw = if place.has_deref() { + let place_base_raw = if place.is_indirect_first_projection() { let ty = self.frame().body.local_decls[place.local].ty; ty.is_unsafe_ptr() } else { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c1f87d79b83..ddb5e248cdc 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1592,14 +1592,13 @@ impl<'tcx> Place<'tcx> { self.projection.iter().any(|elem| elem.is_indirect()) } - /// If MirPhase >= Derefered and if projection contains Deref, - /// It's guaranteed to be in the first place - pub fn has_deref(&self) -> bool { - // To make sure this is not accidentally used in wrong mir phase - debug_assert!( - self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref) - ); - self.projection.first() == Some(&PlaceElem::Deref) + /// Returns `true` if this `Place`'s first projection is `Deref`. + /// + /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later, + /// `Deref` projections can only occur as the first projection. In that case this method + /// is equivalent to `is_indirect`, but faster. + pub fn is_indirect_first_projection(&self) -> bool { + self.as_ref().is_indirect_first_projection() } /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or @@ -1672,9 +1671,16 @@ impl<'tcx> PlaceRef<'tcx> { self.projection.iter().any(|elem| elem.is_indirect()) } - /// If MirPhase >= Derefered and if projection contains Deref, - /// It's guaranteed to be in the first place - pub fn has_deref(&self) -> bool { + /// Returns `true` if this `Place`'s first projection is `Deref`. + /// + /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later, + /// `Deref` projections can only occur as the first projection. In that case this method + /// is equivalent to `is_indirect`, but faster. + pub fn is_indirect_first_projection(&self) -> bool { + // To make sure this is not accidentally used in wrong mir phase + debug_assert!( + self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref) + ); self.projection.first() == Some(&PlaceElem::Deref) } diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 8d78ec04821..17bb8fc37ad 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -839,7 +839,7 @@ impl Map { tail_elem: Option, f: &mut impl FnMut(ValueIndex), ) { - if place.has_deref() { + if place.is_indirect_first_projection() { // We do not track indirect places. return; } diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index d9e7339f1b2..75473ca53fb 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &body.local_decls; let needs_retag = |place: &Place<'tcx>| { - !place.has_deref() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway + !place.is_indirect_first_projection() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx) && !local_decls[place.local].is_deref_temp() }; diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 47d9f52bfb5..9a3798eea3b 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -154,7 +154,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) { if let Operand::Move(place) = *operand // A move out of a projection of a copy is equivalent to a copy of the original projection. - && !place.has_deref() + && !place.is_indirect_first_projection() && !self.fully_moved.contains(place.local) { *operand = Operand::Copy(place); diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index a5ec979ccd9..aeaf9fae891 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1170,7 +1170,7 @@ fn referent_used_exactly_once<'tcx>( && let [location] = *local_assignments(mir, local).as_slice() && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index) && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind - && !place.has_deref() + && !place.is_indirect_first_projection() // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710) && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none() { -- cgit 1.4.1-3-g733a5