Skip to content

Commit d79dee0

Browse files
committed
rustc_mir: also promote interior borrows, not just whole temps.
1 parent b9af400 commit d79dee0

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,10 +737,21 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
737737
// We might have a candidate for promotion.
738738
let candidate = Candidate::Ref(location);
739739
if self.can_promote() {
740-
// We can only promote direct borrows of temps.
740+
// We can only promote interior borrows of non-drop temps.
741+
let mut place = place;
742+
while let Place::Projection(ref proj) = *place {
743+
if proj.elem == ProjectionElem::Deref {
744+
break;
745+
}
746+
place = &proj.base;
747+
}
741748
if let Place::Local(local) = *place {
742749
if self.mir.local_kind(local) == LocalKind::Temp {
743-
self.promotion_candidates.push(candidate);
750+
if let Some(qualif) = self.temp_qualif[local] {
751+
if !qualif.intersects(Qualif::NEEDS_DROP) {
752+
self.promotion_candidates.push(candidate);
753+
}
754+
}
744755
}
745756
}
746757
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2018 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+
// compile-flags: -Z borrowck=compare
12+
13+
const ALL_THE_NUMS: [u32; 1] = [
14+
1
15+
];
16+
17+
#[inline(never)]
18+
fn array(i: usize) -> &'static u32 {
19+
return &ALL_THE_NUMS[i];
20+
}
21+
22+
#[inline(never)]
23+
fn tuple_field() -> &'static u32 {
24+
&(42,).0
25+
}
26+
27+
fn main() {
28+
assert_eq!(tuple_field().to_string(), "42");
29+
// assert_eq!(array(0).to_string(), "1");
30+
}

0 commit comments

Comments
 (0)