Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: You need edition 2015 or 2018 to reproduce this. `
Looks to me like the problem is that doesn't realize that a makes the place not dead.
The bug is . is a nonuse, but should get the same treatment as a . I feel obligated to mention that I have repeatedly warned that these bugs are going to happen. We should really stop using in optimizations. It was written for borrowck. (To be clear: I am as much at fault for this as anyone, I originally wrote this code).
I was wondering why always has strangely unhelpful information for optimizations...
Why is this not just a bug in PlaceContext assignment?
See my comment in the PR - in general, my understanding is that the definition of placecontext is what it is because that's what makes sense in some other part of the compiler. If we start changing placecontext now to have the information that's useful to optimizations, I worry we'll just end up making those parts of the compiler buggy

Discussion:
// `PlaceMention` and `AscribeUserType` both evaluate the place, which must not // contain dangling references. <del> PlaceContext::NonUse(NonUseContext::PlaceMention) | </del> <ins> PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) | </ins> PlaceContext::NonUse(NonUseContext::AscribeUserTy) | PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |

match context { PlaceContext::MutatingUse(_) => ty::Invariant, <del> PlaceContext::NonUse(StorageDead | StorageLive | PlaceMention | VarDebugInfo) => { ty::Invariant } </del> <ins> PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant, </ins> PlaceContext::NonMutatingUse( <del> Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf | Projection, </del> <ins> Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf | Projection, </ins> ) => ty::Covariant, PlaceContext::NonUse(AscribeUserTy) => ty::Covariant, }

self.assign(local, DefLocation::Body(location)); } <del> PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} </del> <ins> PlaceContext::NonUse(_) | PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} </ins> PlaceContext::NonMutatingUse( NonMutatingUseContext::Copy | NonMutatingUseContext::Move,

StatementKind::PlaceMention(place) => { self.visit_place( place, <del> PlaceContext::NonUse(NonUseContext::PlaceMention), </del> <ins> PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention), </ins> location ); }

UniqueBorrow, /// AddressOf for *const pointer. AddressOf, <ins> /// 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, </ins> /// 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)

AscribeUserTy, /// The data of a user variable, for debug info. VarDebugInfo, <del> /// PlaceMention statement. PlaceMention, </del> } #[derive(Copy, Clone, Debug, PartialEq, Eq)]

| NonMutatingUseContext::Copy | NonMutatingUseContext::Inspect | NonMutatingUseContext::Move <ins> | NonMutatingUseContext::PlaceMention </ins> | NonMutatingUseContext::ShallowBorrow | NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::UniqueBorrow,

| NonMutatingUse(NonMutatingUseContext::Move) | NonMutatingUse(NonMutatingUseContext::Inspect) | NonMutatingUse(NonMutatingUseContext::Projection) <ins> | NonMutatingUse(NonMutatingUseContext::PlaceMention) </ins> | NonUse(_) => {} // These could be propagated with a smarter analysis or just some careful thinking about

<ins> - // 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 } } </ins>

<ins> // 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"); } </ins>