summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_dataflow/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_mir_dataflow/src
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_mir_dataflow/src')
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs253
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs17
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs28
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs7
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs12
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs30
12 files changed, 174 insertions, 200 deletions
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index bd1208762..bd8ec82df 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -7,7 +7,7 @@ use rustc_middle::traits::Reveal;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_target::abi::VariantIdx;
+use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use std::{fmt, iter};
/// The value of an inserted drop flag.
@@ -77,10 +77,10 @@ impl Unwind {
}
}
- fn into_option(self) -> Option<BasicBlock> {
+ fn into_action(self) -> UnwindAction {
match self {
- Unwind::To(bb) => Some(bb),
- Unwind::InCleanup => None,
+ Unwind::To(bb) => UnwindAction::Cleanup(bb),
+ Unwind::InCleanup => UnwindAction::Terminate,
}
}
@@ -129,7 +129,7 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
/// Returns the subpath of a field of `path` (or `None` if there is no dedicated subpath).
///
/// If this returns `None`, `field` will not get a dedicated drop flag.
- fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path>;
+ fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option<Self::Path>;
/// Returns the subpath of a dereference of `path` (or `None` if there is no dedicated subpath).
///
@@ -236,7 +236,7 @@ where
TerminatorKind::Drop {
place: self.place,
target: self.succ,
- unwind: self.unwind.into_option(),
+ unwind: self.unwind.into_action(),
},
);
}
@@ -269,7 +269,7 @@ where
.iter()
.enumerate()
.map(|(i, f)| {
- let field = Field::new(i);
+ let field = FieldIdx::new(i);
let subpath = self.elaborator.field_subpath(variant_path, field);
let tcx = self.tcx();
@@ -397,8 +397,8 @@ where
.enumerate()
.map(|(i, &ty)| {
(
- self.tcx().mk_place_field(self.place, Field::new(i), ty),
- self.elaborator.field_subpath(self.path, Field::new(i)),
+ self.tcx().mk_place_field(self.place, FieldIdx::new(i), ty),
+ self.elaborator.field_subpath(self.path, FieldIdx::new(i)),
)
})
.collect();
@@ -411,14 +411,14 @@ where
fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
// drop glue is sent straight to codegen
// box cannot be directly dereferenced
- let unique_ty = adt.non_enum_variant().fields[0].ty(self.tcx(), substs);
- let nonnull_ty =
- unique_ty.ty_adt_def().unwrap().non_enum_variant().fields[0].ty(self.tcx(), substs);
+ let unique_ty = adt.non_enum_variant().fields[FieldIdx::new(0)].ty(self.tcx(), substs);
+ let unique_variant = unique_ty.ty_adt_def().unwrap().non_enum_variant();
+ let nonnull_ty = unique_variant.fields[FieldIdx::from_u32(0)].ty(self.tcx(), substs);
let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty());
- let unique_place = self.tcx().mk_place_field(self.place, Field::new(0), unique_ty);
- let nonnull_place = self.tcx().mk_place_field(unique_place, Field::new(0), nonnull_ty);
- let ptr_place = self.tcx().mk_place_field(nonnull_place, Field::new(0), ptr_ty);
+ let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty);
+ let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::new(0), nonnull_ty);
+ let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::new(0), ptr_ty);
let interior = self.tcx().mk_place_deref(ptr_place);
let interior_path = self.elaborator.deref_subpath(self.path);
@@ -468,7 +468,7 @@ where
let fields = self.move_paths_for_fields(
self.place,
self.path,
- &adt.variant(VariantIdx::new(0)),
+ &adt.variant(FIRST_VARIANT),
substs,
);
self.drop_ladder(fields, succ, unwind)
@@ -640,7 +640,7 @@ where
args: vec![Operand::Move(Place::from(ref_place))],
destination: unit_temp,
target: Some(succ),
- cleanup: unwind.into_option(),
+ unwind: unwind.into_action(),
from_hir_call: true,
fn_span: self.source_info.span,
},
@@ -655,26 +655,20 @@ where
///
/// ```text
/// loop-block:
- /// can_go = cur == length_or_end
+ /// can_go = cur == len
/// if can_go then succ else drop-block
/// drop-block:
- /// if ptr_based {
- /// ptr = cur
- /// cur = cur.offset(1)
- /// } else {
- /// ptr = &raw mut P[cur]
- /// cur = cur + 1
- /// }
+ /// ptr = &raw mut P[cur]
+ /// cur = cur + 1
/// drop(ptr)
/// ```
fn drop_loop(
&mut self,
succ: BasicBlock,
cur: Local,
- length_or_end: Place<'tcx>,
+ len: Local,
ety: Ty<'tcx>,
unwind: Unwind,
- ptr_based: bool,
) -> BasicBlock {
let copy = |place: Place<'tcx>| Operand::Copy(place);
let move_ = |place: Place<'tcx>| Operand::Move(place);
@@ -683,22 +677,19 @@ where
let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
let ptr = Place::from(self.new_temp(ptr_ty));
let can_go = Place::from(self.new_temp(tcx.types.bool));
-
let one = self.constant_usize(1);
- let (ptr_next, cur_next) = if ptr_based {
- (
- Rvalue::Use(copy(cur.into())),
- Rvalue::BinaryOp(BinOp::Offset, Box::new((move_(cur.into()), one))),
- )
- } else {
- (
- Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
- Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
- )
- };
let drop_block = BasicBlockData {
- statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)],
+ statements: vec![
+ self.assign(
+ ptr,
+ Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
+ ),
+ self.assign(
+ cur.into(),
+ Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
+ ),
+ ],
is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator {
source_info: self.source_info,
@@ -711,10 +702,7 @@ where
let loop_block = BasicBlockData {
statements: vec![self.assign(
can_go,
- Rvalue::BinaryOp(
- BinOp::Eq,
- Box::new((copy(Place::from(cur)), copy(length_or_end))),
- ),
+ Rvalue::BinaryOp(BinOp::Eq, Box::new((copy(Place::from(cur)), copy(len.into())))),
)],
is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator {
@@ -729,7 +717,7 @@ where
TerminatorKind::Drop {
place: tcx.mk_place_deref(ptr),
target: loop_block,
- unwind: unwind.into_option(),
+ unwind: unwind.into_action(),
},
);
@@ -738,118 +726,97 @@ where
fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
-
- // if size_of::<ety>() == 0 {
- // index_based_loop
- // } else {
- // ptr_based_loop
- // }
-
let tcx = self.tcx();
if let Some(size) = opt_size {
- let fields: Vec<(Place<'tcx>, Option<D::Path>)> = (0..size)
- .map(|i| {
- (
- tcx.mk_place_elem(
- self.place,
- ProjectionElem::ConstantIndex {
- offset: i,
- min_length: size,
- from_end: false,
- },
- ),
- self.elaborator.array_subpath(self.path, i, size),
- )
- })
- .collect();
-
- if fields.iter().any(|(_, path)| path.is_some()) {
+ enum ProjectionKind<Path> {
+ Drop(std::ops::Range<u64>),
+ Keep(u64, Path),
+ }
+ // Previously, we'd make a projection for every element in the array and create a drop
+ // ladder if any `array_subpath` was `Some`, i.e. moving out with an array pattern.
+ // This caused huge memory usage when generating the drops for large arrays, so we instead
+ // record the *subslices* which are dropped and the *indexes* which are kept
+ let mut drop_ranges = vec![];
+ let mut dropping = true;
+ let mut start = 0;
+ for i in 0..size {
+ let path = self.elaborator.array_subpath(self.path, i, size);
+ if dropping && path.is_some() {
+ drop_ranges.push(ProjectionKind::Drop(start..i));
+ dropping = false;
+ } else if !dropping && path.is_none() {
+ dropping = true;
+ start = i;
+ }
+ if let Some(path) = path {
+ drop_ranges.push(ProjectionKind::Keep(i, path));
+ }
+ }
+ if !drop_ranges.is_empty() {
+ if dropping {
+ drop_ranges.push(ProjectionKind::Drop(start..size));
+ }
+ let fields = drop_ranges
+ .iter()
+ .rev()
+ .map(|p| {
+ let (project, path) = match p {
+ ProjectionKind::Drop(r) => (
+ ProjectionElem::Subslice {
+ from: r.start,
+ to: r.end,
+ from_end: false,
+ },
+ None,
+ ),
+ &ProjectionKind::Keep(offset, path) => (
+ ProjectionElem::ConstantIndex {
+ offset,
+ min_length: size,
+ from_end: false,
+ },
+ Some(path),
+ ),
+ };
+ (tcx.mk_place_elem(self.place, project), path)
+ })
+ .collect::<Vec<_>>();
let (succ, unwind) = self.drop_ladder_bottom();
return self.drop_ladder(fields, succ, unwind).0;
}
}
- let move_ = |place: Place<'tcx>| Operand::Move(place);
- let elem_size = Place::from(self.new_temp(tcx.types.usize));
- let len = Place::from(self.new_temp(tcx.types.usize));
-
- let base_block = BasicBlockData {
- statements: vec![
- self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
- self.assign(len, Rvalue::Len(self.place)),
- ],
- is_cleanup: self.unwind.is_cleanup(),
- terminator: Some(Terminator {
- source_info: self.source_info,
- kind: TerminatorKind::SwitchInt {
- discr: move_(elem_size),
- targets: SwitchTargets::static_if(
- 0,
- self.drop_loop_pair(ety, false, len),
- self.drop_loop_pair(ety, true, len),
- ),
- },
- }),
- };
- self.elaborator.patch().new_block(base_block)
+ self.drop_loop_pair(ety)
}
/// Creates a pair of drop-loops of `place`, which drops its contents, even
- /// in the case of 1 panic. If `ptr_based`, creates a pointer loop,
- /// otherwise create an index loop.
- fn drop_loop_pair(
- &mut self,
- ety: Ty<'tcx>,
- ptr_based: bool,
- length: Place<'tcx>,
- ) -> BasicBlock {
- debug!("drop_loop_pair({:?}, {:?})", ety, ptr_based);
+ /// in the case of 1 panic.
+ fn drop_loop_pair(&mut self, ety: Ty<'tcx>) -> BasicBlock {
+ debug!("drop_loop_pair({:?})", ety);
let tcx = self.tcx();
- let iter_ty = if ptr_based { tcx.mk_mut_ptr(ety) } else { tcx.types.usize };
+ let len = self.new_temp(tcx.types.usize);
+ let cur = self.new_temp(tcx.types.usize);
- let cur = self.new_temp(iter_ty);
- let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length };
+ let unwind =
+ self.unwind.map(|unwind| self.drop_loop(unwind, cur, len, ety, Unwind::InCleanup));
- let unwind = self.unwind.map(|unwind| {
- self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based)
- });
+ let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind);
- let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based);
-
- let cur = Place::from(cur);
- let drop_block_stmts = if ptr_based {
- let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place));
- let tmp = Place::from(self.new_temp(tmp_ty));
- // tmp = &raw mut P;
- // cur = tmp as *mut T;
- // end = Offset(cur, len);
- let mir_cast_kind = ty::cast::mir_cast_kind(iter_ty, tmp_ty);
- vec![
- self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
- self.assign(cur, Rvalue::Cast(mir_cast_kind, Operand::Move(tmp), iter_ty)),
- self.assign(
- length_or_end,
- Rvalue::BinaryOp(
- BinOp::Offset,
- Box::new((Operand::Copy(cur), Operand::Move(length))),
- ),
- ),
- ]
- } else {
- // cur = 0 (length already pushed)
- let zero = self.constant_usize(0);
- vec![self.assign(cur, Rvalue::Use(zero))]
- };
- let drop_block = self.elaborator.patch().new_block(BasicBlockData {
- statements: drop_block_stmts,
+ let zero = self.constant_usize(0);
+ let block = BasicBlockData {
+ statements: vec![
+ self.assign(len.into(), Rvalue::Len(self.place)),
+ self.assign(cur.into(), Rvalue::Use(zero)),
+ ],
is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator {
source_info: self.source_info,
kind: TerminatorKind::Goto { target: loop_block },
}),
- });
+ };
+ let drop_block = self.elaborator.patch().new_block(block);
// FIXME(#34708): handle partially-dropped array/slice elements.
let reset_block = self.drop_flag_reset_block(DropFlagMode::Deep, drop_block, unwind);
self.drop_flag_test_block(reset_block, self.succ, unwind)
@@ -893,7 +860,7 @@ where
let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env());
self.open_drop_for_array(*ety, size)
}
- ty::Slice(ety) => self.open_drop_for_array(*ety, None),
+ ty::Slice(ety) => self.drop_loop_pair(*ety),
_ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
}
@@ -963,12 +930,12 @@ where
let unit_temp = Place::from(self.new_temp(tcx.mk_unit()));
let free_func = tcx.require_lang_item(LangItem::BoxFree, Some(self.source_info.span));
let args = adt
- .variant(VariantIdx::new(0))
+ .variant(FIRST_VARIANT)
.fields
.iter()
.enumerate()
.map(|(i, f)| {
- let field = Field::new(i);
+ let field = FieldIdx::new(i);
let field_ty = f.ty(tcx, substs);
Operand::Move(tcx.mk_place_field(self.place, field, field_ty))
})
@@ -979,7 +946,11 @@ where
args,
destination: unit_temp,
target: Some(target),
- cleanup: None,
+ unwind: if unwind.is_cleanup() {
+ UnwindAction::Terminate
+ } else {
+ UnwindAction::Continue
+ },
from_hir_call: false,
fn_span: self.source_info.span,
}; // FIXME(#43234)
@@ -992,7 +963,7 @@ where
fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
let block =
- TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_option() };
+ TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_action() };
self.new_block(unwind, block)
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 2ae3ae02f..c8fe1af66 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -1,4 +1,4 @@
-use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets};
+use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets, UnwindAction};
use rustc_middle::ty::TyCtxt;
use std::ops::RangeInclusive;
@@ -474,15 +474,14 @@ impl Direction for Forward {
{
use mir::TerminatorKind::*;
match bb_data.terminator().kind {
- Return | Resume | Abort | GeneratorDrop | Unreachable => {}
+ Return | Resume | Terminate | GeneratorDrop | Unreachable => {}
Goto { target } => propagate(target, exit_state),
- Assert { target, cleanup: unwind, expected: _, msg: _, cond: _ }
+ Assert { target, unwind, expected: _, msg: _, cond: _ }
| Drop { target, unwind, place: _ }
- | DropAndReplace { target, unwind, value: _, place: _ }
| FalseUnwind { real_target: target, unwind } => {
- if let Some(unwind) = unwind {
+ if let UnwindAction::Cleanup(unwind) = unwind {
propagate(unwind, exit_state);
}
@@ -504,7 +503,7 @@ impl Direction for Forward {
}
Call {
- cleanup,
+ unwind,
destination,
target,
func: _,
@@ -512,7 +511,7 @@ impl Direction for Forward {
from_hir_call: _,
fn_span: _,
} => {
- if let Some(unwind) = cleanup {
+ if let UnwindAction::Cleanup(unwind) = unwind {
propagate(unwind, exit_state);
}
@@ -534,9 +533,9 @@ impl Direction for Forward {
options: _,
line_spans: _,
destination,
- cleanup,
+ unwind,
} => {
- if let Some(unwind) = cleanup {
+ if let UnwindAction::Cleanup(unwind) = unwind {
propagate(unwind, exit_state);
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 91c3bf0ad..2abdee064 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -15,6 +15,7 @@ use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::{self, traversal, BasicBlock};
use rustc_middle::mir::{create_dump_file, dump_enabled};
+use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::{sym, Symbol};
@@ -285,7 +286,7 @@ where
if tcx.sess.opts.unstable_opts.graphviz_dark_mode {
render_opts.push(dot::RenderOption::DarkTheme);
}
- dot::render_opts(&graphviz, &mut buf, &render_opts)?;
+ with_no_trimmed_paths!(dot::render_opts(&graphviz, &mut buf, &render_opts)?);
file.write_all(&buf)?;
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 96c42894b..707729f8f 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -6,6 +6,7 @@ use std::{io, ops, str};
use regex::Regex;
use rustc_graphviz as dot;
+use rustc_index::bit_set::BitSet;
use rustc_middle::mir::graphviz_safe_def_name;
use rustc_middle::mir::{self, BasicBlock, Body, Location};
@@ -34,6 +35,7 @@ where
body: &'a Body<'tcx>,
results: &'a Results<'tcx, A>,
style: OutputStyle,
+ reachable: BitSet<BasicBlock>,
}
impl<'a, 'tcx, A> Formatter<'a, 'tcx, A>
@@ -41,7 +43,8 @@ where
A: Analysis<'tcx>,
{
pub fn new(body: &'a Body<'tcx>, results: &'a Results<'tcx, A>, style: OutputStyle) -> Self {
- Formatter { body, results, style }
+ let reachable = mir::traversal::reachable_as_bitset(body);
+ Formatter { body, results, style, reachable }
}
}
@@ -108,7 +111,12 @@ where
type Edge = CfgEdge;
fn nodes(&self) -> dot::Nodes<'_, Self::Node> {
- self.body.basic_blocks.indices().collect::<Vec<_>>().into()
+ self.body
+ .basic_blocks
+ .indices()
+ .filter(|&idx| self.reachable.contains(idx))
+ .collect::<Vec<_>>()
+ .into()
}
fn edges(&self) -> dot::Edges<'_, Self::Edge> {
@@ -386,8 +394,8 @@ where
) -> io::Result<()> {
let diffs = StateDiffCollector::run(body, block, self.results.results(), self.style);
- let mut befores = diffs.before.map(|v| v.into_iter());
- let mut afters = diffs.after.into_iter();
+ let mut diffs_before = diffs.before.map(|v| v.into_iter());
+ let mut diffs_after = diffs.after.into_iter();
let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| {
if A::Direction::IS_FORWARD { it.next().unwrap() } else { it.next_back().unwrap() }
@@ -397,8 +405,8 @@ where
let statement_str = format!("{statement:?}");
let index_str = format!("{i}");
- let after = next_in_dataflow_order(&mut afters);
- let before = befores.as_mut().map(next_in_dataflow_order);
+ let after = next_in_dataflow_order(&mut diffs_after);
+ let before = diffs_before.as_mut().map(next_in_dataflow_order);
self.write_row(w, &index_str, &statement_str, |_this, w, fmt| {
if let Some(before) = before {
@@ -409,11 +417,11 @@ where
})?;
}
- let after = next_in_dataflow_order(&mut afters);
- let before = befores.as_mut().map(next_in_dataflow_order);
+ let after = next_in_dataflow_order(&mut diffs_after);
+ let before = diffs_before.as_mut().map(next_in_dataflow_order);
- assert!(afters.is_empty());
- assert!(befores.as_ref().map_or(true, ExactSizeIterator::is_empty));
+ assert!(diffs_after.is_empty());
+ assert!(diffs_before.as_ref().map_or(true, ExactSizeIterator::is_empty));
let terminator = body[block].terminator();
let mut terminator_str = String::new();
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 17102454a..60679b17d 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -39,7 +39,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
args: vec![],
destination: dummy_place.clone(),
target: Some(mir::START_BLOCK),
- cleanup: None,
+ unwind: mir::UnwindAction::Continue,
from_hir_call: false,
fn_span: DUMMY_SP,
},
@@ -53,7 +53,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
args: vec![],
destination: dummy_place.clone(),
target: Some(mir::START_BLOCK),
- cleanup: None,
+ unwind: mir::UnwindAction::Continue,
from_hir_call: false,
fn_span: DUMMY_SP,
},
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 6f4e7fd46..92d30f254 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -111,8 +111,7 @@ where
self.super_terminator(terminator, location);
match terminator.kind {
- mir::TerminatorKind::Drop { place: dropped_place, .. }
- | mir::TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
+ mir::TerminatorKind::Drop { place: dropped_place, .. } => {
// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut
// self` as a parameter. In the general case, a drop impl could launder that
// reference into the surrounding environment through a raw pointer, thus creating
@@ -126,7 +125,7 @@ where
}
}
- TerminatorKind::Abort
+ TerminatorKind::Terminate
| TerminatorKind::Assert { .. }
| TerminatorKind::Call { .. }
| TerminatorKind::FalseEdge { .. }
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index 633a5674f..1309ea525 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -198,8 +198,7 @@ impl DefUse {
| NonMutatingUseContext::Inspect
| NonMutatingUseContext::Move
| NonMutatingUseContext::ShallowBorrow
- | NonMutatingUseContext::SharedBorrow
- | NonMutatingUseContext::UniqueBorrow,
+ | NonMutatingUseContext::SharedBorrow,
) => Some(DefUse::Use),
PlaceContext::MutatingUse(MutatingUseContext::Projection)
@@ -263,6 +262,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
| StatementKind::StorageDead(_)
| StatementKind::Retag(..)
| StatementKind::AscribeUserType(..)
+ | StatementKind::PlaceMention(..)
| StatementKind::Coverage(..)
| StatementKind::Intrinsic(..)
| StatementKind::ConstEvalCounter
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index fcf0ce9d8..4a5d9d520 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -139,6 +139,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
// Nothing to do for these. Match exhaustively so this fails to compile when new
// variants are added.
StatementKind::AscribeUserType(..)
+ | StatementKind::PlaceMention(..)
| StatementKind::Coverage(..)
| StatementKind::FakeRead(..)
| StatementKind::ConstEvalCounter
@@ -199,10 +200,9 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
// Nothing to do for these. Match exhaustively so this fails to compile when new
// variants are added.
- TerminatorKind::Abort
+ TerminatorKind::Terminate
| TerminatorKind::Assert { .. }
| TerminatorKind::Drop { .. }
- | TerminatorKind::DropAndReplace { .. }
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::GeneratorDrop
@@ -237,10 +237,9 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
// Nothing to do for these. Match exhaustively so this fails to compile when new
// variants are added.
TerminatorKind::Yield { .. }
- | TerminatorKind::Abort
+ | TerminatorKind::Terminate
| TerminatorKind::Assert { .. }
| TerminatorKind::Drop { .. }
- | TerminatorKind::DropAndReplace { .. }
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::GeneratorDrop
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index b1e03faff..43caa2ea9 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -3,7 +3,6 @@
#![feature(exact_size_is_empty)]
#![feature(let_chains)]
#![feature(min_specialization)]
-#![feature(once_cell)]
#![feature(stmt_expr_attributes)]
#![feature(trusted_step)]
#![recursion_limit = "256"]
@@ -46,7 +45,7 @@ pub mod storage;
pub mod un_derefer;
pub mod value_analysis;
-fluent_messages! { "../locales/en-US.ftl" }
+fluent_messages! { "../messages.ftl" }
pub(crate) mod indexes {
pub(crate) use super::move_paths::MovePathIndex;
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 4a163028f..64ed7a29f 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -329,6 +329,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
}
StatementKind::Retag { .. }
| StatementKind::AscribeUserType(..)
+ | StatementKind::PlaceMention(..)
| StatementKind::Coverage(..)
| StatementKind::Intrinsic(..)
| StatementKind::ConstEvalCounter
@@ -374,7 +375,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
// need recording.
| TerminatorKind::Return
| TerminatorKind::Resume
- | TerminatorKind::Abort
+ | TerminatorKind::Terminate
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
| TerminatorKind::Drop { .. } => {}
@@ -392,17 +393,12 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
self.create_move_path(place);
self.gather_init(place.as_ref(), InitKind::Deep);
}
- TerminatorKind::DropAndReplace { place, ref value, .. } => {
- self.create_move_path(place);
- self.gather_operand(value);
- self.gather_init(place.as_ref(), InitKind::Deep);
- }
TerminatorKind::Call {
ref func,
ref args,
destination,
target,
- cleanup: _,
+ unwind: _,
from_hir_call: _,
fn_span: _,
} => {
@@ -421,7 +417,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
options: _,
line_spans: _,
destination: _,
- cleanup: _,
+ unwind: _,
} => {
for op in operands {
match *op {
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index 5f22a418d..257a42cdd 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -1,6 +1,6 @@
use crate::move_paths::builder::MoveDat;
use rustc_data_structures::fx::FxHashMap;
-use rustc_index::vec::IndexVec;
+use rustc_index::vec::{IndexSlice, IndexVec};
use rustc_middle::mir::*;
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
use rustc_span::Span;
@@ -64,7 +64,7 @@ impl<'tcx> MovePath<'tcx> {
/// Returns an iterator over the parents of `self`.
pub fn parents<'a>(
&self,
- move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>,
+ move_paths: &'a IndexSlice<MovePathIndex, MovePath<'tcx>>,
) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> {
let first = self.parent.map(|mpi| (mpi, &move_paths[mpi]));
MovePathLinearIter {
@@ -78,7 +78,7 @@ impl<'tcx> MovePath<'tcx> {
/// Returns an iterator over the immediate children of `self`.
pub fn children<'a>(
&self,
- move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>,
+ move_paths: &'a IndexSlice<MovePathIndex, MovePath<'tcx>>,
) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> {
let first = self.first_child.map(|mpi| (mpi, &move_paths[mpi]));
MovePathLinearIter {
@@ -95,7 +95,7 @@ impl<'tcx> MovePath<'tcx> {
/// `f` will **not** be called on `self`.
pub fn find_descendant(
&self,
- move_paths: &IndexVec<MovePathIndex, MovePath<'_>>,
+ move_paths: &IndexSlice<MovePathIndex, MovePath<'_>>,
f: impl Fn(MovePathIndex) -> bool,
) -> Option<MovePathIndex> {
let mut todo = if let Some(child) = self.first_child {
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 401db890a..98bebc9b1 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -36,11 +36,11 @@ use std::fmt::{Debug, Formatter};
use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::BitSet;
-use rustc_index::vec::IndexVec;
+use rustc_index::vec::{IndexSlice, IndexVec};
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_target::abi::VariantIdx;
+use rustc_target::abi::{FieldIdx, VariantIdx};
use crate::lattice::{HasBottom, HasTop};
use crate::{
@@ -86,6 +86,7 @@ pub trait ValueAnalysis<'tcx> {
StatementKind::ConstEvalCounter
| StatementKind::Nop
| StatementKind::FakeRead(..)
+ | StatementKind::PlaceMention(..)
| StatementKind::Coverage(..)
| StatementKind::AscribeUserType(..) => (),
}
@@ -230,14 +231,14 @@ pub trait ValueAnalysis<'tcx> {
TerminatorKind::Drop { place, .. } => {
state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
}
- TerminatorKind::DropAndReplace { .. } | TerminatorKind::Yield { .. } => {
+ TerminatorKind::Yield { .. } => {
// They would have an effect, but are not allowed in this phase.
bug!("encountered disallowed terminator");
}
TerminatorKind::Goto { .. }
| TerminatorKind::SwitchInt { .. }
| TerminatorKind::Resume
- | TerminatorKind::Abort
+ | TerminatorKind::Terminate
| TerminatorKind::Return
| TerminatorKind::Unreachable
| TerminatorKind::Assert { .. }
@@ -690,7 +691,7 @@ impl Map {
}
// Recurse with all fields of this place.
- iter_fields(ty, tcx, |variant, field, ty| {
+ iter_fields(ty, tcx, ty::ParamEnv::reveal_all(), |variant, field, ty| {
if let Some(variant) = variant {
projection.push(PlaceElem::Downcast(None, variant));
let _ = self.make_place(local, projection);
@@ -918,7 +919,7 @@ impl<V: HasTop> ValueOrPlace<V> {
/// Although only field projections are currently allowed, this could change in the future.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum TrackElem {
- Field(Field),
+ Field(FieldIdx),
Variant(VariantIdx),
Discriminant,
}
@@ -939,7 +940,8 @@ impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
pub fn iter_fields<'tcx>(
ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>,
- mut f: impl FnMut(Option<VariantIdx>, Field, Ty<'tcx>),
+ param_env: ty::ParamEnv<'tcx>,
+ mut f: impl FnMut(Option<VariantIdx>, FieldIdx, Ty<'tcx>),
) {
match ty.kind() {
ty::Tuple(list) => {
@@ -956,14 +958,14 @@ pub fn iter_fields<'tcx>(
for (f_index, f_def) in v_def.fields.iter().enumerate() {
let field_ty = f_def.ty(tcx, substs);
let field_ty = tcx
- .try_normalize_erasing_regions(ty::ParamEnv::reveal_all(), field_ty)
- .unwrap_or(field_ty);
+ .try_normalize_erasing_regions(param_env, field_ty)
+ .unwrap_or_else(|_| tcx.erase_regions(field_ty));
f(variant, f_index.into(), field_ty);
}
}
}
ty::Closure(_, substs) => {
- iter_fields(substs.as_closure().tupled_upvars_ty(), tcx, f);
+ iter_fields(substs.as_closure().tupled_upvars_ty(), tcx, param_env, f);
}
_ => (),
}
@@ -1026,8 +1028,8 @@ where
fn debug_with_context_rec<V: Debug + Eq>(
place: PlaceIndex,
place_str: &str,
- new: &IndexVec<ValueIndex, V>,
- old: Option<&IndexVec<ValueIndex, V>>,
+ new: &IndexSlice<ValueIndex, V>,
+ old: Option<&IndexSlice<ValueIndex, V>>,
map: &Map,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
@@ -1067,8 +1069,8 @@ fn debug_with_context_rec<V: Debug + Eq>(
}
fn debug_with_context<V: Debug + Eq>(
- new: &IndexVec<ValueIndex, V>,
- old: Option<&IndexVec<ValueIndex, V>>,
+ new: &IndexSlice<ValueIndex, V>,
+ old: Option<&IndexSlice<ValueIndex, V>>,
map: &Map,
f: &mut Formatter<'_>,
) -> std::fmt::Result {