From fab0caf1723b243e6446ddca669b30b241daf313 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 23 Oct 2019 09:46:52 -0700 Subject: [PATCH 1/3] Mark entire local as promoted even if only part is used --- src/librustc_mir/transform/qualify_consts.rs | 34 +++++++++----------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index f488b457334e..5dbb4d8d73e3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1067,30 +1067,28 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { }; debug!("qualify_const: promotion_candidates={:?}", promotion_candidates); for candidate in promotion_candidates { - match candidate { + let promoted_place = 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); - } + match &self.body[bb].statements[stmt_idx].kind { + StatementKind::Assign(box(_, Rvalue::Repeat(Operand::Move(place), _))) + => place, + _ => continue, } } 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); - } + match &self.body[bb].statements[stmt_idx].kind { + StatementKind::Assign(box( _, Rvalue::Ref(_, _, place))) => place, + _ => continue, } } - Candidate::Argument { .. } => {} + Candidate::Argument { .. } => continue, + }; + + match promoted_place.base { + PlaceBase::Local(local) if !promoted_place.is_indirect() => { + promoted_temps.insert(local); + } + _ => {} } } From d6431f69ad2d05e9aa2d5a316c1b4fcaf85f24aa Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 23 Oct 2019 09:55:20 -0700 Subject: [PATCH 2/3] Test that borrows of projections are promoted everywhere Previously, this worked in `fn`s but not `const`s or `static`s. --- src/test/ui/consts/promote_borrowed_field.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/test/ui/consts/promote_borrowed_field.rs diff --git a/src/test/ui/consts/promote_borrowed_field.rs b/src/test/ui/consts/promote_borrowed_field.rs new file mode 100644 index 000000000000..c4841b46f60d --- /dev/null +++ b/src/test/ui/consts/promote_borrowed_field.rs @@ -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; +} From 420457e5ca9e724b045fc45f6b05dac8476a5ef4 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 23 Oct 2019 10:30:51 -0700 Subject: [PATCH 3/3] Don't extend lifetime of temp in `Repeat` expressions --- src/librustc_mir/transform/qualify_consts.rs | 29 ++++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 5dbb4d8d73e3..353ce8846564 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1065,30 +1065,23 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } else { self.valid_promotion_candidates() }; + debug!("qualify_const: promotion_candidates={:?}", promotion_candidates); for candidate in promotion_candidates { - let promoted_place = match candidate { - Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => { - match &self.body[bb].statements[stmt_idx].kind { - StatementKind::Assign(box(_, Rvalue::Repeat(Operand::Move(place), _))) - => place, - _ => continue, - } - } + match candidate { Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => { - match &self.body[bb].statements[stmt_idx].kind { - StatementKind::Assign(box( _, Rvalue::Ref(_, _, place))) => place, - _ => continue, + 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 { .. } => continue, - }; - match promoted_place.base { - PlaceBase::Local(local) if !promoted_place.is_indirect() => { - promoted_temps.insert(local); - } - _ => {} + // Only rvalue-static promotion requires extending the lifetime of the promoted + // local. + Candidate::Argument { .. } | Candidate::Repeat(_) => {} } }