Skip to content

Commit

Permalink
Auto merge of #46524 - eddyb:static-static, r=arielb1
Browse files Browse the repository at this point in the history
rustc_mir: promote references of statics from other statics.

Fixes #46522 by also allowing `STATIC_REF` in MIR const-qualification, not just AST rvalue promotion.
  • Loading branch information
bors committed Dec 6, 2017
2 parents 5a2465e + 292c6ac commit 061bdb5
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
23 changes: 16 additions & 7 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ use transform::{MirPass, MirSource};
use super::promote_consts::{self, Candidate, TempState};

bitflags! {
// Borrows of temporaries can be promoted only if
// they have none of these qualifications, with
// the exception of `STATIC_REF` (in statics only).
struct Qualif: u8 {
// Constant containing interior mutability (UnsafeCell).
const MUTABLE_INTERIOR = 1 << 0;
Expand All @@ -65,10 +68,6 @@ bitflags! {
// promote_consts decided they weren't simple enough.
const NOT_PROMOTABLE = 1 << 6;

// Borrows of temporaries can be promoted only
// if they have none of the above qualifications.
const NEVER_PROMOTE = 0b111_1111;

// Const items can only have MUTABLE_INTERIOR
// and NOT_PROMOTABLE without producing an error.
const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits &
Expand Down Expand Up @@ -197,7 +196,17 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
self.add(original);
}

/// Check if an Place with the current qualifications could
/// Check if a Local with the current qualifications is promotable.
fn can_promote(&mut self) -> 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()
} else {
self.qualif.is_empty()
}
}

/// Check if a Place with the current qualifications could
/// be consumed, by either an operand or a Deref projection.
fn try_consume(&mut self) -> bool {
if self.qualif.intersects(Qualif::STATIC) && self.mode != Mode::Fn {
Expand Down Expand Up @@ -633,7 +642,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {

// We might have a candidate for promotion.
let candidate = Candidate::Ref(location);
if !self.qualif.intersects(Qualif::NEVER_PROMOTE) {
if self.can_promote() {
// We can only promote direct borrows of temps.
if let Place::Local(local) = *place {
if self.mir.local_kind(local) == LocalKind::Temp {
Expand Down Expand Up @@ -745,7 +754,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
this.visit_operand(arg, location);
if is_shuffle && i == 2 && this.mode == Mode::Fn {
let candidate = Candidate::ShuffleIndices(bb);
if !this.qualif.intersects(Qualif::NEVER_PROMOTE) {
if this.can_promote() {
this.promotion_candidates.push(candidate);
} else {
span_err!(this.tcx.sess, this.span, E0526,
Expand Down
2 changes: 2 additions & 0 deletions src/test/run-pass/issue-44373.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z borrowck=compare

struct Foo(bool);

struct Container(&'static [&'static Foo]);
Expand Down

0 comments on commit 061bdb5

Please sign in to comment.