mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Completely remove tracking of references for now
This commit is contained in:
parent
3997893ccb
commit
bfbca6c75c
@ -13,11 +13,10 @@
|
||||
//! can be registered. The [`State`] can be queried to retrieve the abstract value stored for a
|
||||
//! certain place by passing the map.
|
||||
//!
|
||||
//! This framework is currently experimental. In particular, the features related to references are
|
||||
//! currently guarded behind `-Zunsound-mir-opts`, because their correctness relies on Stacked
|
||||
//! Borrows. Also, only places with scalar types can be tracked currently. This is because scalar
|
||||
//! types are indivisible, which simplifies the current implementation. But this limitation could be
|
||||
//! lifted in the future.
|
||||
//! This framework is currently experimental. Originally, it supported shared references and enum
|
||||
//! variants. However, it was discovered that both of these were unsound, and especially references
|
||||
//! had subtle but serious issues. In the future, they could be added back in, but we should clarify
|
||||
//! the rules for optimizations that rely on the aliasing model first.
|
||||
//!
|
||||
//!
|
||||
//! # Notes
|
||||
@ -28,29 +27,17 @@
|
||||
//! - The assignment logic in `State::assign_place_idx` assumes that the places are non-overlapping,
|
||||
//! or identical. Note that this refers to place expressions, not memory locations.
|
||||
//!
|
||||
//! - Since pointers (and mutable references) are not tracked, but can be used to change the
|
||||
//! underlying values, we are conservative and immediately flood the referenced place upon creation
|
||||
//! of the pointer. Also, we have to uphold the invariant that the place must stay that way as long
|
||||
//! as this mutable access could exist. However...
|
||||
//!
|
||||
//! - Without an aliasing model like Stacked Borrows (i.e., `-Zunsound-mir-opts` is not given),
|
||||
//! such mutable access is never revoked. And even shared references could be used to obtain the
|
||||
//! address of a value an modify it. When not assuming Stacked Borrows, we prevent such places from
|
||||
//! being tracked at all. This means that the analysis itself can assume that writes to a *tracked*
|
||||
//! place always invalidate all other means of mutable access, regardless of the aliasing model.
|
||||
//!
|
||||
//! - Likewise, the analysis itself assumes that if the value of a *tracked* place behind a shared
|
||||
//! reference is changed, the reference may not be used to access that value anymore. This is true
|
||||
//! for all places if the referenced type is `Freeze` and we assume Stacked Borrows. If we are not
|
||||
//! assuming Stacking Borrows (or if the referenced type could be `!Freeze`), we again prevent such
|
||||
//! places from being tracked at all, making this assertion trivially true.
|
||||
//! - Currently, places that have their reference taken cannot be tracked. Although this would be
|
||||
//! possible, it has to rely on some aliasing model, which we are not ready to commit to yet.
|
||||
//! Because of that, we can assume that the only way to change the value behind a tracked place is
|
||||
//! by direct assignment.
|
||||
|
||||
use std::fmt::{Debug, Formatter};
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
@ -96,10 +83,7 @@ pub trait ValueAnalysis<'tcx> {
|
||||
state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
|
||||
}
|
||||
StatementKind::Retag(..) => {
|
||||
// A retag modifies the provenance of references. Currently references are only
|
||||
// tracked if `-Zunsound-mir-opts` is given, but this might change in the future.
|
||||
// However, it is still unclear how retags should be handled:
|
||||
// https://github.com/rust-lang/rust/pull/101168#discussion_r985304895
|
||||
// We don't track references.
|
||||
}
|
||||
StatementKind::Nop
|
||||
| StatementKind::FakeRead(..)
|
||||
@ -156,7 +140,7 @@ pub trait ValueAnalysis<'tcx> {
|
||||
&self,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
state: &mut State<Self::Value>,
|
||||
) -> ValueOrPlaceOrRef<Self::Value> {
|
||||
) -> ValueOrPlace<Self::Value> {
|
||||
self.super_rvalue(rvalue, state)
|
||||
}
|
||||
|
||||
@ -164,21 +148,15 @@ pub trait ValueAnalysis<'tcx> {
|
||||
&self,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
state: &mut State<Self::Value>,
|
||||
) -> ValueOrPlaceOrRef<Self::Value> {
|
||||
) -> ValueOrPlace<Self::Value> {
|
||||
match rvalue {
|
||||
Rvalue::Use(operand) => self.handle_operand(operand, state).into(),
|
||||
Rvalue::Ref(_, BorrowKind::Shared, place) => self
|
||||
.map()
|
||||
.find(place.as_ref())
|
||||
.map(ValueOrPlaceOrRef::Ref)
|
||||
.unwrap_or(ValueOrPlaceOrRef::top()),
|
||||
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
|
||||
// This is not a `&x` reference and could be used for modification.
|
||||
state.flood(place.as_ref(), self.map());
|
||||
ValueOrPlaceOrRef::top()
|
||||
}
|
||||
Rvalue::Use(operand) => self.handle_operand(operand, state),
|
||||
Rvalue::CopyForDeref(place) => {
|
||||
self.handle_operand(&Operand::Copy(*place), state).into()
|
||||
self.handle_operand(&Operand::Copy(*place), state)
|
||||
}
|
||||
Rvalue::Ref(..) | Rvalue::AddressOf(..) => {
|
||||
// We don't track such places.
|
||||
ValueOrPlace::top()
|
||||
}
|
||||
Rvalue::Repeat(..)
|
||||
| Rvalue::ThreadLocalRef(..)
|
||||
@ -192,7 +170,7 @@ pub trait ValueAnalysis<'tcx> {
|
||||
| Rvalue::Aggregate(..)
|
||||
| Rvalue::ShallowInitBox(..) => {
|
||||
// No modification is possible through these r-values.
|
||||
ValueOrPlaceOrRef::top()
|
||||
ValueOrPlace::top()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -247,14 +225,13 @@ pub trait ValueAnalysis<'tcx> {
|
||||
self.super_terminator(terminator, state)
|
||||
}
|
||||
|
||||
fn super_terminator(&self, terminator: &Terminator<'tcx>, state: &mut State<Self::Value>) {
|
||||
fn super_terminator(&self, terminator: &Terminator<'tcx>, _state: &mut State<Self::Value>) {
|
||||
match &terminator.kind {
|
||||
TerminatorKind::Call { .. } | TerminatorKind::InlineAsm { .. } => {
|
||||
// Effect is applied by `handle_call_return`.
|
||||
}
|
||||
TerminatorKind::Drop { place, .. } => {
|
||||
// Place can still be accessed after drop, and drop has mutable access to it.
|
||||
state.flood(place.as_ref(), self.map());
|
||||
TerminatorKind::Drop { .. } => {
|
||||
// We don't track dropped places.
|
||||
}
|
||||
TerminatorKind::DropAndReplace { .. } | TerminatorKind::Yield { .. } => {
|
||||
// They would have an effect, but are not allowed in this phase.
|
||||
@ -522,7 +499,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assign(&mut self, target: PlaceRef<'_>, result: ValueOrPlaceOrRef<V>, map: &Map) {
|
||||
pub fn assign(&mut self, target: PlaceRef<'_>, result: ValueOrPlace<V>, map: &Map) {
|
||||
if let Some(target) = map.find(target) {
|
||||
self.assign_idx(target, result, map);
|
||||
} else {
|
||||
@ -530,9 +507,9 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assign_idx(&mut self, target: PlaceIndex, result: ValueOrPlaceOrRef<V>, map: &Map) {
|
||||
pub fn assign_idx(&mut self, target: PlaceIndex, result: ValueOrPlace<V>, map: &Map) {
|
||||
match result {
|
||||
ValueOrPlaceOrRef::Value(value) => {
|
||||
ValueOrPlace::Value(value) => {
|
||||
// First flood the target place in case we also track any projections (although
|
||||
// this scenario is currently not well-supported by the API).
|
||||
self.flood_idx(target, map);
|
||||
@ -541,21 +518,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
|
||||
values[value_index] = value;
|
||||
}
|
||||
}
|
||||
ValueOrPlaceOrRef::Place(source) => self.assign_place_idx(target, source, map),
|
||||
ValueOrPlaceOrRef::Ref(source) => {
|
||||
let StateData::Reachable(values) = &mut self.0 else { return };
|
||||
if let Some(value_index) = map.places[target].value_index {
|
||||
values[value_index] = V::top();
|
||||
}
|
||||
// Instead of tracking of *where* a reference points to (as in, which memory
|
||||
// location), we track *what* it points to (as in, what do we know about the
|
||||
// target). For an assignment `x = &y`, we thus copy the info of `y` to `*x`.
|
||||
if let Some(target_deref) = map.apply(target, TrackElem::Deref) {
|
||||
// We know here that `*x` is `Freeze`, because we only track through
|
||||
// dereferences if the target type is `Freeze`.
|
||||
self.assign_place_idx(target_deref, source, map);
|
||||
}
|
||||
}
|
||||
ValueOrPlace::Place(source) => self.assign_place_idx(target, source, map),
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,45 +588,27 @@ impl Map {
|
||||
filter: impl FnMut(Ty<'tcx>) -> bool,
|
||||
) -> Self {
|
||||
let mut map = Self::new();
|
||||
|
||||
// If `-Zunsound-mir-opts` is given, tracking through references, and tracking of places
|
||||
// that have their reference taken is allowed. This would be "unsound" in the sense that
|
||||
// the correctness relies on an aliasing model similar to Stacked Borrows (which is
|
||||
// not yet guaranteed).
|
||||
if tcx.sess.opts.unstable_opts.unsound_mir_opts {
|
||||
// We might want to add additional limitations. If a struct has 10 boxed fields of
|
||||
// itself, there will currently be `10.pow(max_derefs)` tracked places.
|
||||
map.register_with_filter(tcx, body, 2, filter, &FxHashSet::default());
|
||||
} else {
|
||||
map.register_with_filter(tcx, body, 0, filter, &escaped_places(body));
|
||||
}
|
||||
|
||||
map.register_with_filter(tcx, body, filter, &escaped_places(body));
|
||||
debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len());
|
||||
map
|
||||
}
|
||||
|
||||
/// Register all non-excluded places that pass the filter, up to a certain dereference depth.
|
||||
/// Register all non-excluded places that pass the filter.
|
||||
fn register_with_filter<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
max_derefs: u32,
|
||||
mut filter: impl FnMut(Ty<'tcx>) -> bool,
|
||||
exclude: &FxHashSet<Place<'tcx>>,
|
||||
) {
|
||||
// This is used to tell whether a type is `Freeze`.
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
||||
|
||||
let mut projection = Vec::new();
|
||||
for (local, decl) in body.local_decls.iter_enumerated() {
|
||||
self.register_with_filter_rec(
|
||||
tcx,
|
||||
max_derefs,
|
||||
local,
|
||||
&mut projection,
|
||||
decl.ty,
|
||||
&mut filter,
|
||||
param_env,
|
||||
exclude,
|
||||
);
|
||||
}
|
||||
@ -672,12 +617,10 @@ impl Map {
|
||||
fn register_with_filter_rec<'tcx>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
max_derefs: u32,
|
||||
local: Local,
|
||||
projection: &mut Vec<PlaceElem<'tcx>>,
|
||||
ty: Ty<'tcx>,
|
||||
filter: &mut impl FnMut(Ty<'tcx>) -> bool,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
exclude: &FxHashSet<Place<'tcx>>,
|
||||
) {
|
||||
if exclude.contains(&Place { local, projection: tcx.intern_place_elems(projection) }) {
|
||||
@ -689,26 +632,6 @@ impl Map {
|
||||
// This might fail if `ty` is not scalar.
|
||||
let _ = self.register_with_ty(local, projection, ty);
|
||||
}
|
||||
|
||||
if max_derefs > 0 {
|
||||
if let Some(ty::TypeAndMut { ty: deref_ty, .. }) = ty.builtin_deref(false) {
|
||||
// Values behind references can only be tracked if the target is `Freeze`.
|
||||
if deref_ty.is_freeze(tcx, param_env) {
|
||||
projection.push(PlaceElem::Deref);
|
||||
self.register_with_filter_rec(
|
||||
tcx,
|
||||
max_derefs - 1,
|
||||
local,
|
||||
projection,
|
||||
deref_ty,
|
||||
filter,
|
||||
param_env,
|
||||
exclude,
|
||||
);
|
||||
projection.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
iter_fields(ty, tcx, |variant, field, ty| {
|
||||
if variant.is_some() {
|
||||
// Downcasts are currently not supported.
|
||||
@ -716,7 +639,7 @@ impl Map {
|
||||
}
|
||||
projection.push(PlaceElem::Field(field, ty));
|
||||
self.register_with_filter_rec(
|
||||
tcx, max_derefs, local, projection, ty, filter, param_env, exclude,
|
||||
tcx, local, projection, ty, filter, exclude,
|
||||
);
|
||||
projection.pop();
|
||||
});
|
||||
@ -875,7 +798,7 @@ impl<'a> Iterator for Children<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Used as the result of an operand.
|
||||
/// Used as the result of an operand or r-value.
|
||||
pub enum ValueOrPlace<V> {
|
||||
Value(V),
|
||||
Place(PlaceIndex),
|
||||
@ -887,34 +810,11 @@ impl<V: HasTop> ValueOrPlace<V> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Used as the result of an r-value.
|
||||
pub enum ValueOrPlaceOrRef<V> {
|
||||
Value(V),
|
||||
Place(PlaceIndex),
|
||||
Ref(PlaceIndex),
|
||||
}
|
||||
|
||||
impl<V: HasTop> ValueOrPlaceOrRef<V> {
|
||||
pub fn top() -> Self {
|
||||
ValueOrPlaceOrRef::Value(V::top())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> From<ValueOrPlace<V>> for ValueOrPlaceOrRef<V> {
|
||||
fn from(x: ValueOrPlace<V>) -> Self {
|
||||
match x {
|
||||
ValueOrPlace::Value(value) => ValueOrPlaceOrRef::Value(value),
|
||||
ValueOrPlace::Place(place) => ValueOrPlaceOrRef::Place(place),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The set of projection elements that can be used by a tracked place.
|
||||
///
|
||||
/// For now, downcast is not allowed due to aliasing between variants (see #101168).
|
||||
/// Although only field projections are currently allowed, this could change in the future.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum TrackElem {
|
||||
Deref,
|
||||
Field(Field),
|
||||
}
|
||||
|
||||
@ -923,7 +823,6 @@ impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
|
||||
|
||||
fn try_from(value: ProjectionElem<V, T>) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
ProjectionElem::Deref => Ok(TrackElem::Deref),
|
||||
ProjectionElem::Field(field, _) => Ok(TrackElem::Field(field)),
|
||||
_ => Err(()),
|
||||
}
|
||||
@ -962,7 +861,7 @@ fn iter_fields<'tcx>(
|
||||
|
||||
/// Returns all places, that have their reference or address taken.
|
||||
///
|
||||
/// This includes shared references.
|
||||
/// This includes shared references, and also drops and `InlineAsm` out parameters.
|
||||
fn escaped_places<'tcx>(body: &Body<'tcx>) -> FxHashSet<Place<'tcx>> {
|
||||
struct Collector<'tcx> {
|
||||
result: FxHashSet<Place<'tcx>>,
|
||||
@ -970,7 +869,11 @@ fn escaped_places<'tcx>(body: &Body<'tcx>) -> FxHashSet<Place<'tcx>> {
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for Collector<'tcx> {
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
|
||||
if context.is_borrow() || context.is_address_of() {
|
||||
if context.is_borrow()
|
||||
|| context.is_address_of()
|
||||
|| context.is_drop()
|
||||
|| context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)
|
||||
{
|
||||
self.result.insert(*place);
|
||||
}
|
||||
}
|
||||
@ -1032,7 +935,6 @@ fn debug_with_context_rec<V: Debug + Eq>(
|
||||
for child in map.children(place) {
|
||||
let info_elem = map.places[child].proj_elem.unwrap();
|
||||
let child_place_str = match info_elem {
|
||||
TrackElem::Deref => format!("*{}", place_str),
|
||||
TrackElem::Field(field) => {
|
||||
if place_str.starts_with("*") {
|
||||
format!("({}).{}", place_str, field.index())
|
||||
|
@ -8,7 +8,7 @@ use rustc_middle::mir::visit::{MutVisitor, Visitor};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_mir_dataflow::value_analysis::{
|
||||
Map, State, TrackElem, ValueAnalysis, ValueOrPlace, ValueOrPlaceOrRef,
|
||||
Map, State, TrackElem, ValueAnalysis, ValueOrPlace,
|
||||
};
|
||||
use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects};
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -100,7 +100,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
|
||||
let (val, overflow) = self.binary_op(state, *op, left, right);
|
||||
|
||||
if let Some(value_target) = value_target {
|
||||
state.assign_idx(value_target, ValueOrPlaceOrRef::Value(val), self.map());
|
||||
state.assign_idx(value_target, ValueOrPlace::Value(val), self.map());
|
||||
}
|
||||
if let Some(overflow_target) = overflow_target {
|
||||
let overflow = match overflow {
|
||||
@ -117,7 +117,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
|
||||
};
|
||||
state.assign_idx(
|
||||
overflow_target,
|
||||
ValueOrPlaceOrRef::Value(overflow),
|
||||
ValueOrPlace::Value(overflow),
|
||||
self.map(),
|
||||
);
|
||||
}
|
||||
@ -131,7 +131,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
|
||||
&self,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
state: &mut State<Self::Value>,
|
||||
) -> ValueOrPlaceOrRef<Self::Value> {
|
||||
) -> ValueOrPlace<Self::Value> {
|
||||
match rvalue {
|
||||
Rvalue::Cast(
|
||||
kind @ (CastKind::IntToInt
|
||||
@ -150,23 +150,23 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map(|result| ValueOrPlaceOrRef::Value(self.wrap_immediate(result, *ty)))
|
||||
.unwrap_or(ValueOrPlaceOrRef::top()),
|
||||
_ => ValueOrPlaceOrRef::top(),
|
||||
.map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty)))
|
||||
.unwrap_or(ValueOrPlace::top()),
|
||||
_ => ValueOrPlace::top(),
|
||||
},
|
||||
Rvalue::BinaryOp(op, box (left, right)) => {
|
||||
// Overflows must be ignored here.
|
||||
let (val, _overflow) = self.binary_op(state, *op, left, right);
|
||||
ValueOrPlaceOrRef::Value(val)
|
||||
ValueOrPlace::Value(val)
|
||||
}
|
||||
Rvalue::UnaryOp(op, operand) => match self.eval_operand(operand, state) {
|
||||
FlatSet::Elem(value) => self
|
||||
.ecx
|
||||
.unary_op(*op, &value)
|
||||
.map(|val| ValueOrPlaceOrRef::Value(self.wrap_immty(val)))
|
||||
.unwrap_or(ValueOrPlaceOrRef::Value(FlatSet::Top)),
|
||||
FlatSet::Bottom => ValueOrPlaceOrRef::Value(FlatSet::Bottom),
|
||||
FlatSet::Top => ValueOrPlaceOrRef::Value(FlatSet::Top),
|
||||
.map(|val| ValueOrPlace::Value(self.wrap_immty(val)))
|
||||
.unwrap_or(ValueOrPlace::Value(FlatSet::Top)),
|
||||
FlatSet::Bottom => ValueOrPlace::Value(FlatSet::Bottom),
|
||||
FlatSet::Top => ValueOrPlace::Value(FlatSet::Top),
|
||||
},
|
||||
_ => self.super_rvalue(rvalue, state),
|
||||
}
|
||||
|
@ -4,9 +4,8 @@
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10
|
||||
let mut _3: u8; // in scope 0 at $DIR/cast.rs:+2:13: +2:22
|
||||
let mut _4: i32; // in scope 0 at $DIR/cast.rs:+2:13: +2:16
|
||||
let mut _5: &i32; // in scope 0 at $DIR/cast.rs:+2:14: +2:16
|
||||
let mut _3: u8; // in scope 0 at $DIR/cast.rs:+2:13: +2:20
|
||||
let mut _4: i32; // in scope 0 at $DIR/cast.rs:+2:13: +2:14
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10
|
||||
let _2: u8; // in scope 1 at $DIR/cast.rs:+2:9: +2:10
|
||||
@ -19,19 +18,16 @@
|
||||
StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10
|
||||
_1 = const 257_i32; // scope 0 at $DIR/cast.rs:+1:13: +1:16
|
||||
StorageLive(_2); // scope 1 at $DIR/cast.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 1 at $DIR/cast.rs:+2:13: +2:22
|
||||
StorageLive(_4); // scope 1 at $DIR/cast.rs:+2:13: +2:16
|
||||
StorageLive(_5); // scope 1 at $DIR/cast.rs:+2:14: +2:16
|
||||
_5 = &_1; // scope 1 at $DIR/cast.rs:+2:14: +2:16
|
||||
- _4 = (*_5); // scope 1 at $DIR/cast.rs:+2:13: +2:16
|
||||
- _3 = move _4 as u8 (IntToInt); // scope 1 at $DIR/cast.rs:+2:13: +2:22
|
||||
+ _4 = const 257_i32; // scope 1 at $DIR/cast.rs:+2:13: +2:16
|
||||
+ _3 = const 1_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:22
|
||||
StorageDead(_4); // scope 1 at $DIR/cast.rs:+2:21: +2:22
|
||||
- _2 = Add(move _3, const 1_u8); // scope 1 at $DIR/cast.rs:+2:13: +2:26
|
||||
+ _2 = const 2_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:26
|
||||
StorageDead(_3); // scope 1 at $DIR/cast.rs:+2:25: +2:26
|
||||
StorageDead(_5); // scope 1 at $DIR/cast.rs:+2:26: +2:27
|
||||
StorageLive(_3); // scope 1 at $DIR/cast.rs:+2:13: +2:20
|
||||
StorageLive(_4); // scope 1 at $DIR/cast.rs:+2:13: +2:14
|
||||
- _4 = _1; // scope 1 at $DIR/cast.rs:+2:13: +2:14
|
||||
- _3 = move _4 as u8 (IntToInt); // scope 1 at $DIR/cast.rs:+2:13: +2:20
|
||||
+ _4 = const 257_i32; // scope 1 at $DIR/cast.rs:+2:13: +2:14
|
||||
+ _3 = const 1_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:20
|
||||
StorageDead(_4); // scope 1 at $DIR/cast.rs:+2:19: +2:20
|
||||
- _2 = Add(move _3, const 1_u8); // scope 1 at $DIR/cast.rs:+2:13: +2:24
|
||||
+ _2 = const 2_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:24
|
||||
StorageDead(_3); // scope 1 at $DIR/cast.rs:+2:23: +2:24
|
||||
_0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +3:2
|
||||
StorageDead(_2); // scope 1 at $DIR/cast.rs:+3:1: +3:2
|
||||
StorageDead(_1); // scope 0 at $DIR/cast.rs:+3:1: +3:2
|
||||
|
@ -1,8 +1,7 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR cast.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let a = 257;
|
||||
let b = *&a as u8 + 1;
|
||||
let b = a as u8 + 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts -Coverflow-checks=on
|
||||
// compile-flags: -Coverflow-checks=on
|
||||
|
||||
// EMIT_MIR checked.main.DataflowConstProp.diff
|
||||
#[allow(arithmetic_overflow)]
|
||||
|
@ -4,29 +4,27 @@
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/if.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/if.rs:+1:9: +1:10
|
||||
let mut _3: bool; // in scope 0 at $DIR/if.rs:+2:16: +2:24
|
||||
let mut _4: i32; // in scope 0 at $DIR/if.rs:+2:16: +2:19
|
||||
let mut _5: &i32; // in scope 0 at $DIR/if.rs:+2:17: +2:19
|
||||
let mut _7: i32; // in scope 0 at $DIR/if.rs:+3:13: +3:14
|
||||
let mut _9: bool; // in scope 0 at $DIR/if.rs:+5:16: +5:24
|
||||
let mut _10: i32; // in scope 0 at $DIR/if.rs:+5:16: +5:19
|
||||
let mut _11: &i32; // in scope 0 at $DIR/if.rs:+5:17: +5:19
|
||||
let mut _12: i32; // in scope 0 at $DIR/if.rs:+5:38: +5:39
|
||||
let mut _14: i32; // in scope 0 at $DIR/if.rs:+6:13: +6:14
|
||||
let mut _3: bool; // in scope 0 at $DIR/if.rs:+2:16: +2:22
|
||||
let mut _4: i32; // in scope 0 at $DIR/if.rs:+2:16: +2:17
|
||||
let mut _6: i32; // in scope 0 at $DIR/if.rs:+3:13: +3:14
|
||||
let mut _8: bool; // in scope 0 at $DIR/if.rs:+5:16: +5:22
|
||||
let mut _9: i32; // in scope 0 at $DIR/if.rs:+5:16: +5:17
|
||||
let mut _10: i32; // in scope 0 at $DIR/if.rs:+5:36: +5:37
|
||||
let mut _12: i32; // in scope 0 at $DIR/if.rs:+6:13: +6:14
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/if.rs:+1:9: +1:10
|
||||
let _2: i32; // in scope 1 at $DIR/if.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug b => _2; // in scope 2 at $DIR/if.rs:+2:9: +2:10
|
||||
let _6: i32; // in scope 2 at $DIR/if.rs:+3:9: +3:10
|
||||
let _5: i32; // in scope 2 at $DIR/if.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug c => _6; // in scope 3 at $DIR/if.rs:+3:9: +3:10
|
||||
let _8: i32; // in scope 3 at $DIR/if.rs:+5:9: +5:10
|
||||
debug c => _5; // in scope 3 at $DIR/if.rs:+3:9: +3:10
|
||||
let _7: i32; // in scope 3 at $DIR/if.rs:+5:9: +5:10
|
||||
scope 4 {
|
||||
debug d => _8; // in scope 4 at $DIR/if.rs:+5:9: +5:10
|
||||
let _13: i32; // in scope 4 at $DIR/if.rs:+6:9: +6:10
|
||||
debug d => _7; // in scope 4 at $DIR/if.rs:+5:9: +5:10
|
||||
let _11: i32; // in scope 4 at $DIR/if.rs:+6:9: +6:10
|
||||
scope 5 {
|
||||
debug e => _13; // in scope 5 at $DIR/if.rs:+6:9: +6:10
|
||||
debug e => _11; // in scope 5 at $DIR/if.rs:+6:9: +6:10
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,81 +35,75 @@
|
||||
StorageLive(_1); // scope 0 at $DIR/if.rs:+1:9: +1:10
|
||||
_1 = const 1_i32; // scope 0 at $DIR/if.rs:+1:13: +1:14
|
||||
StorageLive(_2); // scope 1 at $DIR/if.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 1 at $DIR/if.rs:+2:16: +2:24
|
||||
StorageLive(_4); // scope 1 at $DIR/if.rs:+2:16: +2:19
|
||||
StorageLive(_5); // scope 1 at $DIR/if.rs:+2:17: +2:19
|
||||
_5 = &_1; // scope 1 at $DIR/if.rs:+2:17: +2:19
|
||||
- _4 = (*_5); // scope 1 at $DIR/if.rs:+2:16: +2:19
|
||||
- _3 = Eq(move _4, const 1_i32); // scope 1 at $DIR/if.rs:+2:16: +2:24
|
||||
+ _4 = const 1_i32; // scope 1 at $DIR/if.rs:+2:16: +2:19
|
||||
+ _3 = const true; // scope 1 at $DIR/if.rs:+2:16: +2:24
|
||||
StorageDead(_5); // scope 1 at $DIR/if.rs:+2:23: +2:24
|
||||
StorageDead(_4); // scope 1 at $DIR/if.rs:+2:23: +2:24
|
||||
- switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:24
|
||||
+ switchInt(const true) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:24
|
||||
StorageLive(_3); // scope 1 at $DIR/if.rs:+2:16: +2:22
|
||||
StorageLive(_4); // scope 1 at $DIR/if.rs:+2:16: +2:17
|
||||
- _4 = _1; // scope 1 at $DIR/if.rs:+2:16: +2:17
|
||||
- _3 = Eq(move _4, const 1_i32); // scope 1 at $DIR/if.rs:+2:16: +2:22
|
||||
+ _4 = const 1_i32; // scope 1 at $DIR/if.rs:+2:16: +2:17
|
||||
+ _3 = const true; // scope 1 at $DIR/if.rs:+2:16: +2:22
|
||||
StorageDead(_4); // scope 1 at $DIR/if.rs:+2:21: +2:22
|
||||
- switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
|
||||
+ switchInt(const true) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = const 2_i32; // scope 1 at $DIR/if.rs:+2:27: +2:28
|
||||
goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:41
|
||||
_2 = const 2_i32; // scope 1 at $DIR/if.rs:+2:25: +2:26
|
||||
goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_2 = const 3_i32; // scope 1 at $DIR/if.rs:+2:38: +2:39
|
||||
goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:41
|
||||
_2 = const 3_i32; // scope 1 at $DIR/if.rs:+2:36: +2:37
|
||||
goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_3); // scope 1 at $DIR/if.rs:+2:40: +2:41
|
||||
StorageLive(_6); // scope 2 at $DIR/if.rs:+3:9: +3:10
|
||||
StorageLive(_7); // scope 2 at $DIR/if.rs:+3:13: +3:14
|
||||
- _7 = _2; // scope 2 at $DIR/if.rs:+3:13: +3:14
|
||||
- _6 = Add(move _7, const 1_i32); // scope 2 at $DIR/if.rs:+3:13: +3:18
|
||||
+ _7 = const 2_i32; // scope 2 at $DIR/if.rs:+3:13: +3:14
|
||||
+ _6 = const 3_i32; // scope 2 at $DIR/if.rs:+3:13: +3:18
|
||||
StorageDead(_7); // scope 2 at $DIR/if.rs:+3:17: +3:18
|
||||
StorageLive(_8); // scope 3 at $DIR/if.rs:+5:9: +5:10
|
||||
StorageLive(_9); // scope 3 at $DIR/if.rs:+5:16: +5:24
|
||||
StorageLive(_10); // scope 3 at $DIR/if.rs:+5:16: +5:19
|
||||
StorageLive(_11); // scope 3 at $DIR/if.rs:+5:17: +5:19
|
||||
_11 = &_1; // scope 3 at $DIR/if.rs:+5:17: +5:19
|
||||
- _10 = (*_11); // scope 3 at $DIR/if.rs:+5:16: +5:19
|
||||
- _9 = Eq(move _10, const 1_i32); // scope 3 at $DIR/if.rs:+5:16: +5:24
|
||||
+ _10 = const 1_i32; // scope 3 at $DIR/if.rs:+5:16: +5:19
|
||||
+ _9 = const true; // scope 3 at $DIR/if.rs:+5:16: +5:24
|
||||
StorageDead(_11); // scope 3 at $DIR/if.rs:+5:23: +5:24
|
||||
StorageDead(_10); // scope 3 at $DIR/if.rs:+5:23: +5:24
|
||||
- switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:24
|
||||
+ switchInt(const true) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:24
|
||||
StorageDead(_3); // scope 1 at $DIR/if.rs:+2:38: +2:39
|
||||
StorageLive(_5); // scope 2 at $DIR/if.rs:+3:9: +3:10
|
||||
StorageLive(_6); // scope 2 at $DIR/if.rs:+3:13: +3:14
|
||||
- _6 = _2; // scope 2 at $DIR/if.rs:+3:13: +3:14
|
||||
- _5 = Add(move _6, const 1_i32); // scope 2 at $DIR/if.rs:+3:13: +3:18
|
||||
+ _6 = const 2_i32; // scope 2 at $DIR/if.rs:+3:13: +3:14
|
||||
+ _5 = const 3_i32; // scope 2 at $DIR/if.rs:+3:13: +3:18
|
||||
StorageDead(_6); // scope 2 at $DIR/if.rs:+3:17: +3:18
|
||||
StorageLive(_7); // scope 3 at $DIR/if.rs:+5:9: +5:10
|
||||
StorageLive(_8); // scope 3 at $DIR/if.rs:+5:16: +5:22
|
||||
StorageLive(_9); // scope 3 at $DIR/if.rs:+5:16: +5:17
|
||||
- _9 = _1; // scope 3 at $DIR/if.rs:+5:16: +5:17
|
||||
- _8 = Eq(move _9, const 1_i32); // scope 3 at $DIR/if.rs:+5:16: +5:22
|
||||
+ _9 = const 1_i32; // scope 3 at $DIR/if.rs:+5:16: +5:17
|
||||
+ _8 = const true; // scope 3 at $DIR/if.rs:+5:16: +5:22
|
||||
StorageDead(_9); // scope 3 at $DIR/if.rs:+5:21: +5:22
|
||||
- switchInt(move _8) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
|
||||
+ switchInt(const true) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
|
||||
}
|
||||
|
||||
bb4: {
|
||||
- _8 = _1; // scope 3 at $DIR/if.rs:+5:27: +5:28
|
||||
+ _8 = const 1_i32; // scope 3 at $DIR/if.rs:+5:27: +5:28
|
||||
goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:45
|
||||
- _7 = _1; // scope 3 at $DIR/if.rs:+5:25: +5:26
|
||||
+ _7 = const 1_i32; // scope 3 at $DIR/if.rs:+5:25: +5:26
|
||||
goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageLive(_12); // scope 3 at $DIR/if.rs:+5:38: +5:39
|
||||
_12 = _1; // scope 3 at $DIR/if.rs:+5:38: +5:39
|
||||
_8 = Add(move _12, const 1_i32); // scope 3 at $DIR/if.rs:+5:38: +5:43
|
||||
StorageDead(_12); // scope 3 at $DIR/if.rs:+5:42: +5:43
|
||||
goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:45
|
||||
StorageLive(_10); // scope 3 at $DIR/if.rs:+5:36: +5:37
|
||||
_10 = _1; // scope 3 at $DIR/if.rs:+5:36: +5:37
|
||||
_7 = Add(move _10, const 1_i32); // scope 3 at $DIR/if.rs:+5:36: +5:41
|
||||
StorageDead(_10); // scope 3 at $DIR/if.rs:+5:40: +5:41
|
||||
goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_9); // scope 3 at $DIR/if.rs:+5:44: +5:45
|
||||
StorageLive(_13); // scope 4 at $DIR/if.rs:+6:9: +6:10
|
||||
StorageLive(_14); // scope 4 at $DIR/if.rs:+6:13: +6:14
|
||||
- _14 = _8; // scope 4 at $DIR/if.rs:+6:13: +6:14
|
||||
- _13 = Add(move _14, const 1_i32); // scope 4 at $DIR/if.rs:+6:13: +6:18
|
||||
+ _14 = const 1_i32; // scope 4 at $DIR/if.rs:+6:13: +6:14
|
||||
+ _13 = const 2_i32; // scope 4 at $DIR/if.rs:+6:13: +6:18
|
||||
StorageDead(_14); // scope 4 at $DIR/if.rs:+6:17: +6:18
|
||||
StorageDead(_8); // scope 3 at $DIR/if.rs:+5:42: +5:43
|
||||
StorageLive(_11); // scope 4 at $DIR/if.rs:+6:9: +6:10
|
||||
StorageLive(_12); // scope 4 at $DIR/if.rs:+6:13: +6:14
|
||||
- _12 = _7; // scope 4 at $DIR/if.rs:+6:13: +6:14
|
||||
- _11 = Add(move _12, const 1_i32); // scope 4 at $DIR/if.rs:+6:13: +6:18
|
||||
+ _12 = const 1_i32; // scope 4 at $DIR/if.rs:+6:13: +6:14
|
||||
+ _11 = const 2_i32; // scope 4 at $DIR/if.rs:+6:13: +6:18
|
||||
StorageDead(_12); // scope 4 at $DIR/if.rs:+6:17: +6:18
|
||||
_0 = const (); // scope 0 at $DIR/if.rs:+0:11: +7:2
|
||||
StorageDead(_13); // scope 4 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_8); // scope 3 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_6); // scope 2 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_11); // scope 4 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_7); // scope 3 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_5); // scope 2 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_2); // scope 1 at $DIR/if.rs:+7:1: +7:2
|
||||
StorageDead(_1); // scope 0 at $DIR/if.rs:+7:1: +7:2
|
||||
return; // scope 0 at $DIR/if.rs:+7:2: +7:2
|
||||
|
@ -1,12 +1,11 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR if.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let a = 1;
|
||||
let b = if *&a == 1 { 2 } else { 3 };
|
||||
let b = if a == 1 { 2 } else { 3 };
|
||||
let c = b + 1;
|
||||
|
||||
let d = if *&a == 1 { a } else { a + 1 };
|
||||
let d = if a == 1 { a } else { a + 1 };
|
||||
let e = d + 1;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: -Coverflow-checks=off -Zunsound-mir-opts
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR issue_81605.f.DataflowConstProp.diff
|
||||
fn f() -> usize {
|
||||
|
@ -1,29 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/promoted.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/promoted.rs:+2:9: +2:10
|
||||
let mut _2: &i32; // in scope 0 at $DIR/promoted.rs:+2:14: +2:17
|
||||
let _3: i32; // in scope 0 at $DIR/promoted.rs:+2:15: +2:17
|
||||
let mut _4: &i32; // in scope 0 at $DIR/promoted.rs:+2:14: +2:17
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/promoted.rs:+2:9: +2:10
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/promoted.rs:+2:9: +2:10
|
||||
StorageLive(_2); // scope 0 at $DIR/promoted.rs:+2:14: +2:17
|
||||
_4 = const _; // scope 0 at $DIR/promoted.rs:+2:14: +2:17
|
||||
// mir::Constant
|
||||
// + span: $DIR/promoted.rs:7:14: 7:17
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||
_2 = &(*_4); // scope 0 at $DIR/promoted.rs:+2:14: +2:17
|
||||
_1 = (*_2); // scope 0 at $DIR/promoted.rs:+2:13: +2:17
|
||||
StorageDead(_2); // scope 0 at $DIR/promoted.rs:+2:17: +2:18
|
||||
_0 = const (); // scope 0 at $DIR/promoted.rs:+0:11: +3:2
|
||||
StorageDead(_1); // scope 0 at $DIR/promoted.rs:+3:1: +3:2
|
||||
return; // scope 0 at $DIR/promoted.rs:+3:2: +3:2
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR promoted.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
// This does not work because `&42` gets promoted.
|
||||
let a = *&42;
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/ref.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/ref.rs:+1:9: +1:10
|
||||
let mut _4: bool; // in scope 0 at $DIR/ref.rs:+3:16: +3:43
|
||||
let mut _5: u32; // in scope 0 at $DIR/ref.rs:+3:16: +3:38
|
||||
let mut _6: u32; // in scope 0 at $DIR/ref.rs:+3:16: +3:34
|
||||
let mut _7: bool; // in scope 0 at $DIR/ref.rs:+3:16: +3:38
|
||||
let _8: &i32; // in scope 0 at $DIR/ref.rs:+3:58: +3:60
|
||||
let mut _10: i32; // in scope 0 at $DIR/ref.rs:+4:13: +4:15
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/ref.rs:+1:9: +1:10
|
||||
let _2: i32; // in scope 1 at $DIR/ref.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug b => _2; // in scope 2 at $DIR/ref.rs:+2:9: +2:10
|
||||
let _3: &i32; // in scope 2 at $DIR/ref.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug c => _3; // in scope 3 at $DIR/ref.rs:+3:9: +3:10
|
||||
let _9: i32; // in scope 3 at $DIR/ref.rs:+4:9: +4:10
|
||||
scope 4 {
|
||||
debug d => _9; // in scope 4 at $DIR/ref.rs:+4:9: +4:10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/ref.rs:+1:9: +1:10
|
||||
_1 = const 0_i32; // scope 0 at $DIR/ref.rs:+1:13: +1:14
|
||||
StorageLive(_2); // scope 1 at $DIR/ref.rs:+2:9: +2:10
|
||||
_2 = const 0_i32; // scope 1 at $DIR/ref.rs:+2:13: +2:14
|
||||
StorageLive(_3); // scope 2 at $DIR/ref.rs:+3:9: +3:10
|
||||
StorageLive(_4); // scope 2 at $DIR/ref.rs:+3:16: +3:43
|
||||
StorageLive(_5); // scope 2 at $DIR/ref.rs:+3:16: +3:38
|
||||
StorageLive(_6); // scope 2 at $DIR/ref.rs:+3:16: +3:34
|
||||
_6 = id() -> bb1; // scope 2 at $DIR/ref.rs:+3:16: +3:34
|
||||
// mir::Constant
|
||||
// + span: $DIR/ref.rs:8:16: 8:32
|
||||
// + literal: Const { ty: fn() -> u32 {id}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _7 = Eq(const 2_u32, const 0_u32); // scope 2 at $DIR/ref.rs:+3:16: +3:38
|
||||
- assert(!move _7, "attempt to calculate the remainder of `{}` with a divisor of zero", _6) -> bb2; // scope 2 at $DIR/ref.rs:+3:16: +3:38
|
||||
+ _7 = const false; // scope 2 at $DIR/ref.rs:+3:16: +3:38
|
||||
+ assert(!const false, "attempt to calculate the remainder of `{}` with a divisor of zero", _6) -> bb2; // scope 2 at $DIR/ref.rs:+3:16: +3:38
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_5 = Rem(move _6, const 2_u32); // scope 2 at $DIR/ref.rs:+3:16: +3:38
|
||||
StorageDead(_6); // scope 2 at $DIR/ref.rs:+3:37: +3:38
|
||||
_4 = Eq(move _5, const 0_u32); // scope 2 at $DIR/ref.rs:+3:16: +3:43
|
||||
StorageDead(_5); // scope 2 at $DIR/ref.rs:+3:42: +3:43
|
||||
switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/ref.rs:+3:16: +3:43
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_3 = &_1; // scope 2 at $DIR/ref.rs:+3:46: +3:48
|
||||
goto -> bb5; // scope 2 at $DIR/ref.rs:+3:13: +3:62
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_8); // scope 2 at $DIR/ref.rs:+3:58: +3:60
|
||||
_8 = &_2; // scope 2 at $DIR/ref.rs:+3:58: +3:60
|
||||
_3 = &(*_8); // scope 2 at $DIR/ref.rs:+3:58: +3:60
|
||||
StorageDead(_8); // scope 2 at $DIR/ref.rs:+3:61: +3:62
|
||||
goto -> bb5; // scope 2 at $DIR/ref.rs:+3:13: +3:62
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_4); // scope 2 at $DIR/ref.rs:+3:61: +3:62
|
||||
StorageLive(_9); // scope 3 at $DIR/ref.rs:+4:9: +4:10
|
||||
StorageLive(_10); // scope 3 at $DIR/ref.rs:+4:13: +4:15
|
||||
- _10 = (*_3); // scope 3 at $DIR/ref.rs:+4:13: +4:15
|
||||
- _9 = Add(move _10, const 1_i32); // scope 3 at $DIR/ref.rs:+4:13: +4:19
|
||||
+ _10 = const 0_i32; // scope 3 at $DIR/ref.rs:+4:13: +4:15
|
||||
+ _9 = const 1_i32; // scope 3 at $DIR/ref.rs:+4:13: +4:19
|
||||
StorageDead(_10); // scope 3 at $DIR/ref.rs:+4:18: +4:19
|
||||
_0 = const (); // scope 0 at $DIR/ref.rs:+0:11: +5:2
|
||||
StorageDead(_9); // scope 3 at $DIR/ref.rs:+5:1: +5:2
|
||||
StorageDead(_3); // scope 2 at $DIR/ref.rs:+5:1: +5:2
|
||||
StorageDead(_2); // scope 1 at $DIR/ref.rs:+5:1: +5:2
|
||||
StorageDead(_1); // scope 0 at $DIR/ref.rs:+5:1: +5:2
|
||||
return; // scope 0 at $DIR/ref.rs:+5:2: +5:2
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR ref.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let a = 0;
|
||||
let b = 0;
|
||||
let c = if std::process::id() % 2 == 0 { &a } else { &b };
|
||||
let d = *c + 1;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/ref_mut.rs:+0:11: +0:11
|
||||
let mut _1: i32; // in scope 0 at $DIR/ref_mut.rs:+1:9: +1:14
|
||||
let mut _7: &i32; // in scope 0 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
let _8: &i32; // in scope 0 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
let _9: i32; // in scope 0 at $DIR/ref_mut.rs:+9:11: +9:12
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/ref_mut.rs:+1:9: +1:14
|
||||
let _2: &mut i32; // in scope 1 at $DIR/ref_mut.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug b => _2; // in scope 2 at $DIR/ref_mut.rs:+2:9: +2:10
|
||||
let _3: i32; // in scope 2 at $DIR/ref_mut.rs:+4:9: +4:10
|
||||
scope 3 {
|
||||
debug c => _3; // in scope 3 at $DIR/ref_mut.rs:+4:9: +4:10
|
||||
let _4: i32; // in scope 3 at $DIR/ref_mut.rs:+6:9: +6:10
|
||||
scope 4 {
|
||||
debug d => _4; // in scope 4 at $DIR/ref_mut.rs:+6:9: +6:10
|
||||
let mut _5: &i32; // in scope 4 at $DIR/ref_mut.rs:+7:9: +7:14
|
||||
scope 5 {
|
||||
debug e => _5; // in scope 5 at $DIR/ref_mut.rs:+7:9: +7:14
|
||||
let _6: &mut &i32; // in scope 5 at $DIR/ref_mut.rs:+8:9: +8:10
|
||||
scope 6 {
|
||||
debug f => _6; // in scope 6 at $DIR/ref_mut.rs:+8:9: +8:10
|
||||
let _10: i32; // in scope 6 at $DIR/ref_mut.rs:+10:9: +10:10
|
||||
let mut _11: &i32; // in scope 6 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
scope 7 {
|
||||
debug g => _10; // in scope 7 at $DIR/ref_mut.rs:+10:9: +10:10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/ref_mut.rs:+1:9: +1:14
|
||||
_1 = const 0_i32; // scope 0 at $DIR/ref_mut.rs:+1:17: +1:18
|
||||
StorageLive(_2); // scope 1 at $DIR/ref_mut.rs:+2:9: +2:10
|
||||
_2 = &mut _1; // scope 1 at $DIR/ref_mut.rs:+2:13: +2:19
|
||||
(*_2) = const 1_i32; // scope 2 at $DIR/ref_mut.rs:+3:5: +3:11
|
||||
StorageLive(_3); // scope 2 at $DIR/ref_mut.rs:+4:9: +4:10
|
||||
_3 = _1; // scope 2 at $DIR/ref_mut.rs:+4:13: +4:14
|
||||
StorageLive(_4); // scope 3 at $DIR/ref_mut.rs:+6:9: +6:10
|
||||
_4 = const 0_i32; // scope 3 at $DIR/ref_mut.rs:+6:13: +6:14
|
||||
StorageLive(_5); // scope 4 at $DIR/ref_mut.rs:+7:9: +7:14
|
||||
_5 = &_4; // scope 4 at $DIR/ref_mut.rs:+7:17: +7:19
|
||||
StorageLive(_6); // scope 5 at $DIR/ref_mut.rs:+8:9: +8:10
|
||||
_6 = &mut _5; // scope 5 at $DIR/ref_mut.rs:+8:13: +8:19
|
||||
StorageLive(_7); // scope 6 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
StorageLive(_8); // scope 6 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
_11 = const _; // scope 6 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
// mir::Constant
|
||||
// + span: $DIR/ref_mut.rs:14:10: 14:12
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
|
||||
_8 = &(*_11); // scope 6 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
_7 = &(*_8); // scope 6 at $DIR/ref_mut.rs:+9:10: +9:12
|
||||
(*_6) = move _7; // scope 6 at $DIR/ref_mut.rs:+9:5: +9:12
|
||||
StorageDead(_7); // scope 6 at $DIR/ref_mut.rs:+9:11: +9:12
|
||||
StorageDead(_8); // scope 6 at $DIR/ref_mut.rs:+9:12: +9:13
|
||||
StorageLive(_10); // scope 6 at $DIR/ref_mut.rs:+10:9: +10:10
|
||||
_10 = (*_5); // scope 6 at $DIR/ref_mut.rs:+10:13: +10:15
|
||||
_0 = const (); // scope 0 at $DIR/ref_mut.rs:+0:11: +11:2
|
||||
StorageDead(_10); // scope 6 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
StorageDead(_6); // scope 5 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
StorageDead(_5); // scope 4 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
StorageDead(_4); // scope 3 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
StorageDead(_3); // scope 2 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
StorageDead(_2); // scope 1 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
StorageDead(_1); // scope 0 at $DIR/ref_mut.rs:+11:1: +11:2
|
||||
return; // scope 0 at $DIR/ref_mut.rs:+11:2: +11:2
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR ref_mut.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let mut a = 0;
|
||||
let b = &mut a;
|
||||
*b = 1;
|
||||
let c = a;
|
||||
|
||||
let d = 0;
|
||||
let mut e = &d;
|
||||
let f = &mut e;
|
||||
*f = &1;
|
||||
let g = *e;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/ref_with_sb.rs:+0:11: +0:11
|
||||
let mut _1: i32; // in scope 0 at $DIR/ref_with_sb.rs:+1:9: +1:14
|
||||
let _2: (); // in scope 0 at $DIR/ref_with_sb.rs:+2:5: +2:15
|
||||
let mut _3: &i32; // in scope 0 at $DIR/ref_with_sb.rs:+2:12: +2:14
|
||||
let _4: &i32; // in scope 0 at $DIR/ref_with_sb.rs:+2:12: +2:14
|
||||
let _5: (); // in scope 0 at $DIR/ref_with_sb.rs:+4:5: +4:20
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/ref_with_sb.rs:+1:9: +1:14
|
||||
let _6: i32; // in scope 1 at $DIR/ref_with_sb.rs:+7:9: +7:10
|
||||
scope 2 {
|
||||
debug b => _6; // in scope 2 at $DIR/ref_with_sb.rs:+7:9: +7:10
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/ref_with_sb.rs:+1:9: +1:14
|
||||
_1 = const 0_i32; // scope 0 at $DIR/ref_with_sb.rs:+1:17: +1:18
|
||||
StorageLive(_2); // scope 1 at $DIR/ref_with_sb.rs:+2:5: +2:15
|
||||
StorageLive(_3); // scope 1 at $DIR/ref_with_sb.rs:+2:12: +2:14
|
||||
StorageLive(_4); // scope 1 at $DIR/ref_with_sb.rs:+2:12: +2:14
|
||||
_4 = &_1; // scope 1 at $DIR/ref_with_sb.rs:+2:12: +2:14
|
||||
_3 = &(*_4); // scope 1 at $DIR/ref_with_sb.rs:+2:12: +2:14
|
||||
_2 = escape::<i32>(move _3) -> bb1; // scope 1 at $DIR/ref_with_sb.rs:+2:5: +2:15
|
||||
// mir::Constant
|
||||
// + span: $DIR/ref_with_sb.rs:13:5: 13:11
|
||||
// + literal: Const { ty: for<'a> fn(&'a i32) {escape::<i32>}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_3); // scope 1 at $DIR/ref_with_sb.rs:+2:14: +2:15
|
||||
StorageDead(_4); // scope 1 at $DIR/ref_with_sb.rs:+2:15: +2:16
|
||||
StorageDead(_2); // scope 1 at $DIR/ref_with_sb.rs:+2:15: +2:16
|
||||
_1 = const 1_i32; // scope 1 at $DIR/ref_with_sb.rs:+3:5: +3:10
|
||||
StorageLive(_5); // scope 1 at $DIR/ref_with_sb.rs:+4:5: +4:20
|
||||
_5 = some_function() -> bb2; // scope 1 at $DIR/ref_with_sb.rs:+4:5: +4:20
|
||||
// mir::Constant
|
||||
// + span: $DIR/ref_with_sb.rs:15:5: 15:18
|
||||
// + literal: Const { ty: fn() {some_function}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_5); // scope 1 at $DIR/ref_with_sb.rs:+4:20: +4:21
|
||||
StorageLive(_6); // scope 1 at $DIR/ref_with_sb.rs:+7:9: +7:10
|
||||
- _6 = _1; // scope 1 at $DIR/ref_with_sb.rs:+7:13: +7:14
|
||||
+ _6 = const 1_i32; // scope 1 at $DIR/ref_with_sb.rs:+7:13: +7:14
|
||||
_0 = const (); // scope 0 at $DIR/ref_with_sb.rs:+0:11: +8:2
|
||||
StorageDead(_6); // scope 1 at $DIR/ref_with_sb.rs:+8:1: +8:2
|
||||
StorageDead(_1); // scope 0 at $DIR/ref_with_sb.rs:+8:1: +8:2
|
||||
return; // scope 0 at $DIR/ref_with_sb.rs:+8:2: +8:2
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
#[inline(never)]
|
||||
fn escape<T>(x: &T) {}
|
||||
|
||||
#[inline(never)]
|
||||
fn some_function() {}
|
||||
|
||||
// EMIT_MIR ref_with_sb.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let mut a = 0;
|
||||
escape(&a);
|
||||
a = 1;
|
||||
some_function();
|
||||
// With `-Zunsound-mir-opt`, this should be propagated
|
||||
// (because we assume Stacked Borrows).
|
||||
let b = a;
|
||||
}
|
@ -10,9 +10,9 @@
|
||||
let _5: (); // in scope 0 at $DIR/ref_without_sb.rs:+4:5: +4:20
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/ref_without_sb.rs:+1:9: +1:14
|
||||
let _6: i32; // in scope 1 at $DIR/ref_without_sb.rs:+7:9: +7:10
|
||||
let _6: i32; // in scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
|
||||
scope 2 {
|
||||
debug b => _6; // in scope 2 at $DIR/ref_without_sb.rs:+7:9: +7:10
|
||||
debug b => _6; // in scope 2 at $DIR/ref_without_sb.rs:+6:9: +6:10
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,12 +44,12 @@
|
||||
|
||||
bb2: {
|
||||
StorageDead(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:20: +4:21
|
||||
StorageLive(_6); // scope 1 at $DIR/ref_without_sb.rs:+7:9: +7:10
|
||||
_6 = _1; // scope 1 at $DIR/ref_without_sb.rs:+7:13: +7:14
|
||||
_0 = const (); // scope 0 at $DIR/ref_without_sb.rs:+0:11: +8:2
|
||||
StorageDead(_6); // scope 1 at $DIR/ref_without_sb.rs:+8:1: +8:2
|
||||
StorageDead(_1); // scope 0 at $DIR/ref_without_sb.rs:+8:1: +8:2
|
||||
return; // scope 0 at $DIR/ref_without_sb.rs:+8:2: +8:2
|
||||
StorageLive(_6); // scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
|
||||
_6 = _1; // scope 1 at $DIR/ref_without_sb.rs:+6:13: +6:14
|
||||
_0 = const (); // scope 0 at $DIR/ref_without_sb.rs:+0:11: +7:2
|
||||
StorageDead(_6); // scope 1 at $DIR/ref_without_sb.rs:+7:1: +7:2
|
||||
StorageDead(_1); // scope 0 at $DIR/ref_without_sb.rs:+7:1: +7:2
|
||||
return; // scope 0 at $DIR/ref_without_sb.rs:+7:2: +7:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ fn main() {
|
||||
escape(&a);
|
||||
a = 1;
|
||||
some_function();
|
||||
// Without `-Zunsound-mir-opt`, this should not be propagated
|
||||
// (because we do not assume Stacked Borrows).
|
||||
// This should currently not be propagated.
|
||||
let b = a;
|
||||
}
|
||||
|
@ -20,16 +20,12 @@
|
||||
StorageLive(_1); // scope 0 at $DIR/self_assign.rs:+1:9: +1:14
|
||||
_1 = const 0_i32; // scope 0 at $DIR/self_assign.rs:+1:17: +1:18
|
||||
StorageLive(_2); // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
|
||||
- _2 = _1; // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
|
||||
- _1 = Add(move _2, const 1_i32); // scope 1 at $DIR/self_assign.rs:+2:5: +2:14
|
||||
+ _2 = const 0_i32; // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
|
||||
+ _1 = const 1_i32; // scope 1 at $DIR/self_assign.rs:+2:5: +2:14
|
||||
_2 = _1; // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
|
||||
_1 = Add(move _2, const 1_i32); // scope 1 at $DIR/self_assign.rs:+2:5: +2:14
|
||||
StorageDead(_2); // scope 1 at $DIR/self_assign.rs:+2:13: +2:14
|
||||
StorageLive(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
|
||||
- _3 = _1; // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
|
||||
- _1 = move _3; // scope 1 at $DIR/self_assign.rs:+3:5: +3:10
|
||||
+ _3 = const 1_i32; // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
|
||||
+ _1 = const 1_i32; // scope 1 at $DIR/self_assign.rs:+3:5: +3:10
|
||||
_3 = _1; // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
|
||||
_1 = move _3; // scope 1 at $DIR/self_assign.rs:+3:5: +3:10
|
||||
StorageDead(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
|
||||
StorageLive(_4); // scope 1 at $DIR/self_assign.rs:+5:9: +5:14
|
||||
_4 = &_1; // scope 1 at $DIR/self_assign.rs:+5:17: +5:19
|
||||
@ -38,10 +34,8 @@
|
||||
_4 = move _5; // scope 2 at $DIR/self_assign.rs:+6:5: +6:10
|
||||
StorageDead(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
|
||||
StorageLive(_6); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
|
||||
- _6 = (*_4); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
|
||||
- _1 = move _6; // scope 2 at $DIR/self_assign.rs:+7:5: +7:11
|
||||
+ _6 = const 1_i32; // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
|
||||
+ _1 = const 1_i32; // scope 2 at $DIR/self_assign.rs:+7:5: +7:11
|
||||
_6 = (*_4); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
|
||||
_1 = move _6; // scope 2 at $DIR/self_assign.rs:+7:5: +7:11
|
||||
StorageDead(_6); // scope 2 at $DIR/self_assign.rs:+7:10: +7:11
|
||||
_0 = const (); // scope 0 at $DIR/self_assign.rs:+0:11: +8:2
|
||||
StorageDead(_4); // scope 1 at $DIR/self_assign.rs:+8:1: +8:2
|
||||
|
@ -1,5 +1,4 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR self_assign.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
|
@ -1,53 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/static_ref.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/static_ref.rs:+3:9: +3:10
|
||||
let mut _3: &i32; // in scope 0 at $DIR/static_ref.rs:+5:9: +5:11
|
||||
let _4: &i32; // in scope 0 at $DIR/static_ref.rs:+5:9: +5:11
|
||||
let _5: &i32; // in scope 0 at $DIR/static_ref.rs:+5:10: +5:11
|
||||
scope 1 {
|
||||
debug x => _1; // in scope 1 at $DIR/static_ref.rs:+3:9: +3:10
|
||||
let mut _2: &i32; // in scope 1 at $DIR/static_ref.rs:+4:9: +4:14
|
||||
scope 2 {
|
||||
debug r => _2; // in scope 2 at $DIR/static_ref.rs:+4:9: +4:14
|
||||
let _6: i32; // in scope 2 at $DIR/static_ref.rs:+6:9: +6:10
|
||||
scope 3 {
|
||||
debug y => _6; // in scope 3 at $DIR/static_ref.rs:+6:9: +6:10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/static_ref.rs:+3:9: +3:10
|
||||
_1 = const 0_i32; // scope 0 at $DIR/static_ref.rs:+3:13: +3:14
|
||||
StorageLive(_2); // scope 1 at $DIR/static_ref.rs:+4:9: +4:14
|
||||
_2 = &_1; // scope 1 at $DIR/static_ref.rs:+4:17: +4:19
|
||||
StorageLive(_3); // scope 2 at $DIR/static_ref.rs:+5:9: +5:11
|
||||
StorageLive(_4); // scope 2 at $DIR/static_ref.rs:+5:9: +5:11
|
||||
StorageLive(_5); // scope 2 at $DIR/static_ref.rs:+5:10: +5:11
|
||||
_5 = const {alloc1: &i32}; // scope 2 at $DIR/static_ref.rs:+5:10: +5:11
|
||||
// mir::Constant
|
||||
// + span: $DIR/static_ref.rs:10:10: 10:11
|
||||
// + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
|
||||
_4 = &(*_5); // scope 2 at $DIR/static_ref.rs:+5:9: +5:11
|
||||
_3 = &(*_4); // scope 2 at $DIR/static_ref.rs:+5:9: +5:11
|
||||
_2 = move _3; // scope 2 at $DIR/static_ref.rs:+5:5: +5:11
|
||||
StorageDead(_3); // scope 2 at $DIR/static_ref.rs:+5:10: +5:11
|
||||
StorageDead(_5); // scope 2 at $DIR/static_ref.rs:+5:11: +5:12
|
||||
StorageDead(_4); // scope 2 at $DIR/static_ref.rs:+5:11: +5:12
|
||||
StorageLive(_6); // scope 2 at $DIR/static_ref.rs:+6:9: +6:10
|
||||
_6 = (*_2); // scope 2 at $DIR/static_ref.rs:+6:13: +6:15
|
||||
_0 = const (); // scope 0 at $DIR/static_ref.rs:+0:11: +7:2
|
||||
StorageDead(_6); // scope 2 at $DIR/static_ref.rs:+7:1: +7:2
|
||||
StorageDead(_2); // scope 1 at $DIR/static_ref.rs:+7:1: +7:2
|
||||
StorageDead(_1); // scope 0 at $DIR/static_ref.rs:+7:1: +7:2
|
||||
return; // scope 0 at $DIR/static_ref.rs:+7:2: +7:2
|
||||
}
|
||||
}
|
||||
|
||||
alloc1 (static: P, size: 4, align: 4) {
|
||||
05 00 00 00 │ ....
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR static_ref.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
// Currently, this will not propagate.
|
||||
static P: i32 = 5;
|
||||
let x = 0;
|
||||
let mut r = &x;
|
||||
r = &P;
|
||||
let y = *r;
|
||||
}
|
@ -4,9 +4,9 @@
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/terminator.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/terminator.rs:+1:9: +1:10
|
||||
let _2: (); // in scope 0 at $DIR/terminator.rs:+2:5: +2:15
|
||||
let mut _3: i32; // in scope 0 at $DIR/terminator.rs:+2:9: +2:14
|
||||
let mut _4: i32; // in scope 0 at $DIR/terminator.rs:+2:9: +2:10
|
||||
let _2: (); // in scope 0 at $DIR/terminator.rs:+3:5: +3:15
|
||||
let mut _3: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:14
|
||||
let mut _4: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:10
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/terminator.rs:+1:9: +1:10
|
||||
}
|
||||
@ -14,27 +14,27 @@
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/terminator.rs:+1:9: +1:10
|
||||
_1 = const 1_i32; // scope 0 at $DIR/terminator.rs:+1:13: +1:14
|
||||
StorageLive(_2); // scope 1 at $DIR/terminator.rs:+2:5: +2:15
|
||||
StorageLive(_3); // scope 1 at $DIR/terminator.rs:+2:9: +2:14
|
||||
StorageLive(_4); // scope 1 at $DIR/terminator.rs:+2:9: +2:10
|
||||
- _4 = _1; // scope 1 at $DIR/terminator.rs:+2:9: +2:10
|
||||
- _3 = Add(move _4, const 1_i32); // scope 1 at $DIR/terminator.rs:+2:9: +2:14
|
||||
+ _4 = const 1_i32; // scope 1 at $DIR/terminator.rs:+2:9: +2:10
|
||||
+ _3 = const 2_i32; // scope 1 at $DIR/terminator.rs:+2:9: +2:14
|
||||
StorageDead(_4); // scope 1 at $DIR/terminator.rs:+2:13: +2:14
|
||||
- _2 = foo(move _3) -> bb1; // scope 1 at $DIR/terminator.rs:+2:5: +2:15
|
||||
+ _2 = foo(const 2_i32) -> bb1; // scope 1 at $DIR/terminator.rs:+2:5: +2:15
|
||||
StorageLive(_2); // scope 1 at $DIR/terminator.rs:+3:5: +3:15
|
||||
StorageLive(_3); // scope 1 at $DIR/terminator.rs:+3:9: +3:14
|
||||
StorageLive(_4); // scope 1 at $DIR/terminator.rs:+3:9: +3:10
|
||||
- _4 = _1; // scope 1 at $DIR/terminator.rs:+3:9: +3:10
|
||||
- _3 = Add(move _4, const 1_i32); // scope 1 at $DIR/terminator.rs:+3:9: +3:14
|
||||
+ _4 = const 1_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:10
|
||||
+ _3 = const 2_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:14
|
||||
StorageDead(_4); // scope 1 at $DIR/terminator.rs:+3:13: +3:14
|
||||
- _2 = foo(move _3) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15
|
||||
+ _2 = foo(const 2_i32) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15
|
||||
// mir::Constant
|
||||
// + span: $DIR/terminator.rs:9:5: 9:8
|
||||
// + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_3); // scope 1 at $DIR/terminator.rs:+2:14: +2:15
|
||||
StorageDead(_2); // scope 1 at $DIR/terminator.rs:+2:15: +2:16
|
||||
_0 = const (); // scope 0 at $DIR/terminator.rs:+0:11: +3:2
|
||||
StorageDead(_1); // scope 0 at $DIR/terminator.rs:+3:1: +3:2
|
||||
return; // scope 0 at $DIR/terminator.rs:+3:2: +3:2
|
||||
StorageDead(_3); // scope 1 at $DIR/terminator.rs:+3:14: +3:15
|
||||
StorageDead(_2); // scope 1 at $DIR/terminator.rs:+3:15: +3:16
|
||||
_0 = const (); // scope 0 at $DIR/terminator.rs:+0:11: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/terminator.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/terminator.rs:+4:2: +4:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
fn foo(n: i32) {}
|
||||
|
||||
// EMIT_MIR terminator.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let a = 1;
|
||||
// Checks that we propagate into terminators.
|
||||
foo(a + 1);
|
||||
}
|
||||
|
@ -4,26 +4,21 @@
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/tuple.rs:+0:11: +0:11
|
||||
let mut _1: (i32, i32); // in scope 0 at $DIR/tuple.rs:+1:9: +1:14
|
||||
let mut _4: i32; // in scope 0 at $DIR/tuple.rs:+3:13: +3:22
|
||||
let mut _5: i32; // in scope 0 at $DIR/tuple.rs:+3:13: +3:16
|
||||
let mut _6: i32; // in scope 0 at $DIR/tuple.rs:+3:19: +3:22
|
||||
let mut _7: &(i32, i32); // in scope 0 at $DIR/tuple.rs:+5:9: +5:11
|
||||
let _8: &(i32, i32); // in scope 0 at $DIR/tuple.rs:+5:9: +5:11
|
||||
let mut _10: i32; // in scope 0 at $DIR/tuple.rs:+6:13: +6:22
|
||||
let mut _11: i32; // in scope 0 at $DIR/tuple.rs:+6:13: +6:16
|
||||
let mut _12: i32; // in scope 0 at $DIR/tuple.rs:+6:19: +6:22
|
||||
let mut _3: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:22
|
||||
let mut _4: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:16
|
||||
let mut _5: i32; // in scope 0 at $DIR/tuple.rs:+2:19: +2:22
|
||||
let mut _7: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:22
|
||||
let mut _8: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:16
|
||||
let mut _9: i32; // in scope 0 at $DIR/tuple.rs:+4:19: +4:22
|
||||
let mut _10: i32; // in scope 0 at $DIR/tuple.rs:+4:25: +4:26
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/tuple.rs:+1:9: +1:14
|
||||
let mut _2: &(i32, i32); // in scope 1 at $DIR/tuple.rs:+2:9: +2:14
|
||||
let _2: i32; // in scope 1 at $DIR/tuple.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug b => _2; // in scope 2 at $DIR/tuple.rs:+2:9: +2:14
|
||||
let _3: i32; // in scope 2 at $DIR/tuple.rs:+3:9: +3:10
|
||||
debug b => _2; // in scope 2 at $DIR/tuple.rs:+2:9: +2:10
|
||||
let _6: i32; // in scope 2 at $DIR/tuple.rs:+4:9: +4:10
|
||||
scope 3 {
|
||||
debug c => _3; // in scope 3 at $DIR/tuple.rs:+3:9: +3:10
|
||||
let _9: i32; // in scope 3 at $DIR/tuple.rs:+6:9: +6:10
|
||||
scope 4 {
|
||||
debug d => _9; // in scope 4 at $DIR/tuple.rs:+6:9: +6:10
|
||||
}
|
||||
debug c => _6; // in scope 3 at $DIR/tuple.rs:+4:9: +4:10
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,54 +28,48 @@
|
||||
Deinit(_1); // scope 0 at $DIR/tuple.rs:+1:17: +1:23
|
||||
(_1.0: i32) = const 1_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23
|
||||
(_1.1: i32) = const 2_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23
|
||||
StorageLive(_2); // scope 1 at $DIR/tuple.rs:+2:9: +2:14
|
||||
_2 = &_1; // scope 1 at $DIR/tuple.rs:+2:17: +2:19
|
||||
StorageLive(_3); // scope 2 at $DIR/tuple.rs:+3:9: +3:10
|
||||
StorageLive(_4); // scope 2 at $DIR/tuple.rs:+3:13: +3:22
|
||||
StorageLive(_5); // scope 2 at $DIR/tuple.rs:+3:13: +3:16
|
||||
- _5 = (_1.0: i32); // scope 2 at $DIR/tuple.rs:+3:13: +3:16
|
||||
+ _5 = const 1_i32; // scope 2 at $DIR/tuple.rs:+3:13: +3:16
|
||||
StorageLive(_6); // scope 2 at $DIR/tuple.rs:+3:19: +3:22
|
||||
- _6 = ((*_2).1: i32); // scope 2 at $DIR/tuple.rs:+3:19: +3:22
|
||||
- _4 = Add(move _5, move _6); // scope 2 at $DIR/tuple.rs:+3:13: +3:22
|
||||
+ _6 = const 2_i32; // scope 2 at $DIR/tuple.rs:+3:19: +3:22
|
||||
+ _4 = const 3_i32; // scope 2 at $DIR/tuple.rs:+3:13: +3:22
|
||||
StorageDead(_6); // scope 2 at $DIR/tuple.rs:+3:21: +3:22
|
||||
StorageDead(_5); // scope 2 at $DIR/tuple.rs:+3:21: +3:22
|
||||
- _3 = Add(move _4, const 3_i32); // scope 2 at $DIR/tuple.rs:+3:13: +3:26
|
||||
+ _3 = const 6_i32; // scope 2 at $DIR/tuple.rs:+3:13: +3:26
|
||||
StorageDead(_4); // scope 2 at $DIR/tuple.rs:+3:25: +3:26
|
||||
Deinit(_1); // scope 3 at $DIR/tuple.rs:+4:5: +4:15
|
||||
(_1.0: i32) = const 2_i32; // scope 3 at $DIR/tuple.rs:+4:5: +4:15
|
||||
(_1.1: i32) = const 3_i32; // scope 3 at $DIR/tuple.rs:+4:5: +4:15
|
||||
StorageLive(_7); // scope 3 at $DIR/tuple.rs:+5:9: +5:11
|
||||
StorageLive(_8); // scope 3 at $DIR/tuple.rs:+5:9: +5:11
|
||||
_8 = &_1; // scope 3 at $DIR/tuple.rs:+5:9: +5:11
|
||||
_7 = &(*_8); // scope 3 at $DIR/tuple.rs:+5:9: +5:11
|
||||
_2 = move _7; // scope 3 at $DIR/tuple.rs:+5:5: +5:11
|
||||
StorageDead(_7); // scope 3 at $DIR/tuple.rs:+5:10: +5:11
|
||||
StorageDead(_8); // scope 3 at $DIR/tuple.rs:+5:11: +5:12
|
||||
StorageLive(_9); // scope 3 at $DIR/tuple.rs:+6:9: +6:10
|
||||
StorageLive(_10); // scope 3 at $DIR/tuple.rs:+6:13: +6:22
|
||||
StorageLive(_11); // scope 3 at $DIR/tuple.rs:+6:13: +6:16
|
||||
- _11 = (_1.0: i32); // scope 3 at $DIR/tuple.rs:+6:13: +6:16
|
||||
+ _11 = const 2_i32; // scope 3 at $DIR/tuple.rs:+6:13: +6:16
|
||||
StorageLive(_12); // scope 3 at $DIR/tuple.rs:+6:19: +6:22
|
||||
- _12 = ((*_2).1: i32); // scope 3 at $DIR/tuple.rs:+6:19: +6:22
|
||||
- _10 = Add(move _11, move _12); // scope 3 at $DIR/tuple.rs:+6:13: +6:22
|
||||
+ _12 = const 3_i32; // scope 3 at $DIR/tuple.rs:+6:19: +6:22
|
||||
+ _10 = const 5_i32; // scope 3 at $DIR/tuple.rs:+6:13: +6:22
|
||||
StorageDead(_12); // scope 3 at $DIR/tuple.rs:+6:21: +6:22
|
||||
StorageDead(_11); // scope 3 at $DIR/tuple.rs:+6:21: +6:22
|
||||
- _9 = Add(move _10, const 4_i32); // scope 3 at $DIR/tuple.rs:+6:13: +6:26
|
||||
+ _9 = const 9_i32; // scope 3 at $DIR/tuple.rs:+6:13: +6:26
|
||||
StorageDead(_10); // scope 3 at $DIR/tuple.rs:+6:25: +6:26
|
||||
_0 = const (); // scope 0 at $DIR/tuple.rs:+0:11: +7:2
|
||||
StorageDead(_9); // scope 3 at $DIR/tuple.rs:+7:1: +7:2
|
||||
StorageDead(_3); // scope 2 at $DIR/tuple.rs:+7:1: +7:2
|
||||
StorageDead(_2); // scope 1 at $DIR/tuple.rs:+7:1: +7:2
|
||||
StorageDead(_1); // scope 0 at $DIR/tuple.rs:+7:1: +7:2
|
||||
return; // scope 0 at $DIR/tuple.rs:+7:2: +7:2
|
||||
StorageLive(_2); // scope 1 at $DIR/tuple.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 1 at $DIR/tuple.rs:+2:13: +2:22
|
||||
StorageLive(_4); // scope 1 at $DIR/tuple.rs:+2:13: +2:16
|
||||
- _4 = (_1.0: i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:16
|
||||
+ _4 = const 1_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:16
|
||||
StorageLive(_5); // scope 1 at $DIR/tuple.rs:+2:19: +2:22
|
||||
- _5 = (_1.1: i32); // scope 1 at $DIR/tuple.rs:+2:19: +2:22
|
||||
- _3 = Add(move _4, move _5); // scope 1 at $DIR/tuple.rs:+2:13: +2:22
|
||||
+ _5 = const 2_i32; // scope 1 at $DIR/tuple.rs:+2:19: +2:22
|
||||
+ _3 = const 3_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:22
|
||||
StorageDead(_5); // scope 1 at $DIR/tuple.rs:+2:21: +2:22
|
||||
StorageDead(_4); // scope 1 at $DIR/tuple.rs:+2:21: +2:22
|
||||
- _2 = Add(move _3, const 3_i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:26
|
||||
+ _2 = const 6_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:26
|
||||
StorageDead(_3); // scope 1 at $DIR/tuple.rs:+2:25: +2:26
|
||||
Deinit(_1); // scope 2 at $DIR/tuple.rs:+3:5: +3:15
|
||||
(_1.0: i32) = const 2_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15
|
||||
(_1.1: i32) = const 3_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15
|
||||
StorageLive(_6); // scope 2 at $DIR/tuple.rs:+4:9: +4:10
|
||||
StorageLive(_7); // scope 2 at $DIR/tuple.rs:+4:13: +4:22
|
||||
StorageLive(_8); // scope 2 at $DIR/tuple.rs:+4:13: +4:16
|
||||
- _8 = (_1.0: i32); // scope 2 at $DIR/tuple.rs:+4:13: +4:16
|
||||
+ _8 = const 2_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:16
|
||||
StorageLive(_9); // scope 2 at $DIR/tuple.rs:+4:19: +4:22
|
||||
- _9 = (_1.1: i32); // scope 2 at $DIR/tuple.rs:+4:19: +4:22
|
||||
- _7 = Add(move _8, move _9); // scope 2 at $DIR/tuple.rs:+4:13: +4:22
|
||||
+ _9 = const 3_i32; // scope 2 at $DIR/tuple.rs:+4:19: +4:22
|
||||
+ _7 = const 5_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:22
|
||||
StorageDead(_9); // scope 2 at $DIR/tuple.rs:+4:21: +4:22
|
||||
StorageDead(_8); // scope 2 at $DIR/tuple.rs:+4:21: +4:22
|
||||
StorageLive(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
|
||||
- _10 = _2; // scope 2 at $DIR/tuple.rs:+4:25: +4:26
|
||||
- _6 = Add(move _7, move _10); // scope 2 at $DIR/tuple.rs:+4:13: +4:26
|
||||
+ _10 = const 6_i32; // scope 2 at $DIR/tuple.rs:+4:25: +4:26
|
||||
+ _6 = const 11_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:26
|
||||
StorageDead(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
|
||||
StorageDead(_7); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
|
||||
_0 = const (); // scope 0 at $DIR/tuple.rs:+0:11: +5:2
|
||||
StorageDead(_6); // scope 2 at $DIR/tuple.rs:+5:1: +5:2
|
||||
StorageDead(_2); // scope 1 at $DIR/tuple.rs:+5:1: +5:2
|
||||
StorageDead(_1); // scope 0 at $DIR/tuple.rs:+5:1: +5:2
|
||||
return; // scope 0 at $DIR/tuple.rs:+5:2: +5:2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
|
||||
// EMIT_MIR tuple.main.DataflowConstProp.diff
|
||||
fn main() {
|
||||
let mut a = (1, 2);
|
||||
let mut b = &a;
|
||||
let c = a.0 + b.1 + 3;
|
||||
let b = a.0 + a.1 + 3;
|
||||
a = (2, 3);
|
||||
b = &a;
|
||||
let d = a.0 + b.1 + 4;
|
||||
let c = a.0 + a.1 + b;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user