Skip to content

Commit

Permalink
rustc_mir: allow promotion of promotable temps indexed at runtime.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed May 16, 2018
1 parent 22275f4 commit d1f117d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 10 deletions.
21 changes: 13 additions & 8 deletions src/librustc_mir/transform/qualify_consts.rs
Expand Up @@ -229,12 +229,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
}

/// Check if a Local with the current qualifications is promotable.
fn can_promote(&mut self) -> bool {
fn can_promote(&self, qualif: Qualif) -> bool {
// References to statics are allowed, but only in other statics.
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
(self.qualif - Qualif::STATIC_REF).is_empty()
(qualif - Qualif::STATIC_REF).is_empty()
} else {
self.qualif.is_empty()
qualif.is_empty()
}
}

Expand Down Expand Up @@ -746,10 +746,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {

if forbidden_mut {
self.add(Qualif::NOT_CONST);
} else if self.can_promote() {
} else {
// We might have a candidate for promotion.
let candidate = Candidate::Ref(location);
// We can only promote interior borrows of non-drop temps.
// We can only promote interior borrows of promotable temps.
let mut place = place;
while let Place::Projection(ref proj) = *place {
if proj.elem == ProjectionElem::Deref {
Expand All @@ -760,7 +760,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
if let Place::Local(local) = *place {
if self.mir.local_kind(local) == LocalKind::Temp {
if let Some(qualif) = self.temp_qualif[local] {
if !qualif.intersects(Qualif::NEEDS_DROP) {
// `forbidden_mut` is false, so we can safely ignore
// `MUTABLE_INTERIOR` from the local's qualifications.
// This allows borrowing fields which don't have
// `MUTABLE_INTERIOR`, from a type that does, e.g.:
// `let _: &'static _ = &(Cell::new(1), 2).1;`
if self.can_promote(qualif - Qualif::MUTABLE_INTERIOR) {
self.promotion_candidates.push(candidate);
}
}
Expand Down Expand Up @@ -920,7 +925,7 @@ This does not pose a problem by itself because they can't be accessed directly."
}
let candidate = Candidate::Argument { bb, index: i };
if is_shuffle && i == 2 {
if this.can_promote() {
if this.can_promote(this.qualif) {
this.promotion_candidates.push(candidate);
} else {
span_err!(this.tcx.sess, this.span, E0526,
Expand All @@ -936,7 +941,7 @@ This does not pose a problem by itself because they can't be accessed directly."
if !constant_arguments.contains(&i) {
return
}
if this.can_promote() {
if this.can_promote(this.qualif) {
this.promotion_candidates.push(candidate);
} else {
this.tcx.sess.span_err(this.span,
Expand Down
3 changes: 2 additions & 1 deletion src/test/mir-opt/match_false_edges.rs
Expand Up @@ -88,7 +88,8 @@ fn main() {
// }
// bb9: { // binding1 and guard
// StorageLive(_5);
// _5 = &((_2 as Some).0: i32);
// _11 = promoted[0];
// _5 = &(((*_11) as Some).0: i32);
// StorageLive(_8);
// _8 = const guard() -> [return: bb10, unwind: bb1];
// }
Expand Down
26 changes: 26 additions & 0 deletions src/test/run-pass/issue-49955-2.rs
@@ -0,0 +1,26 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z borrowck=mir

use std::cell::Cell;

#[inline(never)]
fn tuple_field() -> &'static u32 {
// This test is MIR-borrowck-only because the old borrowck
// doesn't agree that borrows of "frozen" (i.e. without any
// interior mutability) fields of non-frozen temporaries,
// should be promoted, while MIR promotion does promote them.
&(Cell::new(5), 42).1
}

fn main() {
assert_eq!(tuple_field().to_string(), "42");
}
2 changes: 1 addition & 1 deletion src/test/run-pass/issue-49955.rs
Expand Up @@ -26,5 +26,5 @@ fn tuple_field() -> &'static u32 {

fn main() {
assert_eq!(tuple_field().to_string(), "42");
// assert_eq!(array(0).to_string(), "1");
assert_eq!(array(0).to_string(), "1");
}

0 comments on commit d1f117d

Please sign in to comment.