diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-05-04 19:18:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-04 19:18:19 +0200 |
| commit | 0ac8ebdf11f7b288f3c62c12f97c57dd16f07808 (patch) | |
| tree | a3d41c2a8b44ba4049abde2acd0b96edeb864a2d | |
| parent | bf72b64b96a70b04d1a20096138856f525aaa7cf (diff) | |
| parent | 4ec76df4a9edc6c7a3a69a82bd3eab3881b70ffa (diff) | |
| download | rust-0ac8ebdf11f7b288f3c62c12f97c57dd16f07808.tar.gz rust-0ac8ebdf11f7b288f3c62c12f97c57dd16f07808.zip | |
Rollup merge of #110826 - cjgillot:place-mention-use, r=JakobDegen,lcnr
Make PlaceMention a non-mutating use. Fixes https://github.com/rust-lang/rust/issues/110781 r? `@JakobDegen` I don't agree with your statement in https://github.com/rust-lang/rust/issues/110781#issuecomment-1520841434. I suggest that we start fixing `PlaceContext` to be accurate enough for optimizations to use it. This structure is very convenient to use in visitors, and we perhaps have an opportunity to make it less of a footgun.
8 files changed, 49 insertions, 10 deletions
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 6259722b694..74e6ce37e97 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -54,7 +54,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not // contain dangling references. - PlaceContext::NonUse(NonUseContext::PlaceMention) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) | PlaceContext::NonUse(NonUseContext::AscribeUserTy) | PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 601589480d1..43107db2923 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -772,12 +772,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { match context { PlaceContext::MutatingUse(_) => ty::Invariant, - PlaceContext::NonUse(StorageDead | StorageLive | PlaceMention | VarDebugInfo) => { - ty::Invariant - } + PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant, PlaceContext::NonMutatingUse( - Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf - | Projection, + Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow + | AddressOf | Projection, ) => ty::Covariant, PlaceContext::NonUse(AscribeUserTy) => ty::Covariant, } diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 0334c7ff132..569599faa36 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -203,7 +203,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> self.assign(local, DefLocation::Body(location)); } - PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} + PlaceContext::NonUse(_) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) + | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} PlaceContext::NonMutatingUse( NonMutatingUseContext::Copy | NonMutatingUseContext::Move, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 0a9fcd898b9..8e8ca7874f5 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -410,7 +410,7 @@ macro_rules! make_mir_visitor { StatementKind::PlaceMention(place) => { self.visit_place( place, - PlaceContext::NonUse(NonUseContext::PlaceMention), + PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention), location ); } @@ -1251,6 +1251,11 @@ pub enum NonMutatingUseContext { UniqueBorrow, /// AddressOf for *const pointer. AddressOf, + /// PlaceMention statement. + /// + /// This statement is executed as a check that the `Place` is live without reading from it, + /// so it must be considered as a non-mutating use. + PlaceMention, /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place. /// For example, the projection `x.y` is not marked as a mutation in these cases: /// ```ignore (illustrative) @@ -1301,8 +1306,6 @@ pub enum NonUseContext { AscribeUserTy, /// The data of a user variable, for debug info. VarDebugInfo, - /// PlaceMention statement. - PlaceMention, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index bc67aa476f1..aeca0073304 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -197,6 +197,7 @@ impl DefUse { | NonMutatingUseContext::Copy | NonMutatingUseContext::Inspect | NonMutatingUseContext::Move + | NonMutatingUseContext::PlaceMention | NonMutatingUseContext::ShallowBorrow | NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::UniqueBorrow, diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index deec66bbaf3..b3a3a25ebe8 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -752,6 +752,7 @@ impl Visitor<'_> for CanConstProp { | NonMutatingUse(NonMutatingUseContext::Move) | NonMutatingUse(NonMutatingUseContext::Inspect) | NonMutatingUse(NonMutatingUseContext::Projection) + | NonMutatingUse(NonMutatingUseContext::PlaceMention) | NonUse(_) => {} // These could be propagated with a smarter analysis or just some careful thinking about diff --git a/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff new file mode 100644 index 00000000000..761c074ed94 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff @@ -0,0 +1,25 @@ +- // MIR for `main` before DeadStoreElimination ++ // MIR for `main` after DeadStoreElimination + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/place_mention.rs:+0:11: +0:11 + let mut _1: (&str, &str); // in scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + _1 = (const "Hello", const "World"); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + // mir::Constant + // + span: $DIR/place_mention.rs:8:19: 8:26 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + // mir::Constant + // + span: $DIR/place_mention.rs:8:28: 8:35 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + PlaceMention(_1); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 + StorageDead(_1); // scope 0 at $DIR/place_mention.rs:+3:36: +3:37 + _0 = const (); // scope 0 at $DIR/place_mention.rs:+0:11: +4:2 + return; // scope 0 at $DIR/place_mention.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dead-store-elimination/place_mention.rs b/tests/mir-opt/dead-store-elimination/place_mention.rs new file mode 100644 index 00000000000..59dc74454a4 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/place_mention.rs @@ -0,0 +1,9 @@ +// unit-test: DeadStoreElimination +// compile-flags: -Zmir-keep-place-mention + +// EMIT_MIR place_mention.main.DeadStoreElimination.diff +fn main() { + // Verify that we account for the `PlaceMention` statement as a use of the tuple, + // and don't remove it as a dead store. + let (_, _) = ("Hello", "World"); +} |
