Auto merge of #65728 - ecstatic-morse:promotion-const-proj, r=eddyb

Fix promotion in a `const` when projections are present

Resolves #65727.

This marks the entire local as "needs promotion" when only a projection of that local appears in a promotable context. This should only affect promotion in a `const` or `static`, not in a `fn` or `const fn`, which is handled in `promote_consts.rs`.

r? @eddyb
This commit is contained in:
bors 2019-11-06 18:12:57 +00:00
commit 38048763e8
2 changed files with 22 additions and 19 deletions

View file

@ -1066,32 +1066,23 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
} else {
self.valid_promotion_candidates()
};
debug!("qualify_const: promotion_candidates={:?}", promotion_candidates);
for candidate in promotion_candidates {
match candidate {
Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => {
if let StatementKind::Assign(box(_, Rvalue::Repeat(
Operand::Move(place),
_
))) = &self.body[bb].statements[stmt_idx].kind {
if let Some(index) = place.as_local() {
promoted_temps.insert(index);
}
}
}
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
if let StatementKind::Assign(
box(
_,
Rvalue::Ref(_, _, place)
)
) = &self.body[bb].statements[stmt_idx].kind {
if let Some(index) = place.as_local() {
promoted_temps.insert(index);
if let StatementKind::Assign(box( _, Rvalue::Ref(_, _, place)))
= &self.body[bb].statements[stmt_idx].kind
{
if let PlaceBase::Local(local) = place.base {
promoted_temps.insert(local);
}
}
}
Candidate::Argument { .. } => {}
// Only rvalue-static promotion requires extending the lifetime of the promoted
// local.
Candidate::Argument { .. } | Candidate::Repeat(_) => {}
}
}

View file

@ -0,0 +1,12 @@
// run-pass
// From https://github.com/rust-lang/rust/issues/65727
const _: &i32 = {
let x = &(5, false).0;
x
};
fn main() {
let _: &'static i32 = &(5, false).0;
}