summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/mir
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /compiler/rustc_middle/src/mir
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+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/consts.rs122
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs12
-rw-r--r--compiler/rustc_middle/src/mir/generic_graph.rs2
-rw-r--r--compiler/rustc_middle/src/mir/graphviz.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs18
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs21
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs10
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs99
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs10
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs28
-rw-r--r--compiler/rustc_middle/src/mir/patch.rs3
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs15
-rw-r--r--compiler/rustc_middle/src/mir/query.rs82
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs16
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs4
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs8
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs12
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs15
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs4
22 files changed, 222 insertions, 272 deletions
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index a9d09709e..2c38f998c 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -1,17 +1,15 @@
use std::fmt::{self, Debug, Display, Formatter};
-use rustc_hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self as hir};
+use rustc_hir::def_id::DefId;
use rustc_session::RemapFileNameExt;
use rustc_span::Span;
use rustc_target::abi::{HasDataLayout, Size};
use crate::mir::interpret::{alloc_range, AllocId, ConstAllocation, ErrorHandled, Scalar};
use crate::mir::{pretty_print_const_value, Promoted};
+use crate::ty::GenericArgsRef;
use crate::ty::ScalarInt;
-use crate::ty::{self, print::pretty_print_const, List, Ty, TyCtxt};
-use crate::ty::{GenericArgs, GenericArgsRef};
+use crate::ty::{self, print::pretty_print_const, Ty, TyCtxt};
///////////////////////////////////////////////////////////////////////////
/// Evaluated Constants
@@ -76,7 +74,7 @@ static_assert_size!(ConstValue<'_>, 24);
impl<'tcx> ConstValue<'tcx> {
#[inline]
- pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> {
+ pub fn try_to_scalar(&self) -> Option<Scalar> {
match *self {
ConstValue::Indirect { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None,
ConstValue::Scalar(val) => Some(val),
@@ -162,8 +160,8 @@ impl<'tcx> ConstValue<'tcx> {
return Some(&[]);
}
// Non-empty slice, must have memory. We know this is a relative pointer.
- let (inner_alloc_id, offset) = ptr.into_parts();
- let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory();
+ let (inner_prov, offset) = ptr.into_parts();
+ let data = tcx.global_alloc(inner_prov?.alloc_id()).unwrap_memory();
(data, offset.bytes(), offset.bytes() + len)
}
};
@@ -220,6 +218,17 @@ pub enum Const<'tcx> {
}
impl<'tcx> Const<'tcx> {
+ pub fn identity_unevaluated(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::EarlyBinder<Const<'tcx>> {
+ ty::EarlyBinder::bind(Const::Unevaluated(
+ UnevaluatedConst {
+ def: def_id,
+ args: ty::GenericArgs::identity_for_item(tcx, def_id),
+ promoted: None,
+ },
+ tcx.type_of(def_id).skip_binder(),
+ ))
+ }
+
#[inline(always)]
pub fn ty(&self) -> Ty<'tcx> {
match self {
@@ -399,101 +408,6 @@ impl<'tcx> Const<'tcx> {
Self::Val(val, ty)
}
- /// Literals are converted to `Const::Val`, const generic parameters are eagerly
- /// converted to a constant, everything else becomes `Unevaluated`.
- #[instrument(skip(tcx), level = "debug", ret)]
- pub fn from_anon_const(
- tcx: TyCtxt<'tcx>,
- def: LocalDefId,
- param_env: ty::ParamEnv<'tcx>,
- ) -> Self {
- let body_id = match tcx.hir().get_by_def_id(def) {
- hir::Node::AnonConst(ac) => ac.body,
- _ => {
- span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants")
- }
- };
-
- let expr = &tcx.hir().body(body_id).value;
- debug!(?expr);
-
- // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
- // currently have to be wrapped in curly brackets, so it's necessary to special-case.
- let expr = match &expr.kind {
- hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
- block.expr.as_ref().unwrap()
- }
- _ => expr,
- };
- debug!("expr.kind: {:?}", expr.kind);
-
- let ty = tcx.type_of(def).instantiate_identity();
- debug!(?ty);
-
- // 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
- // 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
- // cause issues if we were to remove that special-case and try to evaluate the constant instead.
- use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
- match expr.kind {
- ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
- // Find the name and index of the const parameter by indexing the generics of
- // the parent item and construct a `ParamConst`.
- let item_def_id = tcx.parent(def_id);
- let generics = tcx.generics_of(item_def_id);
- let index = generics.param_def_id_to_index[&def_id];
- let name = tcx.item_name(def_id);
- let ty_const = ty::Const::new_param(tcx, ty::ParamConst::new(index, name), ty);
- debug!(?ty_const);
-
- return Self::Ty(ty_const);
- }
- _ => {}
- }
-
- let hir_id = tcx.hir().local_def_id_to_hir_id(def);
- let parent_args = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id)
- && let Some(parent_did) = parent_hir_id.as_owner()
- {
- GenericArgs::identity_for_item(tcx, parent_did)
- } else {
- List::empty()
- };
- debug!(?parent_args);
-
- let did = def.to_def_id();
- let child_args = GenericArgs::identity_for_item(tcx, did);
- let args = tcx.mk_args_from_iter(parent_args.into_iter().chain(child_args.into_iter()));
- debug!(?args);
-
- let span = tcx.def_span(def);
- let uneval = UnevaluatedConst::new(did, args);
- debug!(?span, ?param_env);
-
- match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
- Ok(val) => {
- debug!("evaluated const value");
- Self::Val(val, ty)
- }
- Err(_) => {
- debug!("error encountered during evaluation");
- // Error was handled in `const_eval_resolve`. Here we just create a
- // new unevaluated const and error hard later in codegen
- Self::Unevaluated(
- UnevaluatedConst {
- def: did,
- args: GenericArgs::identity_for_item(tcx, did),
- promoted: None,
- },
- ty,
- )
- }
- }
- }
-
pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
match c.kind() {
ty::ConstKind::Value(valtree) => {
@@ -592,7 +506,7 @@ impl<'tcx> TyCtxt<'tcx> {
let caller = self.sess.source_map().lookup_char_pos(topmost.lo());
self.const_caller_location(
rustc_span::symbol::Symbol::intern(
- &caller.file.name.for_codegen(&self.sess).to_string_lossy(),
+ &caller.file.name.for_codegen(self.sess).to_string_lossy(),
),
caller.line as u32,
caller.col_display as u32 + 1,
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 08d377a86..ec5edceb2 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -17,6 +17,8 @@ rustc_index::newtype_index! {
/// Note that LLVM handles counter IDs as `uint32_t`, so there is no need
/// to use a larger representation on the Rust side.
#[derive(HashStable)]
+ #[encodable]
+ #[orderable]
#[max = 0xFFFF_FFFF]
#[debug_format = "CounterId({})"]
pub struct CounterId {}
@@ -37,6 +39,8 @@ rustc_index::newtype_index! {
/// Note that LLVM handles expression IDs as `uint32_t`, so there is no need
/// to use a larger representation on the Rust side.
#[derive(HashStable)]
+ #[encodable]
+ #[orderable]
#[max = 0xFFFF_FFFF]
#[debug_format = "ExpressionId({})"]
pub struct ExpressionId {}
@@ -72,6 +76,13 @@ impl Debug for CovTerm {
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum CoverageKind {
+ /// Marks a span that might otherwise not be represented in MIR, so that
+ /// coverage instrumentation can associate it with its enclosing block/BCB.
+ ///
+ /// Only used by the `InstrumentCoverage` pass, and has no effect during
+ /// codegen.
+ SpanMarker,
+
/// Marks the point in MIR control flow represented by a coverage counter.
///
/// This is eventually lowered to `llvm.instrprof.increment` in LLVM IR.
@@ -95,6 +106,7 @@ impl Debug for CoverageKind {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
use CoverageKind::*;
match self {
+ SpanMarker => write!(fmt, "SpanMarker"),
CounterIncrement { id } => write!(fmt, "CounterIncrement({:?})", id.index()),
ExpressionUsed { id } => write!(fmt, "ExpressionUsed({:?})", id.index()),
}
diff --git a/compiler/rustc_middle/src/mir/generic_graph.rs b/compiler/rustc_middle/src/mir/generic_graph.rs
index d1753427e..51e26ab79 100644
--- a/compiler/rustc_middle/src/mir/generic_graph.rs
+++ b/compiler/rustc_middle/src/mir/generic_graph.rs
@@ -1,7 +1,5 @@
use gsgdt::{Edge, Graph, Node, NodeStyle};
-use rustc_hir::def_id::DefId;
use rustc_middle::mir::*;
-use rustc_middle::ty::TyCtxt;
/// Convert an MIR function into a gsgdt Graph
pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph {
diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs
index 5c7de8644..96bef40da 100644
--- a/compiler/rustc_middle/src/mir/graphviz.rs
+++ b/compiler/rustc_middle/src/mir/graphviz.rs
@@ -1,9 +1,6 @@
use gsgdt::GraphvizSettings;
use rustc_graphviz as dot;
-use rustc_hir::def_id::DefId;
use rustc_middle::mir::*;
-use rustc_middle::ty::{self, TyCtxt};
-use std::fmt::Debug;
use std::io::{self, Write};
use super::generic_graph::mir_fn_to_generic_graph;
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index aded3e495..2a9e0847f 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -18,9 +18,9 @@ use rustc_span::DUMMY_SP;
use rustc_target::abi::{Align, HasDataLayout, Size};
use super::{
- read_target_uint, write_target_uint, AllocId, BadBytesAccess, InterpError, InterpResult,
- Pointer, PointerArithmetic, Provenance, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch,
- UndefinedBehaviorInfo, UnsupportedOpInfo,
+ read_target_uint, write_target_uint, AllocId, BadBytesAccess, CtfeProvenance, InterpError,
+ InterpResult, Pointer, PointerArithmetic, Provenance, ResourceExhaustionInfo, Scalar,
+ ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo,
};
use crate::ty;
use init_mask::*;
@@ -63,7 +63,7 @@ impl AllocBytes for Box<[u8]> {
// hashed. (see the `Hash` impl below for more details), so the impl is not derived.
#[derive(Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
#[derive(HashStable)]
-pub struct Allocation<Prov: Provenance = AllocId, Extra = (), Bytes = Box<[u8]>> {
+pub struct Allocation<Prov: Provenance = CtfeProvenance, Extra = (), Bytes = Box<[u8]>> {
/// The actual bytes of the allocation.
/// Note that the bytes of a pointer represent the offset of the pointer.
bytes: Bytes,
@@ -315,7 +315,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
Self::uninit_inner(size, align, || {
ty::tls::with(|tcx| {
- tcx.sess.delay_span_bug(DUMMY_SP, "exhausted memory during interpretation")
+ tcx.sess.span_delayed_bug(DUMMY_SP, "exhausted memory during interpretation")
});
InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted).into()
})
@@ -336,14 +336,14 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
}
}
-impl<Bytes: AllocBytes> Allocation<AllocId, (), Bytes> {
- /// Adjust allocation from the ones in tcx to a custom Machine instance
- /// with a different Provenance and Extra type.
+impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
+ /// Adjust allocation from the ones in `tcx` to a custom Machine instance
+ /// with a different `Provenance` and `Extra` type.
pub fn adjust_from_tcx<Prov: Provenance, Extra, Err>(
self,
cx: &impl HasDataLayout,
extra: Extra,
- mut adjust_ptr: impl FnMut(Pointer<AllocId>) -> Result<Pointer<Prov>, Err>,
+ mut adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> Result<Pointer<Prov>, Err>,
) -> Result<Allocation<Prov, Extra, Bytes>, Err> {
let mut bytes = self.bytes;
// Adjust provenance of pointers stored in this allocation.
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
index d504af6b7..9459af490 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
@@ -6,14 +6,14 @@ use std::cmp;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_target::abi::{HasDataLayout, Size};
-use super::{alloc_range, AllocError, AllocId, AllocRange, AllocResult, Provenance};
+use super::{alloc_range, AllocError, AllocRange, AllocResult, CtfeProvenance, Provenance};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
/// Stores the provenance information of pointers stored in memory.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[derive(HashStable)]
-pub struct ProvenanceMap<Prov = AllocId> {
- /// Provenance in this map applies from the given offset for an entire pointer-size worth of
+pub struct ProvenanceMap<Prov = CtfeProvenance> {
+ /// `Provenance` in this map applies from the given offset for an entire pointer-size worth of
/// bytes. Two entries in this map are always at least a pointer size apart.
ptrs: SortedMap<Size, Prov>,
/// Provenance in this map only applies to the given single byte.
@@ -22,18 +22,19 @@ pub struct ProvenanceMap<Prov = AllocId> {
bytes: Option<Box<SortedMap<Size, Prov>>>,
}
+// These impls are generic over `Prov` since `CtfeProvenance` is only decodable/encodable
+// for some particular `D`/`S`.
impl<D: Decoder, Prov: Provenance + Decodable<D>> Decodable<D> for ProvenanceMap<Prov> {
fn decode(d: &mut D) -> Self {
- assert!(!Prov::OFFSET_IS_ADDR); // only `AllocId` is ever serialized
+ assert!(!Prov::OFFSET_IS_ADDR); // only `CtfeProvenance` is ever serialized
Self { ptrs: Decodable::decode(d), bytes: None }
}
}
-
impl<S: Encoder, Prov: Provenance + Encodable<S>> Encodable<S> for ProvenanceMap<Prov> {
fn encode(&self, s: &mut S) {
let Self { ptrs, bytes } = self;
- assert!(!Prov::OFFSET_IS_ADDR); // only `AllocId` is ever serialized
- debug_assert!(bytes.is_none());
+ assert!(!Prov::OFFSET_IS_ADDR); // only `CtfeProvenance` is ever serialized
+ debug_assert!(bytes.is_none()); // without `OFFSET_IS_ADDR`, this is always empty
ptrs.encode(s)
}
}
@@ -54,10 +55,10 @@ impl ProvenanceMap {
/// Give access to the ptr-sized provenances (which can also be thought of as relocations, and
/// indeed that is how codegen treats them).
///
- /// Only exposed with `AllocId` provenance, since it panics if there is bytewise provenance.
+ /// Only exposed with `CtfeProvenance` provenance, since it panics if there is bytewise provenance.
#[inline]
- pub fn ptrs(&self) -> &SortedMap<Size, AllocId> {
- debug_assert!(self.bytes.is_none()); // `AllocId::OFFSET_IS_ADDR` is false so this cannot fail
+ pub fn ptrs(&self) -> &SortedMap<Size, CtfeProvenance> {
+ debug_assert!(self.bytes.is_none()); // `CtfeProvenance::OFFSET_IS_ADDR` is false so this cannot fail
&self.ptrs
}
}
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 44b22e2d3..413867939 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -290,7 +290,7 @@ macro_rules! impl_into_diagnostic_arg_through_debug {
// These types have nice `Debug` output so we can just use them in diagnostics.
impl_into_diagnostic_arg_through_debug! {
AllocId,
- Pointer,
+ Pointer<AllocId>,
AllocRange,
}
@@ -323,7 +323,7 @@ pub enum UndefinedBehaviorInfo<'tcx> {
/// Invalid metadata in a wide pointer
InvalidMeta(InvalidMetaKind),
/// Reading a C string that does not end within its allocation.
- UnterminatedCString(Pointer),
+ UnterminatedCString(Pointer<AllocId>),
/// Using a pointer after it got freed.
PointerUseAfterFree(AllocId, CheckInAllocMsg),
/// Used a pointer outside the bounds it is valid for.
@@ -350,11 +350,11 @@ pub enum UndefinedBehaviorInfo<'tcx> {
/// Using a non-character `u32` as character.
InvalidChar(u32),
/// The tag of an enum does not encode an actual discriminant.
- InvalidTag(Scalar),
+ InvalidTag(Scalar<AllocId>),
/// Using a pointer-not-to-a-function as function pointer.
- InvalidFunctionPointer(Pointer),
+ InvalidFunctionPointer(Pointer<AllocId>),
/// Using a pointer-not-to-a-vtable as vtable pointer.
- InvalidVTablePointer(Pointer),
+ InvalidVTablePointer(Pointer<AllocId>),
/// Using a string that is not valid UTF-8,
InvalidStr(std::str::Utf8Error),
/// Using uninitialized data where it is not allowed.
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index e360fb3ea..2db560085 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -157,7 +157,7 @@ pub use self::allocation::{
InitChunk, InitChunkIter,
};
-pub use self::pointer::{Pointer, PointerArithmetic, Provenance};
+pub use self::pointer::{CtfeProvenance, Pointer, PointerArithmetic, Provenance};
/// Uniquely identifies one of the following:
/// - A constant
@@ -199,7 +199,7 @@ pub struct LitToConstInput<'tcx> {
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
pub enum LitToConstError {
/// The literal's inferred type did not match the expected `ty` in the input.
- /// This is used for graceful error handling (`delay_span_bug`) in
+ /// This is used for graceful error handling (`span_delayed_bug`) in
/// type checking (`Const::from_anon_const`).
TypeError,
Reported(ErrorGuaranteed),
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index 1c9ce1cb1..689338773 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -3,7 +3,7 @@ use super::{AllocId, InterpResult};
use rustc_macros::HashStable;
use rustc_target::abi::{HasDataLayout, Size};
-use std::fmt;
+use std::{fmt, num::NonZeroU64};
////////////////////////////////////////////////////////////////////////////////
// Pointer arithmetic
@@ -114,22 +114,7 @@ pub trait Provenance: Copy + fmt::Debug + 'static {
const OFFSET_IS_ADDR: bool;
/// Determines how a pointer should be printed.
- ///
- /// Default impl is only good for when `OFFSET_IS_ADDR == true`.
- fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result
- where
- Self: Sized,
- {
- assert!(Self::OFFSET_IS_ADDR);
- let (prov, addr) = ptr.into_parts(); // address is absolute
- write!(f, "{:#x}", addr.bytes())?;
- if f.alternate() {
- write!(f, "{prov:#?}")?;
- } else {
- write!(f, "{prov:?}")?;
- }
- Ok(())
- }
+ fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result;
/// If `OFFSET_IS_ADDR == false`, provenance must always be able to
/// identify the allocation this ptr points to (i.e., this must return `Some`).
@@ -141,6 +126,80 @@ pub trait Provenance: Copy + fmt::Debug + 'static {
fn join(left: Option<Self>, right: Option<Self>) -> Option<Self>;
}
+/// The type of provenance in the compile-time interpreter.
+/// This is a packed representation of an `AllocId` and an `immutable: bool`.
+#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct CtfeProvenance(NonZeroU64);
+
+impl From<AllocId> for CtfeProvenance {
+ fn from(value: AllocId) -> Self {
+ let prov = CtfeProvenance(value.0);
+ assert!(!prov.immutable(), "`AllocId` with the highest bit set cannot be used in CTFE");
+ prov
+ }
+}
+
+impl fmt::Debug for CtfeProvenance {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&self.alloc_id(), f)?; // propagates `alternate` flag
+ if self.immutable() {
+ write!(f, "<imm>")?;
+ }
+ Ok(())
+ }
+}
+
+const IMMUTABLE_MASK: u64 = 1 << 63; // the highest bit
+
+impl CtfeProvenance {
+ /// Returns the `AllocId` of this provenance.
+ #[inline(always)]
+ pub fn alloc_id(self) -> AllocId {
+ AllocId(NonZeroU64::new(self.0.get() & !IMMUTABLE_MASK).unwrap())
+ }
+
+ /// Returns whether this provenance is immutable.
+ #[inline]
+ pub fn immutable(self) -> bool {
+ self.0.get() & IMMUTABLE_MASK != 0
+ }
+
+ /// Returns an immutable version of this provenance.
+ #[inline]
+ pub fn as_immutable(self) -> Self {
+ CtfeProvenance(self.0 | IMMUTABLE_MASK)
+ }
+}
+
+impl Provenance for CtfeProvenance {
+ // With the `AllocId` as provenance, the `offset` is interpreted *relative to the allocation*,
+ // so ptr-to-int casts are not possible (since we do not know the global physical offset).
+ const OFFSET_IS_ADDR: bool = false;
+
+ fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Print AllocId.
+ fmt::Debug::fmt(&ptr.provenance.alloc_id(), f)?; // propagates `alternate` flag
+ // Print offset only if it is non-zero.
+ if ptr.offset.bytes() > 0 {
+ write!(f, "+{:#x}", ptr.offset.bytes())?;
+ }
+ // Print immutable status.
+ if ptr.provenance.immutable() {
+ write!(f, "<imm>")?;
+ }
+ Ok(())
+ }
+
+ fn get_alloc_id(self) -> Option<AllocId> {
+ Some(self.alloc_id())
+ }
+
+ fn join(_left: Option<Self>, _right: Option<Self>) -> Option<Self> {
+ panic!("merging provenance is not supported when `OFFSET_IS_ADDR` is false")
+ }
+}
+
+// We also need this impl so that one can debug-print `Pointer<AllocId>`
impl Provenance for AllocId {
// With the `AllocId` as provenance, the `offset` is interpreted *relative to the allocation*,
// so ptr-to-int casts are not possible (since we do not know the global physical offset).
@@ -174,7 +233,7 @@ impl Provenance for AllocId {
/// Pointers are "tagged" with provenance information; typically the `AllocId` they belong to.
#[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable, Hash)]
#[derive(HashStable)]
-pub struct Pointer<Prov = AllocId> {
+pub struct Pointer<Prov = CtfeProvenance> {
pub(super) offset: Size, // kept private to avoid accidental misinterpretation (meaning depends on `Prov` type)
pub provenance: Prov,
}
@@ -182,7 +241,7 @@ pub struct Pointer<Prov = AllocId> {
static_assert_size!(Pointer, 16);
// `Option<Prov>` pointers are also passed around quite a bit
// (but not stored in permanent machine state).
-static_assert_size!(Pointer<Option<AllocId>>, 16);
+static_assert_size!(Pointer<Option<CtfeProvenance>>, 16);
// We want the `Debug` output to be readable as it is used by `derive(Debug)` for
// all the Miri types.
@@ -215,7 +274,7 @@ impl<Prov: Provenance> fmt::Display for Pointer<Option<Prov>> {
impl From<AllocId> for Pointer {
#[inline(always)]
fn from(alloc_id: AllocId) -> Self {
- Pointer::new(alloc_id, Size::ZERO)
+ Pointer::new(alloc_id.into(), Size::ZERO)
}
}
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index fbf6403ea..092b59dee 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -110,10 +110,10 @@ impl<'tcx> TyCtxt<'tcx> {
let Some(local_def_id) = ct.def.as_local() else { return };
self.struct_span_lint_hir(
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
- self.hir().local_def_id_to_hir_id(local_def_id),
+ self.local_def_id_to_hir_id(local_def_id),
self.def_span(ct.def),
"cannot use constants which depend on generic parameters in types",
- |err| err,
+ |_| {},
)
}
}
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 0d548f886..5ecff04f3 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -11,7 +11,10 @@ use rustc_target::abi::{HasDataLayout, Size};
use crate::ty::ScalarInt;
-use super::{AllocId, InterpResult, Pointer, PointerArithmetic, Provenance, ScalarSizeMismatch};
+use super::{
+ AllocId, CtfeProvenance, InterpResult, Pointer, PointerArithmetic, Provenance,
+ ScalarSizeMismatch,
+};
/// A `Scalar` represents an immediate, primitive value existing outside of a
/// `memory::Allocation`. It is in many ways like a small chunk of an `Allocation`, up to 16 bytes in
@@ -22,7 +25,7 @@ use super::{AllocId, InterpResult, Pointer, PointerArithmetic, Provenance, Scala
/// Do *not* match on a `Scalar`! Use the various `to_*` methods instead.
#[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, Hash)]
#[derive(HashStable)]
-pub enum Scalar<Prov = AllocId> {
+pub enum Scalar<Prov = CtfeProvenance> {
/// The raw bytes of a simple value.
Int(ScalarInt),
@@ -267,6 +270,9 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
/// Will perform ptr-to-int casts if needed and possible.
/// If that fails, we know the offset is relative, so we return an "erased" Scalar
/// (which is useful for error messages but not much else).
+ ///
+ /// The error type is `AllocId`, not `CtfeProvenance`, since `AllocId` is the "minimal"
+ /// component all provenance types must have.
#[inline]
pub fn try_to_int(self) -> Result<ScalarInt, Scalar<AllocId>> {
match self {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 7054cede2..1e5a7401c 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -736,6 +736,8 @@ impl SourceInfo {
rustc_index::newtype_index! {
#[derive(HashStable)]
+ #[encodable]
+ #[orderable]
#[debug_format = "_{}"]
pub struct Local {
const RETURN_PLACE = 0;
@@ -973,7 +975,7 @@ pub enum LocalInfo<'tcx> {
impl<'tcx> LocalDecl<'tcx> {
pub fn local_info(&self) -> &LocalInfo<'tcx> {
- &self.local_info.as_ref().assert_crate_local()
+ self.local_info.as_ref().assert_crate_local()
}
/// Returns `true` only if local is a binding that can itself be
@@ -1171,6 +1173,8 @@ rustc_index::newtype_index! {
/// [`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)]
+ #[encodable]
+ #[orderable]
#[debug_format = "bb{}"]
pub struct BasicBlock {
const START_BLOCK = 0;
@@ -1305,6 +1309,7 @@ impl<'tcx> BasicBlockData<'tcx> {
rustc_index::newtype_index! {
#[derive(HashStable)]
+ #[encodable]
#[debug_format = "scope[{}]"]
pub struct SourceScope {
const OUTERMOST_SOURCE_SCOPE = 0;
@@ -1533,6 +1538,8 @@ impl UserTypeProjection {
rustc_index::newtype_index! {
#[derive(HashStable)]
+ #[encodable]
+ #[orderable]
#[debug_format = "promoted[{}]"]
pub struct Promoted {}
}
@@ -1611,14 +1618,29 @@ impl Location {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DefLocation {
Argument,
- Body(Location),
+ Assignment(Location),
+ CallReturn { call: BasicBlock, target: Option<BasicBlock> },
}
impl DefLocation {
pub fn dominates(self, location: Location, dominators: &Dominators<BasicBlock>) -> bool {
match self {
DefLocation::Argument => true,
- DefLocation::Body(def) => def.successor_within_block().dominates(location, dominators),
+ DefLocation::Assignment(def) => {
+ def.successor_within_block().dominates(location, dominators)
+ }
+ DefLocation::CallReturn { target: None, .. } => false,
+ DefLocation::CallReturn { call, target: Some(target) } => {
+ // The definition occurs on the call -> target edge. The definition dominates a use
+ // if and only if the edge is on all paths from the entry to the use.
+ //
+ // Note that a call terminator has only one edge that can reach the target, so when
+ // the call strongly dominates the target, all paths from the entry to the target
+ // go through the call -> target edge.
+ call != target
+ && dominators.dominates(call, target)
+ && dominators.dominates(target, location.block)
+ }
}
}
}
diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs
index eb4aa9eb9..b81e9fa1a 100644
--- a/compiler/rustc_middle/src/mir/patch.rs
+++ b/compiler/rustc_middle/src/mir/patch.rs
@@ -1,7 +1,4 @@
-use rustc_index::{Idx, IndexVec};
use rustc_middle::mir::*;
-use rustc_middle::ty::Ty;
-use rustc_span::Span;
/// This struct represents a patch to MIR, which can add
/// new statements and basic blocks and patch over block
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a13248584..071c6a755 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1,23 +1,18 @@
use std::collections::BTreeSet;
-use std::fmt::{self, Debug, Display, Write as _};
+use std::fmt::{Display, Write as _};
use std::fs;
use std::io::{self, Write as _};
use std::path::{Path, PathBuf};
use super::graphviz::write_mir_fn_graphviz;
use super::spanview::write_mir_fn_spanview;
-use either::Either;
use rustc_ast::InlineAsmTemplatePiece;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def_id::DefId;
-use rustc_index::Idx;
use rustc_middle::mir::interpret::{
- alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, ConstAllocation, GlobalAlloc,
- Pointer, Provenance,
+ alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
+ Provenance,
};
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, *};
-use rustc_middle::ty::{self, TyCtxt};
use rustc_target::abi::Size;
const INDENT: &str = " ";
@@ -1337,13 +1332,13 @@ pub fn write_allocations<'tcx>(
fn alloc_ids_from_alloc(
alloc: ConstAllocation<'_>,
) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
- alloc.inner().provenance().ptrs().values().map(|id| *id)
+ alloc.inner().provenance().ptrs().values().map(|p| p.alloc_id())
}
fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
match val {
ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _)) => {
- Either::Left(std::iter::once(ptr.provenance))
+ Either::Left(std::iter::once(ptr.provenance.alloc_id()))
}
ConstValue::Scalar(interpret::Scalar::Int { .. }) => Either::Right(std::iter::empty()),
ConstValue::ZeroSized => Either::Right(std::iter::empty()),
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 0540eb0ef..98642adc1 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -27,7 +27,7 @@ pub enum UnsafetyViolationKind {
UnsafeFn,
}
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
+#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum UnsafetyViolationDetails {
CallToUnsafeFunction,
UseOfInlineAssembly,
@@ -39,68 +39,17 @@ pub enum UnsafetyViolationDetails {
AccessToUnionField,
MutationOfLayoutConstrainedField,
BorrowOfLayoutConstrainedField,
- CallToFunctionWith,
+ CallToFunctionWith {
+ /// Target features enabled in callee's `#[target_feature]` but missing in
+ /// caller's `#[target_feature]`.
+ missing: Vec<Symbol>,
+ /// Target features in `missing` that are enabled at compile time
+ /// (e.g., with `-C target-feature`).
+ build_enabled: Vec<Symbol>,
+ },
}
-impl UnsafetyViolationDetails {
- pub fn description_and_note(&self) -> (&'static str, &'static str) {
- use UnsafetyViolationDetails::*;
- match self {
- CallToUnsafeFunction => (
- "call to unsafe function",
- "consult the function's documentation for information on how to avoid undefined \
- behavior",
- ),
- UseOfInlineAssembly => (
- "use of inline assembly",
- "inline assembly is entirely unchecked and can cause undefined behavior",
- ),
- InitializingTypeWith => (
- "initializing type with `rustc_layout_scalar_valid_range` attr",
- "initializing a layout restricted type's field with a value outside the valid \
- range is undefined behavior",
- ),
- CastOfPointerToInt => {
- ("cast of pointer to int", "casting pointers to integers in constants")
- }
- UseOfMutableStatic => (
- "use of mutable static",
- "mutable statics can be mutated by multiple threads: aliasing violations or data \
- races will cause undefined behavior",
- ),
- UseOfExternStatic => (
- "use of extern static",
- "extern statics are not controlled by the Rust type system: invalid data, \
- aliasing violations or data races will cause undefined behavior",
- ),
- DerefOfRawPointer => (
- "dereference of raw pointer",
- "raw pointers may be null, dangling or unaligned; they can violate aliasing rules \
- and cause data races: all of these are undefined behavior",
- ),
- AccessToUnionField => (
- "access to union field",
- "the field may not be properly initialized: using uninitialized data will cause \
- undefined behavior",
- ),
- MutationOfLayoutConstrainedField => (
- "mutation of layout constrained field",
- "mutating layout constrained fields cannot statically be checked for valid values",
- ),
- BorrowOfLayoutConstrainedField => (
- "borrow of layout constrained field with interior mutability",
- "references to fields of layout constrained fields lose the constraints. Coupled \
- with interior mutability, the field can be changed to invalid values",
- ),
- CallToFunctionWith => (
- "call to function with `#[target_feature]`",
- "can only be called if the required target features are available",
- ),
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
+#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub struct UnsafetyViolation {
pub source_info: SourceInfo,
pub lint_root: hir::HirId,
@@ -132,6 +81,7 @@ pub struct UnsafetyCheckResult {
rustc_index::newtype_index! {
#[derive(HashStable)]
+ #[encodable]
#[debug_format = "_{}"]
pub struct CoroutineSavedLocal {}
}
@@ -341,7 +291,11 @@ pub enum ConstraintCategory<'tcx> {
UseAsConst,
UseAsStatic,
TypeAnnotation,
- Cast,
+ Cast {
+ /// Whether this is an unsizing cast and if yes, this contains the target type.
+ /// Region variables are erased to ReErased.
+ unsize_to: Option<Ty<'tcx>>,
+ },
/// A constraint that came from checking the body of a closure.
///
@@ -416,7 +370,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
ty::ReVar(vid) => {
let br = ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon };
- ty::Region::new_late_bound(tcx, depth, br)
+ ty::Region::new_bound(tcx, depth, br)
}
_ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
});
@@ -430,7 +384,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
) -> Ty<'tcx> {
tcx.fold_regions(self.inner, |r, depth| match r.kind() {
- ty::ReLateBound(debruijn, br) => {
+ ty::ReBound(debruijn, br) => {
debug_assert_eq!(debruijn, depth);
map(ty::RegionVid::new(br.var.index()))
}
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index a5358687c..cb9fc0d37 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -1,9 +1,7 @@
-use rustc_hir::def_id::DefId;
use rustc_middle::hir;
use rustc_middle::mir::*;
-use rustc_middle::ty::TyCtxt;
use rustc_session::config::MirSpanview;
-use rustc_span::{BytePos, Pos, Span};
+use rustc_span::{BytePos, Pos};
use std::cmp;
use std::io::{self, Write};
@@ -369,7 +367,7 @@ where
debug_indent, span, viewable.span
);
from_pos = span.hi();
- make_html_snippet(tcx, span, Some(&viewable))
+ make_html_snippet(tcx, span, Some(viewable))
} else {
None
};
@@ -439,7 +437,7 @@ where
tcx,
from_pos,
to_pos,
- &remaining_viewables,
+ remaining_viewables,
subalt,
layer + 1,
w,
@@ -472,7 +470,7 @@ where
"{}After overlaps, writing (end span?) {:?} of viewable.span {:?}",
debug_indent, span, viewable.span
);
- if let Some(ref html_snippet) = make_html_snippet(tcx, span, Some(&viewable)) {
+ if let Some(ref html_snippet) = make_html_snippet(tcx, span, Some(viewable)) {
from_pos = span.hi();
write_span(html_snippet, &viewable.tooltip, alt, layer, w)?;
}
@@ -507,11 +505,7 @@ fn write_span<W>(
where
W: Write,
{
- let maybe_alt_class = if layer > 0 {
- if alt { " odd" } else { " even" }
- } else {
- ""
- };
+ let maybe_alt_class = if layer > 0 { if alt { " odd" } else { " even" } } else { "" };
let maybe_title_attr = if !tooltip.is_empty() {
format!(" title=\"{}\"", escape_attr(tooltip))
} else {
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 3471d620e..f929a5cec 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -159,7 +159,7 @@ impl<'tcx> Place<'tcx> {
#[inline]
pub fn as_ref(&self) -> PlaceRef<'tcx> {
- PlaceRef { local: self.local, projection: &self.projection }
+ PlaceRef { local: self.local, projection: self.projection }
}
/// Iterate over the projections in evaluation order, i.e., the first element is the base with
@@ -381,7 +381,7 @@ impl<'tcx> Operand<'tcx> {
impl<'tcx> ConstOperand<'tcx> {
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
match self.const_.try_to_scalar() {
- Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
+ Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance.alloc_id()) {
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
Some(def_id)
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 7b0f27f9b..8cf9e55f0 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1404,18 +1404,18 @@ pub enum BinOp {
BitOr,
/// The `<<` operator (shift left)
///
- /// The offset is truncated to the size of the first operand before shifting.
+ /// The offset is truncated to the size of the first operand and made unsigned before shifting.
Shl,
- /// Like `Shl`, but is UB if the RHS >= LHS::BITS
+ /// Like `Shl`, but is UB if the RHS >= LHS::BITS or RHS < 0
ShlUnchecked,
/// The `>>` operator (shift right)
///
- /// The offset is truncated to the size of the first operand before shifting.
+ /// The offset is truncated to the size of the first operand and made unsigned before shifting.
///
/// This is an arithmetic shift if the LHS is signed
/// and a logical shift if the LHS is unsigned.
Shr,
- /// Like `Shl`, but is UB if the RHS >= LHS::BITS
+ /// Like `Shl`, but is UB if the RHS >= LHS::BITS or RHS < 0
ShrUnchecked,
/// The `==` operator (equality)
Eq,
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 6ab2da23a..f9b2a6ee8 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -4,9 +4,7 @@
*/
use crate::mir::*;
-use crate::ty::{self, Ty, TyCtxt};
use rustc_hir as hir;
-use rustc_target::abi::{FieldIdx, VariantIdx};
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
pub struct PlaceTy<'tcx> {
@@ -40,7 +38,7 @@ impl<'tcx> PlaceTy<'tcx> {
None => adt_def.non_enum_variant(),
Some(variant_index) => {
assert!(adt_def.is_enum());
- &adt_def.variant(variant_index)
+ adt_def.variant(variant_index)
}
};
let field_def = &variant_def.fields[f];
@@ -95,9 +93,7 @@ impl<'tcx> PlaceTy<'tcx> {
ProjectionElem::Subslice { from, to, from_end } => {
PlaceTy::from_ty(match self.ty.kind() {
ty::Slice(..) => self.ty,
- ty::Array(inner, _) if !from_end => {
- Ty::new_array(tcx, *inner, (to - from) as u64)
- }
+ ty::Array(inner, _) if !from_end => Ty::new_array(tcx, *inner, to - from),
ty::Array(inner, size) if from_end => {
let size = size.eval_target_usize(tcx, param_env);
let len = size - from - to;
@@ -143,7 +139,7 @@ impl<'tcx> Place<'tcx> {
where
D: HasLocalDecls<'tcx>,
{
- Place::ty_from(self.local, &self.projection, local_decls, tcx)
+ Place::ty_from(self.local, self.projection, local_decls, tcx)
}
}
@@ -152,7 +148,7 @@ impl<'tcx> PlaceRef<'tcx> {
where
D: HasLocalDecls<'tcx>,
{
- Place::ty_from(self.local, &self.projection, local_decls, tcx)
+ Place::ty_from(self.local, self.projection, local_decls, tcx)
}
}
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 9dfbe1733..98e3a1f60 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -2,9 +2,8 @@
use rustc_hir::LangItem;
use smallvec::SmallVec;
-use super::{BasicBlock, InlineAsmOperand, Operand, SourceInfo, TerminatorKind, UnwindAction};
+use super::TerminatorKind;
use rustc_macros::HashStable;
-use std::iter;
use std::slice;
use super::*;
@@ -28,7 +27,9 @@ impl SwitchTargets {
/// Inverse of `SwitchTargets::static_if`.
pub fn as_static_if(&self) -> Option<(u128, BasicBlock, BasicBlock)> {
- if let &[value] = &self.values[..] && let &[then, else_] = &self.targets[..] {
+ if let &[value] = &self.values[..]
+ && let &[then, else_] = &self.targets[..]
+ {
Some((value, then, else_))
} else {
None
@@ -148,11 +149,17 @@ impl<O> AssertKind<O> {
RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
ResumedAfterReturn(CoroutineKind::Coroutine) => "coroutine resumed after completion",
ResumedAfterReturn(CoroutineKind::Async(_)) => "`async fn` resumed after completion",
+ ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => {
+ "`async gen fn` resumed after completion"
+ }
ResumedAfterReturn(CoroutineKind::Gen(_)) => {
"`gen fn` should just keep returning `None` after completion"
}
ResumedAfterPanic(CoroutineKind::Coroutine) => "coroutine resumed after panicking",
ResumedAfterPanic(CoroutineKind::Async(_)) => "`async fn` resumed after panicking",
+ ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => {
+ "`async gen fn` resumed after panicking"
+ }
ResumedAfterPanic(CoroutineKind::Gen(_)) => {
"`gen fn` should just keep returning `None` after panicking"
}
@@ -243,6 +250,7 @@ impl<O> AssertKind<O> {
DivisionByZero(_) => middle_assert_divide_by_zero,
RemainderByZero(_) => middle_assert_remainder_by_zero,
ResumedAfterReturn(CoroutineKind::Async(_)) => middle_assert_async_resume_after_return,
+ ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => todo!(),
ResumedAfterReturn(CoroutineKind::Gen(_)) => {
bug!("gen blocks can be resumed after they return and will keep returning `None`")
}
@@ -250,6 +258,7 @@ impl<O> AssertKind<O> {
middle_assert_coroutine_resume_after_return
}
ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic,
+ ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => todo!(),
ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_gen_resume_after_panic,
ResumedAfterPanic(CoroutineKind::Coroutine) => {
middle_assert_coroutine_resume_after_panic
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index d5c81b6cd..93a9bbf64 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -3,7 +3,6 @@
use rustc_ast::InlineAsmTemplatePiece;
use super::*;
-use crate::ty;
TrivialTypeTraversalImpls! {
BlockTailInfo,
@@ -16,7 +15,6 @@ TrivialTypeTraversalImpls! {
UserTypeAnnotationIndex,
BorrowKind,
CastKind,
- hir::Movability,
BasicBlock,
SwitchTargets,
CoroutineKind,
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index d47cfd571..9059936f4 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -63,9 +63,7 @@
//! `is_cleanup` above.
use crate::mir::*;
-use crate::ty::GenericArgsRef;
-use crate::ty::{self, CanonicalUserTypeAnnotation, Ty};
-use rustc_span::Span;
+use crate::ty::CanonicalUserTypeAnnotation;
macro_rules! make_mir_visitor {
($visitor_trait_name:ident, $($mutability:ident)?) => {