summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/mir
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /compiler/rustc_middle/src/mir
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/mir')
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs43
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs7
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs1
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs50
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs9
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs12
-rw-r--r--compiler/rustc_middle/src/mir/query.rs7
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs19
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs37
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs9
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs47
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs2
-rw-r--r--compiler/rustc_middle/src/mir/type_visitable.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs10
15 files changed, 116 insertions, 140 deletions
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index efa946452..e7bb3ab0b 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -3,7 +3,6 @@
use rustc_macros::HashStable;
use rustc_span::Symbol;
-use std::cmp::Ord;
use std::fmt::{self, Debug, Formatter};
rustc_index::newtype_index! {
@@ -11,10 +10,10 @@ rustc_index::newtype_index! {
/// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32()
/// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a
/// constant value of `0`.
+ #[derive(HashStable)]
+ #[max = 0xFFFF_FFFF]
+ #[debug_format = "ExpressionOperandId({})"]
pub struct ExpressionOperandId {
- derive [HashStable]
- DEBUG_FORMAT = "ExpressionOperandId({})",
- MAX = 0xFFFF_FFFF,
}
}
@@ -33,11 +32,10 @@ impl ExpressionOperandId {
}
rustc_index::newtype_index! {
- pub struct CounterValueReference {
- derive [HashStable]
- DEBUG_FORMAT = "CounterValueReference({})",
- MAX = 0xFFFF_FFFF,
- }
+ #[derive(HashStable)]
+ #[max = 0xFFFF_FFFF]
+ #[debug_format = "CounterValueReference({})"]
+ pub struct CounterValueReference {}
}
impl CounterValueReference {
@@ -57,33 +55,30 @@ rustc_index::newtype_index! {
/// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32()
///
/// Values descend from u32::MAX.
- pub struct InjectedExpressionId {
- derive [HashStable]
- DEBUG_FORMAT = "InjectedExpressionId({})",
- MAX = 0xFFFF_FFFF,
- }
+ #[derive(HashStable)]
+ #[max = 0xFFFF_FFFF]
+ #[debug_format = "InjectedExpressionId({})"]
+ pub struct InjectedExpressionId {}
}
rustc_index::newtype_index! {
/// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32()
///
/// Values ascend from 0.
- pub struct InjectedExpressionIndex {
- derive [HashStable]
- DEBUG_FORMAT = "InjectedExpressionIndex({})",
- MAX = 0xFFFF_FFFF,
- }
+ #[derive(HashStable)]
+ #[max = 0xFFFF_FFFF]
+ #[debug_format = "InjectedExpressionIndex({})"]
+ pub struct InjectedExpressionIndex {}
}
rustc_index::newtype_index! {
/// MappedExpressionIndex values ascend from zero, and are recalculated indexes based on their
/// array position in the LLVM coverage map "Expressions" array, which is assembled during the
/// "mapgen" process. They cannot be computed algorithmically, from the other `newtype_index`s.
- pub struct MappedExpressionIndex {
- derive [HashStable]
- DEBUG_FORMAT = "MappedExpressionIndex({})",
- MAX = 0xFFFF_FFFF,
- }
+ #[derive(HashStable)]
+ #[max = 0xFFFF_FFFF]
+ #[debug_format = "MappedExpressionIndex({})"]
+ pub struct MappedExpressionIndex {}
}
impl From<CounterValueReference> for ExpressionOperandId {
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index d79cd8b7a..5f425a287 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -95,7 +95,6 @@ mod pointer;
mod queries;
mod value;
-use std::convert::TryFrom;
use std::fmt;
use std::io;
use std::io::{Read, Write};
@@ -510,7 +509,7 @@ impl<'tcx> TyCtxt<'tcx> {
self.reserve_and_set_dedup(GlobalAlloc::Static(static_id))
}
- /// Generates an `AllocId` for a function. Depending on the function type,
+ /// Generates an `AllocId` for a function. Depending on the function type,
/// this might get deduplicated or assigned a new ID each time.
pub fn create_fn_alloc(self, instance: Instance<'tcx>) -> AllocId {
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
@@ -519,7 +518,7 @@ impl<'tcx> TyCtxt<'tcx> {
// We thus generate a new `AllocId` for every mention of a function. This means that
// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
// However, formatting code relies on function identity (see #58320), so we only do
- // this for generic functions. Lifetime parameters are ignored.
+ // this for generic functions. Lifetime parameters are ignored.
let is_generic = instance
.substs
.into_iter()
@@ -536,7 +535,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- /// Generates an `AllocId` for a (symbolic, not-reified) vtable. Will get deduplicated.
+ /// Generates an `AllocId` for a (symbolic, not-reified) vtable. Will get deduplicated.
pub fn create_vtable_alloc(
self,
ty: Ty<'tcx>,
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index 9c270ba1e..b08309910 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -3,7 +3,6 @@ use super::{AllocId, InterpResult};
use rustc_macros::HashStable;
use rustc_target::abi::{HasDataLayout, Size};
-use std::convert::{TryFrom, TryInto};
use std::fmt;
////////////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index e6636e50e..88fb14eb3 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -1,4 +1,3 @@
-use std::convert::{TryFrom, TryInto};
use std::fmt;
use either::{Either, Left, Right};
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index a513444e1..e52b243ec 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -36,7 +36,6 @@ use rustc_span::{Span, DUMMY_SP};
use either::Either;
use std::borrow::Cow;
-use std::convert::TryInto;
use std::fmt::{self, Debug, Display, Formatter, Write};
use std::ops::{ControlFlow, Index, IndexMut};
use std::{iter, mem};
@@ -534,6 +533,11 @@ impl<'tcx> Body<'tcx> {
};
injection_phase > self.phase
}
+
+ #[inline]
+ pub fn is_custom_mir(&self) -> bool {
+ self.injection_phase.is_some()
+ }
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
@@ -650,10 +654,10 @@ impl SourceInfo {
// Variables and temps
rustc_index::newtype_index! {
+ #[derive(HashStable)]
+ #[debug_format = "_{}"]
pub struct Local {
- derive [HashStable]
- DEBUG_FORMAT = "_{}",
- const RETURN_PLACE = 0,
+ const RETURN_PLACE = 0;
}
}
@@ -1142,10 +1146,10 @@ rustc_index::newtype_index! {
/// https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis
/// [`CriticalCallEdges`]: ../../rustc_const_eval/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges
/// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/
+ #[derive(HashStable)]
+ #[debug_format = "bb{}"]
pub struct BasicBlock {
- derive [HashStable]
- DEBUG_FORMAT = "bb{}",
- const START_BLOCK = 0,
+ const START_BLOCK = 0;
}
}
@@ -1526,10 +1530,9 @@ rustc_index::newtype_index! {
/// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype
/// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
/// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
- pub struct Field {
- derive [HashStable]
- DEBUG_FORMAT = "field[{}]"
- }
+ #[derive(HashStable)]
+ #[debug_format = "field[{}]"]
+ pub struct Field {}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -1753,10 +1756,10 @@ impl Debug for Place<'_> {
// Scopes
rustc_index::newtype_index! {
+ #[derive(HashStable)]
+ #[debug_format = "scope[{}]"]
pub struct SourceScope {
- derive [HashStable]
- DEBUG_FORMAT = "scope[{}]",
- const OUTERMOST_SOURCE_SCOPE = 0,
+ const OUTERMOST_SOURCE_SCOPE = 0;
}
}
@@ -1764,9 +1767,9 @@ impl SourceScope {
/// Finds the original HirId this MIR item came from.
/// This is necessary after MIR optimizations, as otherwise we get a HirId
/// from the function that was inlined instead of the function call site.
- pub fn lint_root<'tcx>(
+ pub fn lint_root(
self,
- source_scopes: &IndexVec<SourceScope, SourceScopeData<'tcx>>,
+ source_scopes: &IndexVec<SourceScope, SourceScopeData<'_>>,
) -> Option<HirId> {
let mut data = &source_scopes[self];
// FIXME(oli-obk): we should be able to just walk the `inlined_parent_scope`, but it
@@ -1848,7 +1851,7 @@ impl<'tcx> Operand<'tcx> {
pub fn function_handle(
tcx: TyCtxt<'tcx>,
def_id: DefId,
- substs: SubstsRef<'tcx>,
+ substs: impl IntoIterator<Item = GenericArg<'tcx>>,
span: Span,
) -> Self {
let ty = tcx.mk_fn_def(def_id, substs);
@@ -2480,7 +2483,7 @@ impl<'tcx> ConstantKind<'tcx> {
// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
// does not provide the parents generics to anonymous constants. We still allow generic const
- // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
+ // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
// ever try to substitute the generic parameters in their bodies.
//
// While this doesn't happen as these constants are always used as `ty::ConstKind::Param`, it does
@@ -2503,7 +2506,7 @@ impl<'tcx> ConstantKind<'tcx> {
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
- let parent_substs = if let Some(parent_hir_id) = tcx.hir().find_parent_node(hir_id) {
+ let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) {
if let Some(parent_did) = tcx.hir().opt_local_def_id(parent_hir_id) {
InternalSubsts::identity_for_item(tcx, parent_did.to_def_id())
} else {
@@ -2751,10 +2754,9 @@ impl<'tcx> TypeVisitable<'tcx> for UserTypeProjection {
}
rustc_index::newtype_index! {
- pub struct Promoted {
- derive [HashStable]
- DEBUG_FORMAT = "promoted[{}]"
- }
+ #[derive(HashStable)]
+ #[debug_format = "promoted[{}]"]
+ pub struct Promoted {}
}
impl<'tcx> Debug for Constant<'tcx> {
@@ -2892,7 +2894,7 @@ fn pretty_print_const_value<'tcx>(
if let Some(contents) = tcx.try_destructure_mir_constant(
ty::ParamEnv::reveal_all().and(ConstantKind::Val(ct, ty)),
) {
- let fields = contents.fields.iter().copied().collect::<Vec<_>>();
+ let fields = contents.fields.to_vec();
match *ty.kind() {
ty::Array(..) => {
fmt.write_str("[")?;
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 15a24aa4a..1e8d5f7ea 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -200,6 +200,15 @@ impl<'tcx> MonoItem<'tcx> {
MonoItem::GlobalAsm(..) => LOCAL_CRATE,
}
}
+
+ /// Returns the item's `DefId`
+ pub fn def_id(&self) -> DefId {
+ match *self {
+ MonoItem::Fn(Instance { def, .. }) => def.def_id(),
+ MonoItem::Static(def_id) => def_id,
+ MonoItem::GlobalAsm(item_id) => item_id.owner_id.to_def_id(),
+ }
+ }
}
impl<'tcx> fmt::Display for MonoItem<'tcx> {
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 2a4ff4b88..40289af25 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -88,7 +88,7 @@ pub fn dump_mir<'tcx, F>(
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data);
}
-pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool {
+pub fn dump_enabled(tcx: TyCtxt<'_>, pass_name: &str, def_id: DefId) -> bool {
let Some(ref filters) = tcx.sess.opts.unstable_opts.dump_mir else {
return false;
};
@@ -421,7 +421,7 @@ impl<'tcx> ExtraComments<'tcx> {
}
}
-fn use_verbose<'tcx>(ty: Ty<'tcx>, fn_def: bool) -> bool {
+fn use_verbose(ty: Ty<'_>, fn_def: bool) -> bool {
match *ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) => false,
// Unit type
@@ -448,15 +448,15 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
// FIXME: this is a poor version of `pretty_print_const_value`.
let fmt_val = |val: &ConstValue<'tcx>| match val {
- ConstValue::ZeroSized => format!("<ZST>"),
+ ConstValue::ZeroSized => "<ZST>".to_string(),
ConstValue::Scalar(s) => format!("Scalar({:?})", s),
- ConstValue::Slice { .. } => format!("Slice(..)"),
- ConstValue::ByRef { .. } => format!("ByRef(..)"),
+ ConstValue::Slice { .. } => "Slice(..)".to_string(),
+ ConstValue::ByRef { .. } => "ByRef(..)".to_string(),
};
let fmt_valtree = |valtree: &ty::ValTree<'tcx>| match valtree {
ty::ValTree::Leaf(leaf) => format!("ValTree::Leaf({:?})", leaf),
- ty::ValTree::Branch(_) => format!("ValTree::Branch(..)"),
+ ty::ValTree::Branch(_) => "ValTree::Branch(..)".to_string(),
};
let val = match literal {
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index efd7357af..a8a453222 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -130,10 +130,9 @@ pub struct UnsafetyCheckResult {
}
rustc_index::newtype_index! {
- pub struct GeneratorSavedLocal {
- derive [HashStable]
- DEBUG_FORMAT = "_{}",
- }
+ #[derive(HashStable)]
+ #[debug_format = "_{}"]
+ pub struct GeneratorSavedLocal {}
}
/// The layout of generator state.
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index 4e06d9101..887ee5715 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -230,7 +230,7 @@ where
}
/// Format a string showing the start line and column, and end line and column within a file.
-pub fn source_range_no_file<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
+pub fn source_range_no_file(tcx: TyCtxt<'_>, span: Span) -> String {
let source_map = tcx.sess.source_map();
let start = source_map.lookup_char_pos(span.lo());
let end = source_map.lookup_char_pos(span.hi());
@@ -322,7 +322,7 @@ fn block_span_viewable<'tcx>(
Some(SpanViewable { bb, span, id, tooltip })
}
-fn compute_block_span<'tcx>(data: &BasicBlockData<'tcx>, body_span: Span) -> Span {
+fn compute_block_span(data: &BasicBlockData<'_>, body_span: Span) -> Span {
let mut span = data.terminator().source_info.span;
for statement_span in data.statements.iter().map(|statement| statement.source_info.span) {
// Only combine Spans from the root context, and within the function's body_span.
@@ -522,12 +522,7 @@ where
}
#[inline(always)]
-fn write_coverage_gap<'tcx, W>(
- tcx: TyCtxt<'tcx>,
- lo: BytePos,
- hi: BytePos,
- w: &mut W,
-) -> io::Result<()>
+fn write_coverage_gap<W>(tcx: TyCtxt<'_>, lo: BytePos, hi: BytePos, w: &mut W) -> io::Result<()>
where
W: Write,
{
@@ -582,8 +577,8 @@ where
Ok(())
}
-fn make_html_snippet<'tcx>(
- tcx: TyCtxt<'tcx>,
+fn make_html_snippet(
+ tcx: TyCtxt<'_>,
span: Span,
some_viewable: Option<&SpanViewable>,
) -> Option<String> {
@@ -664,7 +659,7 @@ fn trim_span_hi(span: Span, to_pos: BytePos) -> Span {
if to_pos >= span.hi() { span } else { span.with_hi(cmp::max(span.lo(), to_pos)) }
}
-fn fn_span<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Span {
+fn fn_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span {
let fn_decl_span = tcx.def_span(def_id);
if let Some(body_span) = hir_body(tcx, def_id).map(|hir_body| hir_body.value.span) {
if fn_decl_span.eq_ctxt(body_span) { fn_decl_span.to(body_span) } else { body_span }
@@ -673,7 +668,7 @@ fn fn_span<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Span {
}
}
-fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<&'tcx rustc_hir::Body<'tcx>> {
+fn hir_body(tcx: TyCtxt<'_>, def_id: DefId) -> Option<&rustc_hir::Body<'_>> {
let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local");
hir::map::associated_body(hir_node).map(|fn_body_id| tcx.hir().body(fn_body_id))
}
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 5ba053820..52c2b10cb 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -320,8 +320,10 @@ pub enum StatementKind<'tcx> {
/// <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/> for
/// more details.
///
- /// For code that is not specific to stacked borrows, you should consider retags to read
- /// and modify the place in an opaque way.
+ /// For code that is not specific to stacked borrows, you should consider retags to read and
+ /// modify the place in an opaque way.
+ ///
+ /// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted.
Retag(RetagKind, Box<Place<'tcx>>),
/// Encodes a user's type ascription. These need to be preserved
@@ -510,6 +512,16 @@ pub struct CopyNonOverlapping<'tcx> {
/// must also be `cleanup`. This is a part of the type system and checked statically, so it is
/// still an error to have such an edge in the CFG even if it's known that it won't be taken at
/// runtime.
+/// 4. The control flow between cleanup blocks must look like an upside down tree. Roughly
+/// speaking, this means that control flow that looks like a V is allowed, while control flow
+/// that looks like a W is not. This is necessary to ensure that landing pad information can be
+/// correctly codegened on MSVC. More precisely:
+///
+/// Begin with the standard control flow graph `G`. Modify `G` as follows: for any two cleanup
+/// vertices `u` and `v` such that `u` dominates `v`, contract `u` and `v` into a single vertex,
+/// deleting self edges and duplicate edges in the process. Now remove all vertices from `G`
+/// that are not cleanup vertices or are not reachable. The resulting graph must be an inverted
+/// tree, that is each vertex may have at most one successor and there may be no cycles.
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum TerminatorKind<'tcx> {
/// Block has one successor; we continue execution there.
@@ -526,12 +538,6 @@ pub enum TerminatorKind<'tcx> {
SwitchInt {
/// The discriminant value being tested.
discr: Operand<'tcx>,
-
- /// The type of value being tested.
- /// This is always the same as the type of `discr`.
- /// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing.
- switch_ty: Ty<'tcx>,
-
targets: SwitchTargets,
},
@@ -568,14 +574,13 @@ pub enum TerminatorKind<'tcx> {
Unreachable,
/// The behavior of this statement differs significantly before and after drop elaboration.
- /// After drop elaboration, `Drop` executes the drop glue for the specified place, after which
- /// it continues execution/unwinds at the given basic blocks. It is possible that executing drop
- /// glue is special - this would be part of Rust's memory model. (**FIXME**: due we have an
- /// issue tracking if drop glue has any interesting semantics in addition to those of a function
- /// call?)
- ///
- /// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically, the
- /// `Drop` will be executed if...
+ ///
+ /// After drop elaboration: `Drop` terminators are a complete nop for types that have no drop
+ /// glue. For other types, `Drop` terminators behave exactly like a call to
+ /// `core::mem::drop_in_place` with a pointer to the given place.
+ ///
+ /// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically,
+ /// the `Drop` will be executed if...
///
/// **Needs clarification**: End of that sentence. This in effect should document the exact
/// behavior of drop elaboration. The following sounds vaguely right, but I'm not quite sure:
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index fa3adafd4..599f0b9d3 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -32,8 +32,9 @@ impl<'tcx> PlaceTy<'tcx> {
/// not carry a `Ty` for `T`.)
///
/// Note that the resulting type has not been normalized.
+ #[instrument(level = "debug", skip(tcx), ret)]
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> {
- let answer = match self.ty.kind() {
+ match self.ty.kind() {
ty::Adt(adt_def, substs) => {
let variant_def = match self.variant_index {
None => adt_def.non_enum_variant(),
@@ -47,9 +48,7 @@ impl<'tcx> PlaceTy<'tcx> {
}
ty::Tuple(tys) => tys[f.index()],
_ => bug!("extracting field of non-tuple non-adt: {:?}", self),
- };
- debug!("field_ty self: {:?} f: {:?} yields: {:?}", self, f, answer);
- answer
+ }
}
/// Convenience wrapper around `projection_ty_core` for
@@ -234,7 +233,7 @@ impl<'tcx> Operand<'tcx> {
{
match self {
&Operand::Copy(ref l) | &Operand::Move(ref l) => l.ty(local_decls, tcx).ty,
- &Operand::Constant(ref c) => c.literal.ty(),
+ Operand::Constant(c) => c.literal.ty(),
}
}
}
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 4ea333cff..6e905224c 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -1,7 +1,4 @@
-use crate::mir;
-use crate::mir::interpret::Scalar;
-use crate::ty::{self, Ty, TyCtxt};
-use smallvec::{smallvec, SmallVec};
+use smallvec::SmallVec;
use super::{BasicBlock, InlineAsmOperand, Operand, SourceInfo, TerminatorKind};
use rustc_ast::InlineAsmTemplatePiece;
@@ -77,7 +74,7 @@ impl SwitchTargets {
}
/// Finds the `BasicBlock` to which this `SwitchInt` will branch given the
- /// specific value. This cannot fail, as it'll return the `otherwise`
+ /// specific value. This cannot fail, as it'll return the `otherwise`
/// branch if there's not a specific match for the value.
pub fn target_for_value(&self, value: u128) -> BasicBlock {
self.iter().find_map(|(v, t)| (v == value).then_some(t)).unwrap_or_else(|| self.otherwise())
@@ -131,17 +128,8 @@ impl<'tcx> Terminator<'tcx> {
}
impl<'tcx> TerminatorKind<'tcx> {
- pub fn if_(
- tcx: TyCtxt<'tcx>,
- cond: Operand<'tcx>,
- t: BasicBlock,
- f: BasicBlock,
- ) -> TerminatorKind<'tcx> {
- TerminatorKind::SwitchInt {
- discr: cond,
- switch_ty: tcx.types.bool,
- targets: SwitchTargets::static_if(0, f, t),
- }
+ pub fn if_(cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> {
+ TerminatorKind::SwitchInt { discr: cond, targets: SwitchTargets::static_if(0, f, t) }
}
pub fn successors(&self) -> Successors<'_> {
@@ -264,11 +252,9 @@ impl<'tcx> TerminatorKind<'tcx> {
}
}
- pub fn as_switch(&self) -> Option<(&Operand<'tcx>, Ty<'tcx>, &SwitchTargets)> {
+ pub fn as_switch(&self) -> Option<(&Operand<'tcx>, &SwitchTargets)> {
match self {
- TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
- Some((discr, *switch_ty, targets))
- }
+ TerminatorKind::SwitchInt { discr, targets } => Some((discr, targets)),
_ => None,
}
}
@@ -403,21 +389,12 @@ impl<'tcx> TerminatorKind<'tcx> {
match *self {
Return | Resume | Abort | Unreachable | GeneratorDrop => vec![],
Goto { .. } => vec!["".into()],
- SwitchInt { ref targets, switch_ty, .. } => ty::tls::with(|tcx| {
- let param_env = ty::ParamEnv::empty();
- let switch_ty = tcx.lift(switch_ty).unwrap();
- let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
- targets
- .values
- .iter()
- .map(|&u| {
- mir::ConstantKind::from_scalar(tcx, Scalar::from_uint(u, size), switch_ty)
- .to_string()
- .into()
- })
- .chain(iter::once("otherwise".into()))
- .collect()
- }),
+ SwitchInt { ref targets, .. } => targets
+ .values
+ .iter()
+ .map(|&u| Cow::Owned(u.to_string()))
+ .chain(iter::once("otherwise".into()))
+ .collect(),
Call { target: Some(_), cleanup: Some(_), .. } => {
vec!["return".into(), "unwind".into()]
}
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 55b2c5927..0b461d1ce 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -302,7 +302,7 @@ pub fn reachable<'a, 'tcx>(
}
/// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`.
-pub fn reachable_as_bitset<'tcx>(body: &Body<'tcx>) -> BitSet<BasicBlock> {
+pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet<BasicBlock> {
let mut iter = preorder(body);
(&mut iter).for_each(drop);
iter.visited
diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs
index e7cd497b2..d44c6809b 100644
--- a/compiler/rustc_middle/src/mir/type_visitable.rs
+++ b/compiler/rustc_middle/src/mir/type_visitable.rs
@@ -4,6 +4,6 @@ use super::*;
impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
- ControlFlow::CONTINUE
+ ControlFlow::Continue(())
}
}
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index b21f50ae5..1a264d2d5 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -3,15 +3,15 @@
//! ## Overview
//!
//! There are two visitors, one for immutable and one for mutable references,
-//! but both are generated by the following macro. The code is written according
-//! to the following conventions:
+//! but both are generated by the `make_mir_visitor` macro.
+//! The code is written according to the following conventions:
//!
//! - introduce a `visit_foo` and a `super_foo` method for every MIR type
//! - `visit_foo`, by default, calls `super_foo`
//! - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
//!
-//! This allows you as a user to override `visit_foo` for types are
-//! interested in, and invoke (within that method) call
+//! This allows you to override `visit_foo` for types you are
+//! interested in, and invoke (within that method call)
//! `self.super_foo` to get the default behavior. Just as in an OO
//! language, you should never call `super` methods ordinarily except
//! in that circumstance.
@@ -477,11 +477,9 @@ macro_rules! make_mir_visitor {
TerminatorKind::SwitchInt {
discr,
- switch_ty,
targets: _
} => {
self.visit_operand(discr, location);
- self.visit_ty($(& $mutability)? *switch_ty, TyContext::Location(location));
}
TerminatorKind::Drop {