Skip to content

Commit ac6dbff

Browse files
authored
Rollup merge of rust-lang#67333 - wesleywiser:fix_inline_into_box_place, r=oli-obk
[mir-opt] Fix `Inline` pass to handle inlining into `box` expressions r? @oli-obk Before, the test case just ICE'd here: https://github.com/rust-lang/rust/blob/a605441e049f0b6d5f7715b94b8ac4662fd7fcf6/src/librustc_mir/transform/inline.rs#L668
2 parents b50c3b7 + f1325a7 commit ac6dbff

9 files changed

+91
-10
lines changed

src/librustc_mir/transform/inline.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,9 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
663663

664664
fn make_integrate_local(&self, local: &Local) -> Local {
665665
if *local == RETURN_PLACE {
666-
match self.destination.as_local() {
667-
Some(l) => return l,
668-
ref place => bug!("Return place is {:?}, not local", place),
666+
match self.destination.base {
667+
PlaceBase::Local(l) => return l,
668+
PlaceBase::Static(ref s) => bug!("Return place is {:?}, not local", s),
669669
}
670670
}
671671

@@ -695,14 +695,24 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
695695
fn visit_place(
696696
&mut self,
697697
place: &mut Place<'tcx>,
698-
context: PlaceContext,
699-
location: Location,
698+
_context: PlaceContext,
699+
_location: Location,
700700
) {
701-
if let Some(RETURN_PLACE) = place.as_local() {
702-
// Return pointer; update the place itself
703-
*place = self.destination.clone();
704-
} else {
705-
self.super_place(place, context, location);
701+
match &mut place.base {
702+
PlaceBase::Static(_) => {},
703+
PlaceBase::Local(l) => {
704+
// If this is the `RETURN_PLACE`, we need to rebase any projections onto it.
705+
let dest_proj_len = self.destination.projection.len();
706+
if *l == RETURN_PLACE && dest_proj_len > 0 {
707+
let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len());
708+
projs.extend(self.destination.projection);
709+
projs.extend(place.projection);
710+
711+
place.projection = self.tcx.intern_place_elems(&*projs);
712+
}
713+
714+
*l = self.make_integrate_local(l);
715+
}
706716
}
707717
}
708718

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// ignore-tidy-linelength
2+
// ignore-wasm32-bare compiled with panic=abort by default
3+
#![feature(box_syntax)]
4+
5+
fn main() {
6+
let _x: Box<Vec<u32>> = box Vec::new();
7+
}
8+
9+
// END RUST SOURCE
10+
// START rustc.main.Inline.before.mir
11+
// let mut _0: ();
12+
// let _1: std::boxed::Box<std::vec::Vec<u32>> as UserTypeProjection { base: UserType(0), projs: [] };
13+
// let mut _2: std::boxed::Box<std::vec::Vec<u32>>;
14+
// let mut _3: ();
15+
// scope 1 {
16+
// debug _x => _1;
17+
// }
18+
// bb0: {
19+
// StorageLive(_1);
20+
// StorageLive(_2);
21+
// _2 = Box(std::vec::Vec<u32>);
22+
// (*_2) = const std::vec::Vec::<u32>::new() -> [return: bb2, unwind: bb4];
23+
// }
24+
// bb1 (cleanup): {
25+
// resume;
26+
// }
27+
// bb2: {
28+
// _1 = move _2;
29+
// StorageDead(_2);
30+
// _0 = ();
31+
// drop(_1) -> [return: bb3, unwind: bb1];
32+
// }
33+
// bb3: {
34+
// StorageDead(_1);
35+
// return;
36+
// }
37+
// bb4 (cleanup): {
38+
// _3 = const alloc::alloc::box_free::<std::vec::Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb1;
39+
// }
40+
// END rustc.main.Inline.before.mir
41+
// START rustc.main.Inline.after.mir
42+
// let mut _0: ();
43+
// let _1: std::boxed::Box<std::vec::Vec<u32>> as UserTypeProjection { base: UserType(0), projs: [] };
44+
// let mut _2: std::boxed::Box<std::vec::Vec<u32>>;
45+
// let mut _3: ();
46+
// let mut _4: &mut std::vec::Vec<u32>;
47+
// scope 1 {
48+
// debug _x => _1;
49+
// }
50+
// scope 2 {
51+
// }
52+
// bb0: {
53+
// StorageLive(_1);
54+
// StorageLive(_2);
55+
// _2 = Box(std::vec::Vec<u32>);
56+
// _4 = &mut (*_2);
57+
// ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32>::NEW;
58+
// ((*_4).1: usize) = const 0usize;
59+
// _1 = move _2;
60+
// StorageDead(_2);
61+
// _0 = ();
62+
// drop(_1) -> [return: bb2, unwind: bb1];
63+
// }
64+
// bb1 (cleanup): {
65+
// resume;
66+
// }
67+
// bb2: {
68+
// StorageDead(_1);
69+
// return;
70+
// }
71+
// END rustc.main.Inline.after.mir

0 commit comments

Comments
 (0)