mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Rollup merge of #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:
a605441e04/src/librustc_mir/transform/inline.rs (L668)
This commit is contained in:
commit
ac6dbff45e
@ -663,9 +663,9 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
|
||||
|
||||
fn make_integrate_local(&self, local: &Local) -> Local {
|
||||
if *local == RETURN_PLACE {
|
||||
match self.destination.as_local() {
|
||||
Some(l) => return l,
|
||||
ref place => bug!("Return place is {:?}, not local", place),
|
||||
match self.destination.base {
|
||||
PlaceBase::Local(l) => return l,
|
||||
PlaceBase::Static(ref s) => bug!("Return place is {:?}, not local", s),
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,14 +695,24 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
|
||||
fn visit_place(
|
||||
&mut self,
|
||||
place: &mut Place<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location,
|
||||
_context: PlaceContext,
|
||||
_location: Location,
|
||||
) {
|
||||
if let Some(RETURN_PLACE) = place.as_local() {
|
||||
// Return pointer; update the place itself
|
||||
*place = self.destination.clone();
|
||||
} else {
|
||||
self.super_place(place, context, location);
|
||||
match &mut place.base {
|
||||
PlaceBase::Static(_) => {},
|
||||
PlaceBase::Local(l) => {
|
||||
// If this is the `RETURN_PLACE`, we need to rebase any projections onto it.
|
||||
let dest_proj_len = self.destination.projection.len();
|
||||
if *l == RETURN_PLACE && dest_proj_len > 0 {
|
||||
let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len());
|
||||
projs.extend(self.destination.projection);
|
||||
projs.extend(place.projection);
|
||||
|
||||
place.projection = self.tcx.intern_place_elems(&*projs);
|
||||
}
|
||||
|
||||
*l = self.make_integrate_local(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
71
src/test/mir-opt/inline/inline-into-box-place.rs
Normal file
71
src/test/mir-opt/inline/inline-into-box-place.rs
Normal file
@ -0,0 +1,71 @@
|
||||
// ignore-tidy-linelength
|
||||
// ignore-wasm32-bare compiled with panic=abort by default
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
let _x: Box<Vec<u32>> = box Vec::new();
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.Inline.before.mir
|
||||
// let mut _0: ();
|
||||
// let _1: std::boxed::Box<std::vec::Vec<u32>> as UserTypeProjection { base: UserType(0), projs: [] };
|
||||
// let mut _2: std::boxed::Box<std::vec::Vec<u32>>;
|
||||
// let mut _3: ();
|
||||
// scope 1 {
|
||||
// debug _x => _1;
|
||||
// }
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// StorageLive(_2);
|
||||
// _2 = Box(std::vec::Vec<u32>);
|
||||
// (*_2) = const std::vec::Vec::<u32>::new() -> [return: bb2, unwind: bb4];
|
||||
// }
|
||||
// bb1 (cleanup): {
|
||||
// resume;
|
||||
// }
|
||||
// bb2: {
|
||||
// _1 = move _2;
|
||||
// StorageDead(_2);
|
||||
// _0 = ();
|
||||
// drop(_1) -> [return: bb3, unwind: bb1];
|
||||
// }
|
||||
// bb3: {
|
||||
// StorageDead(_1);
|
||||
// return;
|
||||
// }
|
||||
// bb4 (cleanup): {
|
||||
// _3 = const alloc::alloc::box_free::<std::vec::Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb1;
|
||||
// }
|
||||
// END rustc.main.Inline.before.mir
|
||||
// START rustc.main.Inline.after.mir
|
||||
// let mut _0: ();
|
||||
// let _1: std::boxed::Box<std::vec::Vec<u32>> as UserTypeProjection { base: UserType(0), projs: [] };
|
||||
// let mut _2: std::boxed::Box<std::vec::Vec<u32>>;
|
||||
// let mut _3: ();
|
||||
// let mut _4: &mut std::vec::Vec<u32>;
|
||||
// scope 1 {
|
||||
// debug _x => _1;
|
||||
// }
|
||||
// scope 2 {
|
||||
// }
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// StorageLive(_2);
|
||||
// _2 = Box(std::vec::Vec<u32>);
|
||||
// _4 = &mut (*_2);
|
||||
// ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32>::NEW;
|
||||
// ((*_4).1: usize) = const 0usize;
|
||||
// _1 = move _2;
|
||||
// StorageDead(_2);
|
||||
// _0 = ();
|
||||
// drop(_1) -> [return: bb2, unwind: bb1];
|
||||
// }
|
||||
// bb1 (cleanup): {
|
||||
// resume;
|
||||
// }
|
||||
// bb2: {
|
||||
// StorageDead(_1);
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main.Inline.after.mir
|
Loading…
Reference in New Issue
Block a user