Skip to content

Commit e5a91b7

Browse files
committed
mir: don't attempt to promote Unpromotable constant temps.
1 parent d658809 commit e5a91b7

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

src/librustc_mir/transform/qualify_consts.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,18 @@ bitflags! {
6565
// pointer comparisons, ptr-to-int casts, etc.
6666
const NOT_CONST = 1 << 6,
6767

68+
// Refers to temporaries which cannot be promoted as
69+
// promote_consts decided they weren't simple enough.
70+
const NOT_PROMOTABLE = 1 << 7,
71+
6872
// Borrows of temporaries can be promoted only
6973
// if they have none of the above qualifications.
70-
const UNPROMOTABLE = !0,
74+
const NEVER_PROMOTE = !0,
7175

7276
// Const items can only have MUTABLE_INTERIOR
73-
// without producing an error.
74-
const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits
77+
// and NOT_PROMOTABLE without producing an error.
78+
const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits &
79+
!Qualif::NOT_PROMOTABLE.bits
7580
}
7681
}
7782

@@ -502,6 +507,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> {
502507
self.add(Qualif::NOT_CONST);
503508
}
504509
Lvalue::Temp(index) => {
510+
if !self.temp_promotion_state[index as usize].is_promotable() {
511+
self.add(Qualif::NOT_PROMOTABLE);
512+
}
513+
505514
if let Some(qualif) = self.temp_qualif[index as usize] {
506515
self.add(qualif);
507516
} else {
@@ -687,8 +696,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> {
687696
// We might have a candidate for promotion.
688697
let candidate = Candidate::Ref(self.location);
689698
if self.mode == Mode::Fn || self.mode == Mode::ConstFn {
690-
if !self.qualif.intersects(Qualif::UNPROMOTABLE) {
691-
self.promotion_candidates.push(candidate);
699+
if !self.qualif.intersects(Qualif::NEVER_PROMOTE) {
700+
// We can only promote direct borrows of temps.
701+
if let Lvalue::Temp(_) = *lvalue {
702+
self.promotion_candidates.push(candidate);
703+
}
692704
}
693705
}
694706
}
@@ -780,7 +792,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> {
780792
this.visit_operand(arg);
781793
if is_shuffle && i == 2 && this.mode == Mode::Fn {
782794
let candidate = Candidate::ShuffleIndices(bb);
783-
if !this.qualif.intersects(Qualif::UNPROMOTABLE) {
795+
if !this.qualif.intersects(Qualif::NEVER_PROMOTE) {
784796
this.promotion_candidates.push(candidate);
785797
} else {
786798
span_err!(this.tcx.sess, this.span, E0526,

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

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(const_fn)]
12+
13+
const fn foo() -> *const i8 {
14+
b"foo" as *const _ as *const i8
15+
}
16+
17+
const fn bar() -> i32 {
18+
*&{(1, 2, 3).1}
19+
}
20+
21+
fn main() {
22+
assert_eq!(foo(), b"foo" as *const _ as *const i8);
23+
assert_eq!(bar(), 2);
24+
}

0 commit comments

Comments
 (0)