summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_const_eval
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_const_eval
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_const_eval')
-rw-r--r--compiler/rustc_const_eval/Cargo.toml1
-rw-r--r--compiler/rustc_const_eval/messages.ftl92
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs13
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs8
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs14
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/discriminant.rs17
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs51
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs27
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs26
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs19
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs22
-rw-r--r--compiler/rustc_const_eval/src/lib.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs8
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs30
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs7
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs7
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs82
-rw-r--r--compiler/rustc_const_eval/src/util/call_kind.rs137
-rw-r--r--compiler/rustc_const_eval/src/util/collect_writes.rs36
-rw-r--r--compiler/rustc_const_eval/src/util/compare_types.rs4
-rw-r--r--compiler/rustc_const_eval/src/util/find_self_call.rs36
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs5
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs3
35 files changed, 290 insertions, 410 deletions
diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml
index 98ac36c1c..74030a43c 100644
--- a/compiler/rustc_const_eval/Cargo.toml
+++ b/compiler/rustc_const_eval/Cargo.toml
@@ -14,6 +14,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
+rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_index = { path = "../rustc_index" }
rustc_infer = { path = "../rustc_infer" }
rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index f6751df44..7d56cf0aa 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -1,40 +1,60 @@
-const_eval_unstable_in_stable =
- const-stable function cannot use `#[feature({$gate})]`
- .unstable_sugg = if it is not part of the public API, make this function unstably const
- .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+const_eval_interior_mutability_borrow =
+ cannot borrow here, since the borrowed element may contain interior mutability
-const_eval_thread_local_access =
- thread-local statics cannot be accessed at compile-time
+const_eval_interior_mutable_data_refer =
+ {$kind}s cannot refer to interior mutable data
+ .label = this borrow of an interior mutable value may end up in the final value
+ .help = to fix this, the value can be extracted to a separate `static` item and then referenced
+ .teach_note =
+ A constant containing interior mutable data behind a reference can allow you to modify that data.
+ This would make multiple uses of a constant to be able to see different values and allow circumventing
+ the `Send` and `Sync` requirements for shared mutable data, which is unsound.
-const_eval_static_access =
- {$kind}s cannot refer to statics
- .help = consider extracting the value of the `static` to a `const`, and referring to that
- .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
- .teach_help = To fix this, the value can be extracted to a `const` and then used.
+const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
-const_eval_raw_ptr_to_int =
- pointers cannot be cast to integers during const eval
- .note = at compile-time, pointers do not have an integer value
- .note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
+const_eval_mut_deref =
+ mutation through a reference is not allowed in {$kind}s
+
+const_eval_non_const_fmt_macro_call =
+ cannot call non-const formatting macro in {$kind}s
+
+const_eval_non_const_fn_call =
+ cannot call non-const fn `{$def_path_str}` in {$kind}s
+
+const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
const_eval_raw_ptr_comparison =
pointers cannot be reliably compared during const eval
.note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
-const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
+const_eval_raw_ptr_to_int =
+ pointers cannot be cast to integers during const eval
+ .note = at compile-time, pointers do not have an integer value
+ .note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
-const_eval_mut_deref =
- mutation through a reference is not allowed in {$kind}s
+const_eval_static_access =
+ {$kind}s cannot refer to statics
+ .help = consider extracting the value of the `static` to a `const`, and referring to that
+ .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
+ .teach_help = To fix this, the value can be extracted to a `const` and then used.
+
+const_eval_thread_local_access =
+ thread-local statics cannot be accessed at compile-time
const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s
const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s
-const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
-
const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s
-const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
+const_eval_unallowed_heap_allocations =
+ allocations are not allowed in {$kind}s
+ .label = allocation not allowed in {$kind}s
+ .teach_note =
+ The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
+
+const_eval_unallowed_inline_asm =
+ inline assembly is not allowed in {$kind}s
const_eval_unallowed_mutable_refs =
mutable references are not allowed in the final value of {$kind}s
@@ -60,32 +80,12 @@ const_eval_unallowed_mutable_refs_raw =
If you really want global mutable state, try using static mut or a global UnsafeCell.
-const_eval_non_const_fmt_macro_call =
- cannot call non-const formatting macro in {$kind}s
-
-const_eval_non_const_fn_call =
- cannot call non-const fn `{$def_path_str}` in {$kind}s
-
const_eval_unallowed_op_in_const_context =
{$msg}
-const_eval_unallowed_heap_allocations =
- allocations are not allowed in {$kind}s
- .label = allocation not allowed in {$kind}s
- .teach_note =
- The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
-
-const_eval_unallowed_inline_asm =
- inline assembly is not allowed in {$kind}s
-
-const_eval_interior_mutable_data_refer =
- {$kind}s cannot refer to interior mutable data
- .label = this borrow of an interior mutable value may end up in the final value
- .help = to fix this, the value can be extracted to a separate `static` item and then referenced
- .teach_note =
- A constant containing interior mutable data behind a reference can allow you to modify that data.
- This would make multiple uses of a constant to be able to see different values and allow circumventing
- the `Send` and `Sync` requirements for shared mutable data, which is unsound.
+const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
-const_eval_interior_mutability_borrow =
- cannot borrow here, since the borrowed element may contain interior mutability
+const_eval_unstable_in_stable =
+ const-stable function cannot use `#[feature({$gate})]`
+ .unstable_sugg = if it is not part of the public API, make this function unstably const
+ .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 0579f7815..c591ff75a 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -3,7 +3,8 @@ use std::fmt;
use rustc_errors::Diagnostic;
use rustc_middle::mir::AssertKind;
-use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt};
+use rustc_middle::query::TyCtxtAt;
+use rustc_middle::ty::{layout::LayoutError, ConstInt};
use rustc_span::{Span, Symbol};
use super::InterpCx;
@@ -104,13 +105,13 @@ impl<'tcx> ConstEvalErr<'tcx> {
// Add spans for the stacktrace. Don't print a single-line backtrace though.
if self.stacktrace.len() > 1 {
// Helper closure to print duplicated lines.
- let mut flush_last_line = |last_frame, times| {
+ let mut flush_last_line = |last_frame: Option<(String, _)>, times| {
if let Some((line, span)) = last_frame {
- err.span_note(span, &line);
+ err.span_note(span, line.clone());
// Don't print [... additional calls ...] if the number of lines is small
if times < 3 {
for _ in 0..times {
- err.span_note(span, &line);
+ err.span_note(span, line.clone());
}
} else {
err.span_note(
@@ -169,14 +170,14 @@ impl<'tcx> ConstEvalErr<'tcx> {
// See <https://github.com/rust-lang/rust/pull/63152>.
let mut err = struct_error(tcx, &self.error.to_string());
self.decorate(&mut err, decorate);
- ErrorHandled::Reported(err.emit())
+ ErrorHandled::Reported(err.emit().into())
}
_ => {
// Report as hard error.
let mut err = struct_error(tcx, message);
err.span_label(self.span, self.error.to_string());
self.decorate(&mut err, decorate);
- ErrorHandled::Reported(err.emit())
+ ErrorHandled::Reported(err.emit().into())
}
}
}
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 4bd6fe199..046d20529 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -296,12 +296,12 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
}
let cid = key.value;
- let def = cid.instance.def.with_opt_param();
- let is_static = tcx.is_static(def.did);
+ let def = cid.instance.def.def_id();
+ let is_static = tcx.is_static(def);
let mut ecx = InterpCx::new(
tcx,
- tcx.def_span(def.did),
+ tcx.def_span(def),
key.param_env,
// Statics (and promoteds inside statics) may access other statics, because unlike consts
// they do not have to behave "as if" they were evaluated at runtime.
@@ -368,7 +368,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
if matches!(err.error, InterpError::UndefinedBehavior(_)) {
diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR);
}
- diag.note(&format!(
+ diag.note(format!(
"the raw bytes of the constant ({}",
display_allocation(
*ecx.tcx,
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 088a824fd..fa8253d5e 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -2,7 +2,7 @@ use rustc_attr as attr;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index a5dfd1072..58b5755af 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -375,18 +375,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
match instance {
ty::InstanceDef::Item(def) => {
- if ecx.tcx.is_ctfe_mir_available(def.did) {
- Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def))
- } else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst {
+ if ecx.tcx.is_ctfe_mir_available(def) {
+ Ok(ecx.tcx.mir_for_ctfe(def))
+ } else if ecx.tcx.def_kind(def) == DefKind::AssocConst {
let guar = ecx.tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"This is likely a const item that is missing from its impl",
);
- throw_inval!(AlreadyReported(guar));
+ throw_inval!(AlreadyReported(guar.into()));
} else {
// `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
// so this should be unreachable.
- let path = ecx.tcx.def_path_str(def.did);
+ let path = ecx.tcx.def_path_str(def);
bug!("trying to call extern function `{path}` at compile-time");
}
}
@@ -410,9 +410,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
// Execution might have wandered off into other crates, so we cannot do a stability-
// sensitive check here. But we can at least rule out functions that are not const
// at all.
- if !ecx.tcx.is_const_fn_raw(def.did) {
+ if !ecx.tcx.is_const_fn_raw(def) {
// allow calling functions inside a trait marked with #[const_trait].
- if !ecx.tcx.is_const_default_method(def.did) {
+ if !ecx.tcx.is_const_default_method(def) {
// We certainly do *not* want to actually call the fn
// though, so be sure we return here.
throw_unsup_format!("calling non-const function `{}`", instance)
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 3cdf1e6e3..05be45fef 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -83,7 +83,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
Some(span) => {
tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id })
}
- None => tcx.sess.struct_err(&msg),
+ None => tcx.sess.struct_err(msg),
};
diag.emit();
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 4d54c0183..b10f2e9f8 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -337,7 +337,7 @@ fn valtree_into_mplace<'tcx>(
match ty.kind() {
ty::FnDef(_, _) => {
- ecx.write_immediate(Immediate::Uninit, &place.into()).unwrap();
+ // Zero-sized type, nothing to do.
}
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
let scalar_int = valtree.unwrap_leaf();
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index 557e72124..015a9beab 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -211,18 +211,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let variant_index_relative = u32::try_from(variant_index_relative)
.expect("we checked that this fits into a u32");
// Then computing the absolute variant idx should not overflow any more.
- let variant_index = variants_start
- .checked_add(variant_index_relative)
- .expect("overflow computing absolute variant idx");
- let variants_len = op
+ let variant_index = VariantIdx::from_u32(
+ variants_start
+ .checked_add(variant_index_relative)
+ .expect("overflow computing absolute variant idx"),
+ );
+ let variants = op
.layout
.ty
.ty_adt_def()
.expect("tagged layout for non adt")
- .variants()
- .len();
- assert!(usize::try_from(variant_index).unwrap() < variants_len);
- VariantIdx::from_u32(variant_index)
+ .variants();
+ assert!(variant_index < variants.next_index());
+ variant_index
} else {
untagged_variant
}
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 3e58a58ae..7e9457800 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -5,16 +5,15 @@ use std::mem;
use either::{Either, Left, Right};
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
-use rustc_index::vec::IndexVec;
+use rustc_index::IndexVec;
use rustc_middle::mir;
-use rustc_middle::mir::interpret::{ErrorHandled, InterpError};
+use rustc_middle::mir::interpret::{ErrorHandled, InterpError, ReportedErrorInfo};
+use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
TyAndLayout,
};
-use rustc_middle::ty::{
- self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable,
-};
+use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_session::Limit;
use rustc_span::Span;
@@ -132,11 +131,10 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
}
/// What we store about a frame in an interpreter backtrace.
-#[derive(Debug)]
+#[derive(Clone, Debug)]
pub struct FrameInfo<'tcx> {
pub instance: ty::Instance<'tcx>,
pub span: Span,
- pub lint_root: Option<hir::HirId>,
}
#[derive(Clone, Copy, Eq, PartialEq, Debug)] // Miri debug-prints these
@@ -462,16 +460,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
instance: ty::InstanceDef<'tcx>,
promoted: Option<mir::Promoted>,
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
- let def = instance.with_opt_param();
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
let body = if let Some(promoted) = promoted {
- &self.tcx.promoted_mir_opt_const_arg(def)[promoted]
+ let def = instance.def_id();
+ &self.tcx.promoted_mir(def)[promoted]
} else {
M::load_mir(self, instance)?
};
// do not continue if typeck errors occurred (can only occur in local crate)
if let Some(err) = body.tainted_by_errors {
- throw_inval!(AlreadyReported(err));
+ throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err)));
}
Ok(body)
}
@@ -496,25 +494,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> Result<T, InterpError<'tcx>> {
frame
.instance
- .try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
+ .try_subst_mir_and_normalize_erasing_regions(
+ *self.tcx,
+ self.param_env,
+ ty::EarlyBinder(value),
+ )
.map_err(|_| err_inval!(TooGeneric))
}
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).
pub(super) fn resolve(
&self,
- def: ty::WithOptConstParam<DefId>,
+ def: DefId,
substs: SubstsRef<'tcx>,
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
trace!("resolve: {:?}, {:#?}", def, substs);
trace!("param_env: {:#?}", self.param_env);
trace!("substs: {:#?}", substs);
- match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env, def, substs) {
+ match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) {
Ok(Some(instance)) => Ok(instance),
Ok(None) => throw_inval!(TooGeneric),
// FIXME(eddyb) this could be a bit more specific than `AlreadyReported`.
- Err(error_reported) => throw_inval!(AlreadyReported(error_reported)),
+ Err(error_reported) => throw_inval!(AlreadyReported(error_reported.into())),
}
}
@@ -902,7 +904,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| {
match err {
ErrorHandled::Reported(err) => {
- if let Some(span) = span {
+ if !err.is_tainted_by_errors() && let Some(span) = span {
// To make it easier to figure out where this error comes from, also add a note at the current location.
self.tcx.sess.span_note_without_error(span, "erroneous constant used");
}
@@ -947,10 +949,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// This deliberately does *not* honor `requires_caller_location` since it is used for much
// more than just panics.
for frame in stack.iter().rev() {
- let lint_root = frame.lint_root();
- let span = frame.current_span();
-
- frames.push(FrameInfo { span, instance: frame.instance, lint_root });
+ let span = match frame.loc {
+ Left(loc) => {
+ // If the stacktrace passes through MIR-inlined source scopes, add them.
+ let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
+ let mut scope_data = &frame.body.source_scopes[scope];
+ while let Some((instance, call_span)) = scope_data.inlined {
+ frames.push(FrameInfo { span, instance });
+ span = call_span;
+ scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
+ }
+ span
+ }
+ Right(span) => span,
+ };
+ frames.push(FrameInfo { span, instance: frame.instance });
}
trace!("generate stacktrace: {:#?}", frames);
frames
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index b220d21f6..c2b82ba9b 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -387,7 +387,7 @@ pub fn intern_const_alloc_recursive<
Err(error) => {
ecx.tcx.sess.delay_span_bug(
ecx.tcx.span,
- &format!(
+ format!(
"error during interning should later cause validation failure: {}",
error
),
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 26fb041b4..a77c699c2 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -75,7 +75,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
}
sym::type_id => {
ensure_monomorphic_enough(tcx, tp_ty)?;
- ConstValue::from_u64(tcx.type_id_hash(tp_ty))
+ ConstValue::from_u64(tcx.type_id_hash(tp_ty).as_u64())
}
sym::variant_count => match tp_ty.kind() {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
@@ -286,14 +286,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::write_bytes => {
self.write_bytes_intrinsic(&args[0], &args[1], &args[2])?;
}
- sym::offset => {
- let ptr = self.read_pointer(&args[0])?;
- let offset_count = self.read_target_isize(&args[1])?;
- let pointee_ty = substs.type_at(0);
-
- let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
- self.write_pointer(offset_ptr, dest)?;
- }
sym::arith_offset => {
let ptr = self.read_pointer(&args[0])?;
let offset_count = self.read_target_isize(&args[1])?;
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
index 3701eb93e..df5b58100 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
@@ -111,11 +111,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
location
}
- pub(crate) fn location_triple_for_span(&self, mut span: Span) -> (Symbol, u32, u32) {
- // Remove `Inlined` marks as they pollute `expansion_cause`.
- while span.is_inlined() {
- span.remove_mark();
- }
+ pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
(
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 0291cca73..b448e3a24 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -104,7 +104,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
type FrameExtra;
/// Extra data stored in every allocation.
- type AllocExtra: Debug + Clone + 'static;
+ type AllocExtra: Debug + Clone + 'tcx;
/// Type for the bytes of the allocation.
type Bytes: AllocBytes + 'static;
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index a3764a7d1..d5b6a581a 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -215,7 +215,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.allocate_raw_ptr(alloc, kind)
}
- /// This can fail only of `alloc` contains provenance.
+ /// This can fail only if `alloc` contains provenance.
pub fn allocate_raw_ptr(
&mut self,
alloc: Allocation,
@@ -807,9 +807,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
DumpAllocs { ecx: self, allocs }
}
- /// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation
- /// are not considered leaked. Leaks whose kind `may_leak()` returns true are not reported.
- pub fn leak_report(&self, static_roots: &[AllocId]) -> usize {
+ /// Find leaked allocations. Allocations reachable from `static_roots` or a `Global` allocation
+ /// are not considered leaked, as well as leaks whose kind's `may_leak()` returns true.
+ pub fn find_leaked_allocations(
+ &self,
+ static_roots: &[AllocId],
+ ) -> Vec<(AllocId, MemoryKind<M::MemoryKind>, Allocation<M::Provenance, M::AllocExtra, M::Bytes>)>
+ {
// Collect the set of allocations that are *reachable* from `Global` allocations.
let reachable = {
let mut reachable = FxHashSet::default();
@@ -833,14 +837,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
};
// All allocations that are *not* `reachable` and *not* `may_leak` are considered leaking.
- let leaks: Vec<_> = self.memory.alloc_map.filter_map_collect(|&id, &(kind, _)| {
- if kind.may_leak() || reachable.contains(&id) { None } else { Some(id) }
- });
- let n = leaks.len();
- if n > 0 {
- eprintln!("The following memory was leaked: {:?}", self.dump_allocs(leaks));
- }
- n
+ self.memory.alloc_map.filter_map_collect(|id, (kind, alloc)| {
+ if kind.may_leak() || reachable.contains(id) {
+ None
+ } else {
+ Some((*id, *kind, alloc.clone()))
+ }
+ })
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 5310ef0bb..e30af1655 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -245,6 +245,12 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
if self.layout.is_unsized() {
+ if matches!(self.op, Operand::Immediate(Immediate::Uninit)) {
+ // Uninit unsized places shouldn't occur. In the interpreter we have them
+ // temporarily for unsized arguments before their value is put in; in ConstProp they
+ // remain uninit and this code can actually be reached.
+ throw_inval!(UninitUnsizedLocal);
+ }
// There are no unsized immediates.
self.assert_mem_place().len(cx)
} else {
@@ -589,7 +595,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated
ty::ConstKind::Expr(_) => throw_inval!(TooGeneric),
ty::ConstKind::Error(reported) => {
- throw_inval!(AlreadyReported(reported))
+ throw_inval!(AlreadyReported(reported.into()))
}
ty::ConstKind::Unevaluated(uv) => {
let instance = self.resolve(uv.def, uv.substs)?;
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 4decfe863..7186148da 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -299,6 +299,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok((val, false, ty))
}
+ fn binary_ptr_op(
+ &self,
+ bin_op: mir::BinOp,
+ left: &ImmTy<'tcx, M::Provenance>,
+ right: &ImmTy<'tcx, M::Provenance>,
+ ) -> InterpResult<'tcx, (Scalar<M::Provenance>, bool, Ty<'tcx>)> {
+ use rustc_middle::mir::BinOp::*;
+
+ match bin_op {
+ // Pointer ops that are always supported.
+ Offset => {
+ let ptr = left.to_scalar().to_pointer(self)?;
+ let offset_count = right.to_scalar().to_target_isize(self)?;
+ let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
+
+ let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
+ Ok((Scalar::from_maybe_pointer(offset_ptr, self), false, left.layout.ty))
+ }
+
+ // Fall back to machine hook so Miri can support more pointer ops.
+ _ => M::binary_ptr_op(self, bin_op, left, right),
+ }
+ }
+
/// Returns the result of the specified operation, whether it overflowed, and
/// the result type.
pub fn overflowing_binary_op(
@@ -368,7 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
right.layout.ty
);
- M::binary_ptr_op(self, bin_op, left, right)
+ self.binary_ptr_op(bin_op, left, right)
}
_ => span_bug!(
self.cur_span(),
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 03b09cf83..2a31a59ad 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -5,7 +5,7 @@
use either::{Either, Left, Right};
use rustc_ast::Mutability;
-use rustc_index::vec::IndexSlice;
+use rustc_index::IndexSlice;
use rustc_middle::mir;
use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 9a366364e..1e60a1e72 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -113,8 +113,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
- // Statements we do not track.
- PlaceMention(..) | AscribeUserType(..) => {}
+ // Evaluate the place expression, without reading from it.
+ PlaceMention(box place) => {
+ let _ = self.eval_place(*place)?;
+ }
+
+ // This exists purely to guide borrowck lifetime inference, and does not have
+ // an operational effect.
+ AscribeUserType(..) => {}
// Currently, Miri discards Coverage statements. Coverage statements are only injected
// via an optional compile time MIR pass and have no side effects. Since Coverage
@@ -280,20 +286,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.write_immediate(*val, &dest)?;
}
- NullaryOp(null_op, ty) => {
+ NullaryOp(ref null_op, ty) => {
let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
let layout = self.layout_of(ty)?;
- if layout.is_unsized() {
+ if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() {
// FIXME: This should be a span_bug (#80742)
self.tcx.sess.delay_span_bug(
self.frame().current_span(),
- &format!("Nullary MIR operator called for unsized type {}", ty),
+ format!("{null_op:?} MIR operator called for unsized type {ty}"),
);
throw_inval!(SizeOfUnsizedType(ty));
}
let val = match null_op {
mir::NullOp::SizeOf => layout.size.bytes(),
mir::NullOp::AlignOf => layout.align.abi.bytes(),
+ mir::NullOp::OffsetOf(fields) => {
+ layout.offset_of_subfield(self, fields.iter().map(|f| f.index())).bytes()
+ }
};
self.write_scalar(Scalar::from_target_usize(val, self), &dest)?;
}
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index a07702f7d..586e8f063 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -83,8 +83,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
}
ty::FnDef(def_id, substs) => {
- let instance =
- self.resolve(ty::WithOptConstParam::unknown(def_id), substs)?;
+ let instance = self.resolve(def_id, substs)?;
(
FnVal::Instance(instance),
self.fn_abi_of_instance(instance, extra_args)?,
@@ -115,7 +114,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
- Drop { place, target, unwind } => {
+ Drop { place, target, unwind, replace: _ } => {
let frame = self.frame();
let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?;
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index bf2b4ee69..22bdd4d2c 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -14,7 +14,7 @@ where
T: TypeVisitable<TyCtxt<'tcx>>,
{
debug!("ensure_monomorphic_enough: ty={:?}", ty);
- if !ty.needs_subst() {
+ if !ty.has_param() {
return Ok(());
}
@@ -27,7 +27,7 @@ where
type BreakTy = FoundParam;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
- if !ty.needs_subst() {
+ if !ty.has_param() {
return ControlFlow::Continue(());
}
@@ -36,7 +36,7 @@ where
ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, ..)
| ty::FnDef(def_id, substs) => {
- let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id));
+ let instance = ty::InstanceDef::Item(def_id);
let unused_params = self.tcx.unused_generic_params(instance);
for (index, subst) in substs.into_iter().enumerate() {
let index = index
@@ -46,7 +46,7 @@ where
// are used and require substitution.
// Just in case there are closures or generators within this subst,
// recurse.
- if unused_params.is_used(index) && subst.needs_subst() {
+ if unused_params.is_used(index) && subst.has_param() {
return subst.visit_with(self);
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 93b5273e1..01b772899 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -38,16 +38,14 @@ macro_rules! throw_validation_failure {
msg.push_str(", but expected ");
write!(&mut msg, $($expected_fmt)*).unwrap();
)?
- let path = rustc_middle::ty::print::with_no_trimmed_paths!({
- let where_ = &$where;
- if !where_.is_empty() {
- let mut path = String::new();
- write_path(&mut path, where_);
- Some(path)
- } else {
- None
- }
- });
+ let where_ = &$where;
+ let path = if !where_.is_empty() {
+ let mut path = String::new();
+ write_path(&mut path, where_);
+ Some(path)
+ } else {
+ None
+ };
throw_ub!(ValidationFailure { path, msg })
}};
}
@@ -784,7 +782,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
Abi::Scalar(scalar_layout) => {
if !scalar_layout.is_uninit_valid() {
// There is something to check here.
- let scalar = self.read_scalar(op, "initiailized scalar value")?;
+ let scalar = self.read_scalar(op, "initialized scalar value")?;
self.visit_scalar(scalar, scalar_layout)?;
}
}
@@ -794,7 +792,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// the other must be init.
if !a_layout.is_uninit_valid() && !b_layout.is_uninit_valid() {
let (a, b) =
- self.read_immediate(op, "initiailized scalar value")?.to_scalar_pair();
+ self.read_immediate(op, "initialized scalar value")?.to_scalar_pair();
self.visit_scalar(a, a_layout)?;
self.visit_scalar(b, b_layout)?;
}
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 5ab389d04..c36282d5e 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -34,9 +34,9 @@ pub mod transform;
pub mod util;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
-use rustc_macros::fluent_messages;
+use rustc_fluent_macro::fluent_messages;
+use rustc_middle::query::Providers;
use rustc_middle::ty;
-use rustc_middle::ty::query::Providers;
fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 55080d94f..57d939747 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -556,7 +556,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::Cast(_, _, _) => {}
- Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
+ Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) => {}
Rvalue::ShallowInitBox(_, _) => {}
Rvalue::UnaryOp(_, operand) => {
@@ -872,7 +872,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
debug!("Resolving ({:?}) -> {:?}", callee, instance);
if let Ok(Some(func)) = instance {
if let InstanceDef::Item(def) = func.def {
- callee = def.did;
+ callee = def;
}
}
}
@@ -942,7 +942,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate)
};
let feature_gate_declared = gate_declared(gate);
- let implied_gate_declared = implied_by.map(gate_declared).unwrap_or(false);
+ let implied_gate_declared = implied_by.is_some_and(gate_declared);
if !feature_gate_declared && !implied_gate_declared {
self.check_op(ops::FnCallUnstable(callee, Some(gate)));
return;
@@ -969,7 +969,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// have no `rustc_const_stable` attributes to be const-unstable as well. This
// should be fixed later.
let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none()
- && tcx.lookup_stability(callee).map_or(false, |s| s.is_unstable());
+ && tcx.lookup_stability(callee).is_some_and(|s| s.is_unstable());
if callee_is_unstable_unmarked {
trace!("callee_is_unstable_unmarked");
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index 0e4501922..8ebfee887 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -139,5 +139,5 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
return false;
}
- tcx.lookup_const_stability(parent.owner).map_or(false, |stab| stab.is_const_stable())
+ tcx.lookup_const_stability(parent.owner).is_some_and(|stab| stab.is_const_stable())
}
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index c0f5b3725..21f3c2c89 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -14,6 +14,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
use rustc_middle::ty::{Binder, TraitRef};
+use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
use rustc_session::parse::feature_err;
use rustc_span::symbol::sym;
use rustc_span::{BytePos, Pos, Span, Symbol};
@@ -21,7 +22,6 @@ use rustc_trait_selection::traits::SelectionContext;
use super::ConstCx;
use crate::errors;
-use crate::util::{call_kind, CallDesugaringKind, CallKind};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Status {
@@ -77,7 +77,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
&ccx.tcx.sess.parse_sess,
sym::const_fn_floating_point_arithmetic,
span,
- &format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
+ format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
)
}
}
@@ -184,6 +184,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
CallDesugaringKind::TryBlockFromOutput => {
error!("`try` block cannot convert `{}` to the result in {}s")
}
+ CallDesugaringKind::Await => {
+ error!("cannot convert `{}` into a future in {}s")
+ }
};
diag_trait(&mut err, self_ty, kind.trait_def_id(tcx));
@@ -208,13 +211,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
err.span_note(span, "function defined here, but it is not `const`");
}
FnPtr(..) => {
- err.note(&format!(
+ err.note(format!(
"function pointers need an RFC before allowed to be called in {}s",
ccx.const_kind()
));
}
Closure(..) => {
- err.note(&format!(
+ err.note(format!(
"closures need an RFC before allowed to be called in {}s",
ccx.const_kind()
));
@@ -286,7 +289,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
ccx.const_kind()
);
- err.note(&format!("attempting to deref into `{}`", deref_target_ty));
+ err.note(format!("attempting to deref into `{}`", deref_target_ty));
// Check first whether the source is accessible (issue #87060)
if tcx.sess.source_map().is_span_accessible(deref_target) {
@@ -296,7 +299,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
diag_trait(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, Some(span)));
err
}
- _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => ccx
+ _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentMethods) => ccx
.tcx
.sess
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
@@ -307,14 +310,14 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}),
};
- err.note(&format!(
+ err.note(format!(
"calls in {}s are limited to constant functions, \
tuple structs and tuple variants",
ccx.const_kind(),
));
if let Some(feature) = feature && ccx.tcx.sess.is_nightly_build() {
- err.help(&format!(
+ err.help(format!(
"add `#![feature({})]` to the crate attributes to enable",
feature,
));
@@ -351,7 +354,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
err.help("const-stable functions can only call other const-stable functions");
} else if ccx.tcx.sess.is_nightly_build() {
if let Some(feature) = feature {
- err.help(&format!(
+ err.help(format!(
"add `#![feature({})]` to the crate attributes to enable",
feature
));
@@ -610,10 +613,11 @@ pub struct RawPtrComparison;
impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
fn build_error(
&self,
- _: &ConstCx<'_, 'tcx>,
+ ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- span_bug!(span, "raw ptr comparison should already be caught in the trait system");
+ // FIXME(const_trait_impl): revert to span_bug?
+ ccx.tcx.sess.create_err(errors::RawPtrComparisonErr { span })
}
}
@@ -633,7 +637,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
span,
- &format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
+ format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
)
}
}
@@ -720,7 +724,7 @@ pub mod ty {
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
span,
- &format!("mutable references are not allowed in {}s", ccx.const_kind()),
+ format!("mutable references are not allowed in {}s", ccx.const_kind()),
)
}
}
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 6758cba2e..1da205790 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -157,7 +157,7 @@ impl Qualif for NeedsNonConstDrop {
cx.tcx,
ObligationCause::dummy_with_span(cx.body.span),
cx.param_env,
- ty::Binder::dummy(cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, [ty]))
+ ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty])
.with_constness(ty::BoundConstness::ConstIfConst),
);
@@ -364,9 +364,8 @@ where
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
// Don't peek inside trait associated constants.
- if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
- assert_eq!(def.const_param_did, None, "expected associated const: {def:?}");
- let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did);
+ if promoted.is_none() && cx.tcx.trait_of_item(def).is_none() {
+ let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def);
if !Q::in_qualifs(&qualifs) {
return false;
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 7919aed09..0e2d9ee8f 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -21,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
-use rustc_index::vec::{Idx, IndexSlice, IndexVec};
+use rustc_index::{Idx, IndexSlice, IndexVec};
use std::cell::Cell;
use std::{cmp, iter, mem};
@@ -514,6 +514,7 @@ impl<'tcx> Validator<'_, 'tcx> {
Rvalue::NullaryOp(op, _) => match op {
NullOp::SizeOf => {}
NullOp::AlignOf => {}
+ NullOp::OffsetOf(_) => {}
},
Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
@@ -828,7 +829,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}
fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
- let def = self.source.source.with_opt_param();
+ let def = self.source.source.def_id();
let mut rvalue = {
let promoted = &mut self.promoted;
let promoted_id = Promoted::new(next_promoted_id);
@@ -836,7 +837,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let mut promoted_operand = |ty, span| {
promoted.span = span;
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
- let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
+ let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def));
let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) };
Operand::Constant(Box::new(Constant {
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index d4bed9738..3c350e25b 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -2,15 +2,16 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::bit_set::BitSet;
-use rustc_index::vec::IndexVec;
+use rustc_index::IndexVec;
use rustc_infer::traits::Reveal;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{
traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
- MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
- RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
- TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, START_BLOCK,
+ MirPass, MirPhase, NonDivergingIntrinsic, NullOp, Operand, Place, PlaceElem, PlaceRef,
+ ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
+ Terminator, TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents,
+ START_BLOCK,
};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
use rustc_mir_dataflow::impls::MaybeStorageLive;
@@ -106,7 +107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// occurred.
self.tcx.sess.diagnostic().delay_span_bug(
span,
- &format!(
+ format!(
"broken MIR in {:?} ({}) at {:?}:\n{}",
self.body.source.instance,
self.when,
@@ -163,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Some(root) = post_contract_node.get(&bb) {
break *root;
}
- let parent = doms.immediate_dominator(bb);
+ let parent = doms.immediate_dominator(bb).unwrap();
dom_path.push(bb);
if !self.body.basic_blocks[parent].is_cleanup {
break bb;
@@ -262,7 +263,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// We sometimes have to use `defining_opaque_types` for subtyping
// to succeed here and figuring out how exactly that should work
// is annoying. It is harmless enough to just not validate anything
- // in that case. We still check this after analysis as all opque
+ // in that case. We still check this after analysis as all opaque
// types have been revealed at this point.
if (src, dest).has_opaque_types() {
return true;
@@ -447,7 +448,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
match debuginfo.value {
VarDebugInfoContents::Const(_) => {}
- VarDebugInfoContents::Place(place) => check_place(place),
+ VarDebugInfoContents::Place(place) => {
+ check_place(place);
+ if debuginfo.references != 0 && place.projection.last() == Some(&PlaceElem::Deref) {
+ self.fail(
+ START_BLOCK.start_location(),
+ format!("debuginfo {:?}, has both ref and deref", debuginfo),
+ );
+ }
+ }
VarDebugInfoContents::Composite { ty, ref fragments } => {
for f in fragments {
check_place(f.contents);
@@ -711,10 +720,54 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
}
+ Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => {
+ let fail_out_of_bounds = |this: &Self, location, field, ty| {
+ this.fail(location, format!("Out of bounds field {field:?} for {ty:?}"));
+ };
+
+ let mut current_ty = *container;
+
+ for field in fields.iter() {
+ match current_ty.kind() {
+ ty::Tuple(fields) => {
+ let Some(&f_ty) = fields.get(field.as_usize()) else {
+ fail_out_of_bounds(self, location, field, current_ty);
+ return;
+ };
+
+ current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
+ }
+ ty::Adt(adt_def, substs) => {
+ if adt_def.is_enum() {
+ self.fail(
+ location,
+ format!("Cannot get field offset from enum {current_ty:?}"),
+ );
+ return;
+ }
+
+ let Some(field) = adt_def.non_enum_variant().fields.get(field) else {
+ fail_out_of_bounds(self, location, field, current_ty);
+ return;
+ };
+
+ let f_ty = field.ty(self.tcx, substs);
+ current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
+ }
+ _ => {
+ self.fail(
+ location,
+ format!("Cannot get field offset from non-adt type {current_ty:?}"),
+ );
+ return;
+ }
+ }
+ }
+ }
Rvalue::Repeat(_, _)
| Rvalue::ThreadLocalRef(_)
| Rvalue::AddressOf(_, _)
- | Rvalue::NullaryOp(_, _)
+ | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
| Rvalue::Discriminant(_) => {}
}
self.super_rvalue(rvalue, location);
@@ -757,14 +810,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
}
- StatementKind::PlaceMention(..) => {
- if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
- self.fail(
- location,
- "`PlaceMention` should have been removed after drop lowering phase",
- );
- }
- }
StatementKind::AscribeUserType(..) => {
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
@@ -874,6 +919,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
StatementKind::StorageDead(_)
| StatementKind::Coverage(_)
| StatementKind::ConstEvalCounter
+ | StatementKind::PlaceMention(..)
| StatementKind::Nop => {}
}
@@ -1056,7 +1102,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
if self.body.source_scopes.get(scope).is_none() {
self.tcx.sess.diagnostic().delay_span_bug(
self.body.span,
- &format!(
+ format!(
"broken MIR in {:?} ({}):\ninvalid source scope {:?}",
self.body.source.instance, self.when, scope,
),
diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs
deleted file mode 100644
index 995363c0e..000000000
--- a/compiler/rustc_const_eval/src/util/call_kind.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-//! Common logic for borrowck use-after-move errors when moved into a `fn(self)`,
-//! as well as errors when attempting to call a non-const function in a const
-//! context.
-
-use rustc_hir::def_id::DefId;
-use rustc_hir::{lang_items, LangItem};
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt};
-use rustc_span::symbol::Ident;
-use rustc_span::{sym, DesugaringKind, Span};
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum CallDesugaringKind {
- /// for _ in x {} calls x.into_iter()
- ForLoopIntoIter,
- /// x? calls x.branch()
- QuestionBranch,
- /// x? calls type_of(x)::from_residual()
- QuestionFromResidual,
- /// try { ..; x } calls type_of(x)::from_output(x)
- TryBlockFromOutput,
-}
-
-impl CallDesugaringKind {
- pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId {
- match self {
- Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(),
- Self::QuestionBranch | Self::TryBlockFromOutput => {
- tcx.require_lang_item(LangItem::Try, None)
- }
- Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(),
- }
- }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum CallKind<'tcx> {
- /// A normal method call of the form `receiver.foo(a, b, c)`
- Normal {
- self_arg: Option<Ident>,
- desugaring: Option<(CallDesugaringKind, Ty<'tcx>)>,
- method_did: DefId,
- method_substs: SubstsRef<'tcx>,
- },
- /// A call to `Fn(..)::call(..)`, desugared from `my_closure(a, b, c)`
- FnCall { fn_trait_id: DefId, self_ty: Ty<'tcx> },
- /// A call to an operator trait, desugared from operator syntax (e.g. `a << b`)
- Operator { self_arg: Option<Ident>, trait_id: DefId, self_ty: Ty<'tcx> },
- DerefCoercion {
- /// The `Span` of the `Target` associated type
- /// in the `Deref` impl we are using.
- deref_target: Span,
- /// The type `T::Deref` we are dereferencing to
- deref_target_ty: Ty<'tcx>,
- self_ty: Ty<'tcx>,
- },
-}
-
-pub fn call_kind<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- method_did: DefId,
- method_substs: SubstsRef<'tcx>,
- fn_call_span: Span,
- from_hir_call: bool,
- self_arg: Option<Ident>,
-) -> CallKind<'tcx> {
- let parent = tcx.opt_associated_item(method_did).and_then(|assoc| {
- let container_id = assoc.container_id(tcx);
- match assoc.container {
- AssocItemContainer::ImplContainer => tcx.trait_id_of_impl(container_id),
- AssocItemContainer::TraitContainer => Some(container_id),
- }
- });
-
- let fn_call = parent.and_then(|p| {
- lang_items::FN_TRAITS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p)
- });
-
- let operator = if !from_hir_call && let Some(p) = parent {
- lang_items::OPERATORS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p)
- } else {
- None
- };
-
- let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did);
-
- // Check for a 'special' use of 'self' -
- // an FnOnce call, an operator (e.g. `<<`), or a
- // deref coercion.
- let kind = if let Some(trait_id) = fn_call {
- Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_substs.type_at(0) })
- } else if let Some(trait_id) = operator {
- Some(CallKind::Operator { self_arg, trait_id, self_ty: method_substs.type_at(0) })
- } else if is_deref {
- let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
- Instance::resolve(tcx, param_env, deref_target, method_substs).transpose()
- });
- if let Some(Ok(instance)) = deref_target {
- let deref_target_ty = instance.ty(tcx, param_env);
- Some(CallKind::DerefCoercion {
- deref_target: tcx.def_span(instance.def_id()),
- deref_target_ty,
- self_ty: method_substs.type_at(0),
- })
- } else {
- None
- }
- } else {
- None
- };
-
- kind.unwrap_or_else(|| {
- // This isn't a 'special' use of `self`
- debug!(?method_did, ?fn_call_span);
- let desugaring = if Some(method_did) == tcx.lang_items().into_iter_fn()
- && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
- {
- Some((CallDesugaringKind::ForLoopIntoIter, method_substs.type_at(0)))
- } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
- if Some(method_did) == tcx.lang_items().branch_fn() {
- Some((CallDesugaringKind::QuestionBranch, method_substs.type_at(0)))
- } else if Some(method_did) == tcx.lang_items().from_residual_fn() {
- Some((CallDesugaringKind::QuestionFromResidual, method_substs.type_at(0)))
- } else {
- None
- }
- } else if Some(method_did) == tcx.lang_items().from_output_fn()
- && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
- {
- Some((CallDesugaringKind::TryBlockFromOutput, method_substs.type_at(0)))
- } else {
- None
- };
- CallKind::Normal { self_arg, desugaring, method_did, method_substs }
- })
-}
diff --git a/compiler/rustc_const_eval/src/util/collect_writes.rs b/compiler/rustc_const_eval/src/util/collect_writes.rs
deleted file mode 100644
index 8d92bb359..000000000
--- a/compiler/rustc_const_eval/src/util/collect_writes.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use rustc_middle::mir::visit::PlaceContext;
-use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{Body, Local, Location};
-
-pub trait FindAssignments {
- // Finds all statements that assign directly to local (i.e., X = ...)
- // and returns their locations.
- fn find_assignments(&self, local: Local) -> Vec<Location>;
-}
-
-impl<'tcx> FindAssignments for Body<'tcx> {
- fn find_assignments(&self, local: Local) -> Vec<Location> {
- let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] };
- visitor.visit_body(self);
- visitor.locations
- }
-}
-
-// The Visitor walks the MIR to return the assignment statements corresponding
-// to a Local.
-struct FindLocalAssignmentVisitor {
- needle: Local,
- locations: Vec<Location>,
-}
-
-impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor {
- fn visit_local(&mut self, local: Local, place_context: PlaceContext, location: Location) {
- if self.needle != local {
- return;
- }
-
- if place_context.is_place_assignment() {
- self.locations.push(location);
- }
- }
-}
diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs
index f5f3d5de6..d6a2ffb75 100644
--- a/compiler/rustc_const_eval/src/util/compare_types.rs
+++ b/compiler/rustc_const_eval/src/util/compare_types.rs
@@ -3,8 +3,8 @@
//! FIXME: Move this to a more general place. The utility of this extends to
//! other areas of the compiler as well.
-use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
-use rustc_infer::traits::ObligationCause;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::traits::{DefiningAnchor, ObligationCause};
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
use rustc_trait_selection::traits::ObligationCtxt;
diff --git a/compiler/rustc_const_eval/src/util/find_self_call.rs b/compiler/rustc_const_eval/src/util/find_self_call.rs
deleted file mode 100644
index 33ad128ee..000000000
--- a/compiler/rustc_const_eval/src/util/find_self_call.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use rustc_middle::mir::*;
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_span::def_id::DefId;
-
-/// Checks if the specified `local` is used as the `self` parameter of a method call
-/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is
-/// returned.
-pub fn find_self_call<'tcx>(
- tcx: TyCtxt<'tcx>,
- body: &Body<'tcx>,
- local: Local,
- block: BasicBlock,
-) -> Option<(DefId, SubstsRef<'tcx>)> {
- debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator);
- if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
- &body[block].terminator
- {
- debug!("find_self_call: func={:?}", func);
- if let Operand::Constant(box Constant { literal, .. }) = func {
- if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
- if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
- tcx.opt_associated_item(def_id)
- {
- debug!("find_self_call: args={:?}", args);
- if let [Operand::Move(self_place) | Operand::Copy(self_place), ..] = **args {
- if self_place.as_local() == Some(local) {
- return Some((def_id, substs));
- }
- }
- }
- }
- }
- }
- None
-}
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index c0aabd77c..7641f5607 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -1,14 +1,9 @@
mod alignment;
-mod call_kind;
mod check_validity_requirement;
-pub mod collect_writes;
mod compare_types;
-mod find_self_call;
mod type_name;
pub use self::alignment::is_disaligned;
-pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind};
pub use self::check_validity_requirement::check_validity_requirement;
pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
-pub use self::find_self_call::find_self_call;
pub use self::type_name::type_name;
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index 4e80a2851..11ad5b49d 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -58,11 +58,12 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
// Types with identity (print the module path).
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
| ty::FnDef(def_id, substs)
- | ty::Alias(_, ty::AliasTy { def_id, substs, .. })
+ | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
| ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
+ ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"),
}