Skip to content

Commit 061bdb5

Browse files
committed
Auto merge of #46524 - eddyb:static-static, r=arielb1
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.
2 parents 5a2465e + 292c6ac commit 061bdb5

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

src/librustc_mir/transform/qualify_consts.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ use transform::{MirPass, MirSource};
4141
use super::promote_consts::{self, Candidate, TempState};
4242

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

68-
// Borrows of temporaries can be promoted only
69-
// if they have none of the above qualifications.
70-
const NEVER_PROMOTE = 0b111_1111;
71-
7271
// Const items can only have MUTABLE_INTERIOR
7372
// and NOT_PROMOTABLE without producing an error.
7473
const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits &
@@ -197,7 +196,17 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
197196
self.add(original);
198197
}
199198

200-
/// Check if an Place with the current qualifications could
199+
/// Check if a Local with the current qualifications is promotable.
200+
fn can_promote(&mut self) -> bool {
201+
// References to statics are allowed, but only in other statics.
202+
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
203+
(self.qualif - Qualif::STATIC_REF).is_empty()
204+
} else {
205+
self.qualif.is_empty()
206+
}
207+
}
208+
209+
/// Check if a Place with the current qualifications could
201210
/// be consumed, by either an operand or a Deref projection.
202211
fn try_consume(&mut self) -> bool {
203212
if self.qualif.intersects(Qualif::STATIC) && self.mode != Mode::Fn {
@@ -633,7 +642,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
633642

634643
// We might have a candidate for promotion.
635644
let candidate = Candidate::Ref(location);
636-
if !self.qualif.intersects(Qualif::NEVER_PROMOTE) {
645+
if self.can_promote() {
637646
// We can only promote direct borrows of temps.
638647
if let Place::Local(local) = *place {
639648
if self.mir.local_kind(local) == LocalKind::Temp {
@@ -745,7 +754,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
745754
this.visit_operand(arg, location);
746755
if is_shuffle && i == 2 && this.mode == Mode::Fn {
747756
let candidate = Candidate::ShuffleIndices(bb);
748-
if !this.qualif.intersects(Qualif::NEVER_PROMOTE) {
757+
if this.can_promote() {
749758
this.promotion_candidates.push(candidate);
750759
} else {
751760
span_err!(this.tcx.sess, this.span, E0526,

src/test/run-pass/issue-44373.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// compile-flags: -Z borrowck=compare
12+
1113
struct Foo(bool);
1214

1315
struct Container(&'static [&'static Foo]);

0 commit comments

Comments
 (0)