mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
validate derefer, run derefer inside generator
This commit is contained in:
parent
abc7681a76
commit
e71913e847
@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{
|
||||
traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, Local, Location, MirPass,
|
||||
@ -302,9 +303,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
self.super_projection_elem(local, proj_base, elem, context, location);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, _: PlaceContext, _: Location) {
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) {
|
||||
// Set off any `bug!`s in the type computation code
|
||||
let _ = place.ty(&self.body.local_decls, self.tcx);
|
||||
|
||||
if self.mir_phase >= MirPhase::Derefered
|
||||
&& place.projection.len() > 1
|
||||
&& cntxt != PlaceContext::NonUse(VarDebugInfo)
|
||||
&& place.projection[1..].contains(&ProjectionElem::Deref)
|
||||
{
|
||||
self.fail(location, format!("{:?}, has deref at the wrong place", place));
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
|
@ -172,12 +172,14 @@ pub enum MirPhase {
|
||||
/// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands
|
||||
/// are allowed for non-`Copy` types.
|
||||
DropsLowered = 3,
|
||||
/// After this projections may only contain deref projections as the first element.
|
||||
Derefered = 4,
|
||||
/// Beginning with this phase, the following variant is disallowed:
|
||||
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
|
||||
///
|
||||
/// And the following variant is allowed:
|
||||
/// * [`StatementKind::SetDiscriminant`]
|
||||
Deaggregated = 4,
|
||||
Deaggregated = 5,
|
||||
/// Before this phase, generators are in the "source code" form, featuring `yield` statements
|
||||
/// and such. With this phase change, they are transformed into a proper state machine. Running
|
||||
/// optimizations before this change can be potentially dangerous because the source code is to
|
||||
@ -191,8 +193,8 @@ pub enum MirPhase {
|
||||
/// Beginning with this phase, the following variants are disallowed:
|
||||
/// * [`TerminatorKind::Yield`](terminator::TerminatorKind::Yield)
|
||||
/// * [`TerminatorKind::GeneratorDrop`](terminator::TerminatorKind::GeneratorDrop)
|
||||
GeneratorsLowered = 5,
|
||||
Optimized = 6,
|
||||
GeneratorsLowered = 6,
|
||||
Optimized = 7,
|
||||
}
|
||||
|
||||
impl MirPhase {
|
||||
|
@ -1,9 +1,11 @@
|
||||
use crate::MirPass;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::mir::patch::MirPatch;
|
||||
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
|
||||
use rustc_middle::mir::visit::{MutVisitor, PlaceContext};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct Derefer;
|
||||
|
||||
pub struct DerefChecker<'tcx> {
|
||||
@ -17,63 +19,68 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, loc: Location) {
|
||||
let mut place_local = place.local;
|
||||
let mut last_len = 0;
|
||||
let mut last_deref_idx = 0;
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, cntxt: PlaceContext, loc: Location) {
|
||||
if !place.projection.is_empty()
|
||||
&& cntxt != PlaceContext::NonUse(VarDebugInfo)
|
||||
&& place.projection[1..].contains(&ProjectionElem::Deref)
|
||||
{
|
||||
let mut place_local = place.local;
|
||||
let mut last_len = 0;
|
||||
let mut last_deref_idx = 0;
|
||||
|
||||
let mut prev_temp: Option<Local> = None;
|
||||
let mut prev_temp: Option<Local> = None;
|
||||
|
||||
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
||||
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
|
||||
last_deref_idx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
||||
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
|
||||
let ty = p_ref.ty(&self.local_decls, self.tcx).ty;
|
||||
let temp = self.patcher.new_local_with_info(
|
||||
ty,
|
||||
self.local_decls[p_ref.local].source_info.span,
|
||||
Some(Box::new(LocalInfo::DerefTemp)),
|
||||
);
|
||||
|
||||
self.patcher.add_statement(loc, StatementKind::StorageLive(temp));
|
||||
|
||||
// We are adding current p_ref's projections to our
|
||||
// temp value, excluding projections we already covered.
|
||||
let deref_place = Place::from(place_local)
|
||||
.project_deeper(&p_ref.projection[last_len..], self.tcx);
|
||||
|
||||
self.patcher.add_assign(
|
||||
loc,
|
||||
Place::from(temp),
|
||||
Rvalue::Use(Operand::Move(deref_place)),
|
||||
);
|
||||
place_local = temp;
|
||||
last_len = p_ref.projection.len();
|
||||
|
||||
// Change `Place` only if we are actually at the Place's last deref
|
||||
if idx == last_deref_idx {
|
||||
let temp_place =
|
||||
Place::from(temp).project_deeper(&place.projection[idx..], self.tcx);
|
||||
*place = temp_place;
|
||||
for (idx, elem) in place.projection[0..].iter().enumerate() {
|
||||
if *elem == ProjectionElem::Deref {
|
||||
last_deref_idx = idx;
|
||||
}
|
||||
|
||||
// We are destroying the previous temp since it's no longer used.
|
||||
if let Some(prev_temp) = prev_temp {
|
||||
self.patcher.add_statement(loc, StatementKind::StorageDead(prev_temp));
|
||||
}
|
||||
|
||||
prev_temp = Some(temp);
|
||||
}
|
||||
}
|
||||
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
||||
if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref {
|
||||
let ty = p_ref.ty(&self.local_decls, self.tcx).ty;
|
||||
let temp = self.patcher.new_local_with_info(
|
||||
ty,
|
||||
self.local_decls[p_ref.local].source_info.span,
|
||||
Some(Box::new(LocalInfo::DerefTemp)),
|
||||
);
|
||||
|
||||
// Since we won't be able to reach final temp, we destroy it outside the loop.
|
||||
if let Some(prev_temp) = prev_temp {
|
||||
let last_loc = Location { block: loc.block, statement_index: loc.statement_index + 1 };
|
||||
self.patcher.add_statement(last_loc, StatementKind::StorageDead(prev_temp));
|
||||
self.patcher.add_statement(loc, StatementKind::StorageLive(temp));
|
||||
|
||||
// We are adding current p_ref's projections to our
|
||||
// temp value, excluding projections we already covered.
|
||||
let deref_place = Place::from(place_local)
|
||||
.project_deeper(&p_ref.projection[last_len..], self.tcx);
|
||||
|
||||
self.patcher.add_assign(
|
||||
loc,
|
||||
Place::from(temp),
|
||||
Rvalue::Use(Operand::Move(deref_place)),
|
||||
);
|
||||
place_local = temp;
|
||||
last_len = p_ref.projection.len();
|
||||
|
||||
// Change `Place` only if we are actually at the Place's last deref
|
||||
if idx == last_deref_idx {
|
||||
let temp_place =
|
||||
Place::from(temp).project_deeper(&place.projection[idx..], self.tcx);
|
||||
*place = temp_place;
|
||||
}
|
||||
|
||||
// We are destroying the previous temp since it's no longer used.
|
||||
if let Some(prev_temp) = prev_temp {
|
||||
self.patcher.add_statement(loc, StatementKind::StorageDead(prev_temp));
|
||||
}
|
||||
|
||||
prev_temp = Some(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// Since we won't be able to reach final temp, we destroy it outside the loop.
|
||||
if let Some(prev_temp) = prev_temp {
|
||||
let last_loc =
|
||||
Location { block: loc.block, statement_index: loc.statement_index + 1 };
|
||||
self.patcher.add_statement(last_loc, StatementKind::StorageDead(prev_temp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,5 +99,6 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
impl<'tcx> MirPass<'tcx> for Derefer {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
deref_finder(tcx, body);
|
||||
body.phase = MirPhase::Derefered;
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@
|
||||
//! For generators with state 1 (returned) and state 2 (poisoned) it does nothing.
|
||||
//! Otherwise it drops all the values in scope at the last suspension point.
|
||||
|
||||
use crate::deref_separator::deref_finder;
|
||||
use crate::simplify;
|
||||
use crate::util::expand_aggregate;
|
||||
use crate::MirPass;
|
||||
@ -1368,6 +1369,9 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||
|
||||
// Create the Generator::resume function
|
||||
create_generator_resume_function(tcx, transform, body, can_return);
|
||||
|
||||
// Run derefer to fix Derefs that are not in the first place
|
||||
deref_finder(tcx, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Inlining pass for MIR functions
|
||||
|
||||
use crate::deref_separator::deref_finder;
|
||||
use rustc_attr::InlineAttr;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_index::vec::Idx;
|
||||
@ -53,6 +53,7 @@ impl<'tcx> MirPass<'tcx> for Inline {
|
||||
debug!("running simplify cfg on {:?}", body.source);
|
||||
CfgSimplifier::new(body).simplify();
|
||||
remove_dead_blocks(tcx, body);
|
||||
deref_finder(tcx, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
69
src/test/mir-opt/derefer_inline_test.main.Derefer.diff
Normal file
69
src/test/mir-opt/derefer_inline_test.main.Derefer.diff
Normal file
@ -0,0 +1,69 @@
|
||||
- // MIR for `main` before Derefer
|
||||
+ // MIR for `main` after Derefer
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/derefer_inline_test.rs:9:11: 9:11
|
||||
let _1: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
let mut _2: usize; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
let mut _3: usize; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
let mut _4: *mut u8; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
let mut _5: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
let mut _6: (); // in scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
scope 1 {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
_2 = SizeOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
_3 = AlignOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
// mir::Constant
|
||||
// + span: $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_5); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
_5 = ShallowInitBox(move _4, std::boxed::Box<u32>); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
(*_5) = f() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:10:9: 10:12
|
||||
// mir::Constant
|
||||
// + span: $DIR/derefer_inline_test.rs:10:9: 10:10
|
||||
// + literal: Const { ty: fn() -> Box<u32> {f}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_1 = move _5; // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
|
||||
goto -> bb3; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_5); // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_1); // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13
|
||||
_0 = const (); // scope 0 at $DIR/derefer_inline_test.rs:9:11: 11:2
|
||||
return; // scope 0 at $DIR/derefer_inline_test.rs:11:2: 11:2
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
goto -> bb8; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
}
|
||||
|
||||
bb6 (cleanup): {
|
||||
resume; // scope 0 at $DIR/derefer_inline_test.rs:9:1: 11:2
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
_6 = alloc::alloc::box_free::<Box<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::boxed::Box<u32>>), move (_5.1: std::alloc::Global)) -> bb6; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
// mir::Constant
|
||||
// + span: $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
// + literal: Const { ty: unsafe fn(Unique<Box<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Box<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb8 (cleanup): {
|
||||
goto -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
|
||||
}
|
||||
}
|
||||
|
11
src/test/mir-opt/derefer_inline_test.rs
Normal file
11
src/test/mir-opt/derefer_inline_test.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// EMIT_MIR derefer_inline_test.main.Derefer.diff
|
||||
// ignore-wasm32 compiled with panic=abort by default
|
||||
|
||||
#![feature(box_syntax)]
|
||||
#[inline]
|
||||
fn f() -> Box<u32> {
|
||||
box 0
|
||||
}
|
||||
fn main() {
|
||||
box f();
|
||||
}
|
@ -57,6 +57,10 @@
|
||||
StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:34:24: 34:25
|
||||
StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:35:1: 35:2
|
||||
return; // scope 0 at $DIR/dyn-trait.rs:35:2: 35:2
|
||||
+ }
|
||||
+
|
||||
+ bb3 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/dyn-trait.rs:32:1: 35:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,10 @@
|
||||
+ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:21:21: 21:22
|
||||
StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:27:15: 27:16
|
||||
return; // scope 0 at $DIR/dyn-trait.rs:28:2: 28:2
|
||||
+ }
|
||||
+
|
||||
+ bb2 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/dyn-trait.rs:26:1: 28:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,4 +41,8 @@ fn bar() -> bool {
|
||||
StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:13:1: 13:2
|
||||
return; // scope 0 at $DIR/inline-any-operand.rs:13:2: 13:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-any-operand.rs:10:1: 13:2
|
||||
}
|
||||
}
|
||||
|
@ -46,4 +46,8 @@ fn foo(_1: T, _2: i32) -> i32 {
|
||||
StorageDead(_3); // scope 0 at $DIR/inline-closure.rs:13:1: 13:2
|
||||
return; // scope 0 at $DIR/inline-closure.rs:13:2: 13:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-closure.rs:10:1: 13:2
|
||||
}
|
||||
}
|
||||
|
@ -53,4 +53,8 @@ fn foo(_1: T, _2: &i32) -> i32 {
|
||||
StorageDead(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:17:1: 17:2
|
||||
return; // scope 0 at $DIR/inline-closure-borrows-arg.rs:17:2: 17:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-closure-borrows-arg.rs:11:1: 17:2
|
||||
}
|
||||
}
|
||||
|
@ -66,4 +66,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
|
||||
StorageDead(_3); // scope 0 at $DIR/inline-closure-captures.rs:13:1: 13:2
|
||||
return; // scope 0 at $DIR/inline-closure-captures.rs:13:2: 13:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-closure-captures.rs:10:1: 13:2
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,10 @@
|
||||
StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:24:18: 24:19
|
||||
_0 = const (); // scope 0 at $DIR/inline-compatibility.rs:23:37: 25:2
|
||||
return; // scope 0 at $DIR/inline-compatibility.rs:25:2: 25:2
|
||||
+ }
|
||||
+
|
||||
+ bb1 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-compatibility.rs:23:1: 25:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:13:21: 13:22
|
||||
_0 = const (); // scope 0 at $DIR/inline-compatibility.rs:12:40: 14:2
|
||||
return; // scope 0 at $DIR/inline-compatibility.rs:14:2: 14:2
|
||||
+ }
|
||||
+
|
||||
+ bb1 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-compatibility.rs:12:1: 14:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@
|
||||
StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:14:24: 14:25
|
||||
_0 = const (); // scope 0 at $DIR/inline-cycle.rs:13:10: 15:2
|
||||
return; // scope 0 at $DIR/inline-cycle.rs:15:2: 15:2
|
||||
+ }
|
||||
+
|
||||
+ bb2 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-cycle.rs:13:1: 15:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,10 @@
|
||||
StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:49:12: 49:13
|
||||
_0 = const (); // scope 0 at $DIR/inline-cycle.rs:48:10: 50:2
|
||||
return; // scope 0 at $DIR/inline-cycle.rs:50:2: 50:2
|
||||
+ }
|
||||
+
|
||||
+ bb2 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-cycle.rs:48:1: 50:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
+
|
||||
+ bb1: {
|
||||
+ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:39:5: 39:12
|
||||
+ }
|
||||
+
|
||||
+ bb2 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-diverging.rs:7:1: 9:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,10 @@
|
||||
+ // mir::Constant
|
||||
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
|
||||
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
|
||||
+ }
|
||||
+
|
||||
+ bb3 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-diverging.rs:12:1: 18:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,10 @@
|
||||
+
|
||||
+ bb1: {
|
||||
+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
|
||||
+ }
|
||||
+
|
||||
+ bb2 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-diverging.rs:21:1: 23:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,9 @@
|
||||
+ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:15:9: 15:9
|
||||
+ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7
|
||||
+ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
@ -73,7 +76,10 @@
|
||||
+ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
|
||||
+ StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
|
||||
+ StorageLive(_12); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
|
||||
+ _12 = discriminant((*(_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]))); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ StorageLive(_13); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ _13 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ StorageDead(_13); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
+ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
|
||||
}
|
||||
|
||||
@ -118,7 +124,10 @@
|
||||
+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ discriminant((*(_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]))) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ StorageLive(_14); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ _14 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ StorageDead(_14); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39
|
||||
+ }
|
||||
+
|
||||
@ -129,7 +138,10 @@
|
||||
+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ discriminant((*(_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]))) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ StorageLive(_15); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ _15 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ StorageDead(_15); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41
|
||||
+ }
|
||||
+
|
||||
|
@ -39,6 +39,10 @@
|
||||
StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:53:30: 53:31
|
||||
_0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:50:18: 54:2
|
||||
return; // scope 0 at $DIR/inline-instruction-set.rs:54:2: 54:2
|
||||
+ }
|
||||
+
|
||||
+ bb3 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-instruction-set.rs:50:1: 54:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,10 @@
|
||||
StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:46:30: 46:31
|
||||
_0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:41:14: 47:2
|
||||
return; // scope 0 at $DIR/inline-instruction-set.rs:47:2: 47:2
|
||||
+ }
|
||||
+
|
||||
+ bb3 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-instruction-set.rs:41:1: 47:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,4 +52,8 @@ fn main() -> () {
|
||||
_0 = const (); // scope 0 at $DIR/inline-options.rs:8:11: 11:2
|
||||
return; // scope 0 at $DIR/inline-options.rs:11:2: 11:2
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-options.rs:8:1: 11:2
|
||||
}
|
||||
}
|
||||
|
@ -69,4 +69,8 @@ fn bar() -> bool {
|
||||
StorageDead(_4); // scope 0 at $DIR/inline-retag.rs:13:1: 13:2
|
||||
return; // scope 0 at $DIR/inline-retag.rs:13:2: 13:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-retag.rs:10:1: 13:2
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,10 @@
|
||||
+ _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL
|
||||
StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:6:13: 6:14
|
||||
return; // scope 0 at $DIR/inline-shims.rs:7:2: 7:2
|
||||
+ }
|
||||
+
|
||||
+ bb1 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-shims.rs:5:1: 7:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,10 @@
|
||||
+
|
||||
+ bb3: {
|
||||
+ drop((((*_5) as Some).0: B)) -> bb2; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||
+ }
|
||||
+
|
||||
+ bb4 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-shims.rs:10:1: 13:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,10 @@
|
||||
_0 = const (); // scope 0 at $DIR/inline-specialization.rs:4:11: 6:2
|
||||
StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:6:1: 6:2
|
||||
return; // scope 0 at $DIR/inline-specialization.rs:6:2: 6:2
|
||||
+ }
|
||||
+
|
||||
+ bb1 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/inline-specialization.rs:4:1: 6:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,4 +29,8 @@ fn test2(_1: &dyn X) -> bool {
|
||||
StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:5:11: 5:12
|
||||
return; // scope 0 at $DIR/inline-trait-method_2.rs:6:2: 6:2
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume; // scope 0 at $DIR/inline-trait-method_2.rs:4:1: 6:2
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,8 @@ fn a(_1: &mut [T]) -> &mut [T] {
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:1: 4:2
|
||||
return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:2: 4:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:2:1: 4:2
|
||||
}
|
||||
}
|
||||
|
@ -35,4 +35,8 @@ fn b(_1: &mut Box<T>) -> &mut T {
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:1: 9:2
|
||||
return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:2: 9:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:7:1: 9:2
|
||||
}
|
||||
}
|
||||
|
@ -19,4 +19,8 @@ fn c(_1: &[T]) -> &[T] {
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:14:1: 14:2
|
||||
return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:14:2: 14:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:12:1: 14:2
|
||||
}
|
||||
}
|
||||
|
@ -23,4 +23,8 @@ fn d(_1: &Box<T>) -> &T {
|
||||
StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:1: 19:2
|
||||
return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:2: 19:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:17:1: 19:2
|
||||
}
|
||||
}
|
||||
|
@ -39,4 +39,8 @@ fn main() -> () {
|
||||
StorageDead(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:7:1: 7:2
|
||||
return; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:7:2: 7:2
|
||||
}
|
||||
|
||||
bb1 (cleanup): {
|
||||
resume; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:4:1: 7:2
|
||||
}
|
||||
}
|
||||
|
@ -96,5 +96,9 @@
|
||||
_10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:8:14: 8:19
|
||||
switchInt(move _10) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/remove_storage_markers.rs:8:14: 8:19
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
resume; // scope 0 at $DIR/remove_storage_markers.rs:6:1: 11:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@
|
||||
StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:4:12: 4:13
|
||||
- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:3:17: 5:2
|
||||
return; // scope 0 at $DIR/remove_unneeded_drops.rs:5:2: 5:2
|
||||
- }
|
||||
-
|
||||
- bb2 (cleanup): {
|
||||
- resume; // scope 0 at $DIR/remove_unneeded_drops.rs:3:1: 5:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@
|
||||
StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:14:12: 14:13
|
||||
- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:13:36: 15:2
|
||||
return; // scope 0 at $DIR/remove_unneeded_drops.rs:15:2: 15:2
|
||||
- }
|
||||
-
|
||||
- bb2 (cleanup): {
|
||||
- resume; // scope 0 at $DIR/remove_unneeded_drops.rs:13:1: 15:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,5 +85,9 @@
|
||||
bb4: {
|
||||
return; // scope 0 at $DIR/simplify-arm.rs:41:2: 41:2
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
resume; // scope 0 at $DIR/simplify-arm.rs:35:1: 41:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,5 +85,9 @@
|
||||
bb4: {
|
||||
return; // scope 0 at $DIR/simplify-arm.rs:41:2: 41:2
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
resume; // scope 0 at $DIR/simplify-arm.rs:35:1: 41:2
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user