diff options
Diffstat (limited to '')
5 files changed, 37 insertions, 121 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 09d53331b..4977a5d6b 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -2,7 +2,6 @@ use std::error::Error; use std::fmt; use rustc_errors::Diagnostic; -use rustc_hir as hir; use rustc_middle::mir::AssertKind; use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt}; use rustc_span::{Span, Symbol}; @@ -23,11 +22,7 @@ pub enum ConstEvalErrKind { Abort(String), } -impl MachineStopType for ConstEvalErrKind { - fn is_hard_err(&self) -> bool { - matches!(self, Self::Panic { .. }) - } -} +impl MachineStopType for ConstEvalErrKind {} // The errors become `MachineStop` with plain strings when being raised. // `ConstEvalErr` (in `librustc_middle/mir/interpret/error.rs`) knows to @@ -69,7 +64,7 @@ pub struct ConstEvalErr<'tcx> { impl<'tcx> ConstEvalErr<'tcx> { /// Turn an interpreter error into something to report to the user. /// As a side-effect, if RUSTC_CTFE_BACKTRACE is set, this prints the backtrace. - /// Should be called only if the error is actually going to to be reported! + /// Should be called only if the error is actually going to be reported! pub fn new<'mir, M: Machine<'mir, 'tcx>>( ecx: &InterpCx<'mir, 'tcx, M>, error: InterpErrorInfo<'tcx>, @@ -87,48 +82,10 @@ impl<'tcx> ConstEvalErr<'tcx> { ConstEvalErr { error: error.into_kind(), stacktrace, span } } - pub fn struct_error( - &self, - tcx: TyCtxtAt<'tcx>, - message: &str, - decorate: impl FnOnce(&mut Diagnostic), - ) -> ErrorHandled { - self.struct_generic(tcx, message, decorate, None) - } - pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled { self.struct_error(tcx, message, |_| {}) } - pub fn report_as_lint( - &self, - tcx: TyCtxtAt<'tcx>, - message: &str, - lint_root: hir::HirId, - span: Option<Span>, - ) -> ErrorHandled { - self.struct_generic( - tcx, - message, - |lint: &mut Diagnostic| { - // Apply the span. - if let Some(span) = span { - let primary_spans = lint.span.primary_spans().to_vec(); - // point at the actual error as the primary span - lint.replace_span_with(span); - // point to the `const` statement as a secondary span - // they don't have any label - for sp in primary_spans { - if sp != span { - lint.span_label(sp, ""); - } - } - } - }, - Some(lint_root), - ) - } - /// Create a diagnostic for this const eval error. /// /// Sets the message passed in via `message` and adds span labels with detailed error @@ -137,13 +94,12 @@ impl<'tcx> ConstEvalErr<'tcx> { /// /// If `lint_root.is_some()` report it as a lint, else report it as a hard error. /// (Except that for some errors, we ignore all that -- see `must_error` below.) - #[instrument(skip(self, tcx, decorate, lint_root), level = "debug")] - fn struct_generic( + #[instrument(skip(self, tcx, decorate), level = "debug")] + pub fn struct_error( &self, tcx: TyCtxtAt<'tcx>, message: &str, decorate: impl FnOnce(&mut Diagnostic), - lint_root: Option<hir::HirId>, ) -> ErrorHandled { let finish = |err: &mut Diagnostic, span_msg: Option<String>| { trace!("reporting const eval failure at {:?}", self.span); @@ -224,27 +180,9 @@ impl<'tcx> ConstEvalErr<'tcx> { let err_msg = self.error.to_string(); - // Regular case - emit a lint. - if let Some(lint_root) = lint_root { - // Report as lint. - let hir_id = - self.stacktrace.iter().rev().find_map(|frame| frame.lint_root).unwrap_or(lint_root); - tcx.struct_span_lint_hir( - rustc_session::lint::builtin::CONST_ERR, - hir_id, - tcx.span, - |lint| { - let mut lint = lint.build(message); - finish(&mut lint, Some(err_msg)); - lint.emit(); - }, - ); - ErrorHandled::Linted - } else { - // Report as hard error. - let mut err = struct_error(tcx, message); - finish(&mut err, Some(err_msg)); - ErrorHandled::Reported(err.emit()) - } + // Report as hard error. + let mut err = struct_error(tcx, message); + finish(&mut err, Some(err_msg)); + ErrorHandled::Reported(err.emit()) } } 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 a2f14e753..1b1052fdf 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::pretty::display_allocation; use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, subst::Subst, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::source_map::Span; use rustc_target::abi::{self, Abi}; use std::borrow::Cow; @@ -317,45 +317,23 @@ pub fn eval_to_allocation_raw_provider<'tcx>( match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) { Err(error) => { let err = ConstEvalErr::new(&ecx, error, None); - // Some CTFE errors raise just a lint, not a hard error; see - // <https://github.com/rust-lang/rust/issues/71800>. - let is_hard_err = if let Some(def) = def.as_local() { - // (Associated) consts only emit a lint, since they might be unused. - !matches!(tcx.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) - // check if the inner InterpError is hard - || err.error.is_hard_err() + let msg = if is_static { + Cow::from("could not evaluate static initializer") } else { - // use of broken constant from other crate: always an error - true - }; - - if is_hard_err { - let msg = if is_static { - Cow::from("could not evaluate static initializer") + // If the current item has generics, we'd like to enrich the message with the + // instance and its substs: to show the actual compile-time values, in addition to + // the expression, leading to the const eval error. + let instance = &key.value.instance; + if !instance.substs.is_empty() { + let instance = with_no_trimmed_paths!(instance.to_string()); + let msg = format!("evaluation of `{}` failed", instance); + Cow::from(msg) } else { - // If the current item has generics, we'd like to enrich the message with the - // instance and its substs: to show the actual compile-time values, in addition to - // the expression, leading to the const eval error. - let instance = &key.value.instance; - if !instance.substs.is_empty() { - let instance = with_no_trimmed_paths!(instance.to_string()); - let msg = format!("evaluation of `{}` failed", instance); - Cow::from(msg) - } else { - Cow::from("evaluation of constant value failed") - } - }; + Cow::from("evaluation of constant value failed") + } + }; - Err(err.report_as_error(ecx.tcx.at(err.span), &msg)) - } else { - let hir_id = tcx.hir().local_def_id_to_hir_id(def.as_local().unwrap().did); - Err(err.report_as_lint( - tcx.at(tcx.def_span(def.did)), - "any use of this value will cause an error", - hir_id, - Some(err.span), - )) - } + Err(err.report_as_error(ecx.tcx.at(err.span), &msg)) } Ok(mplace) => { // Since evaluation had no errors, validate the resulting constant. diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index e5acacd91..35d58d2f6 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -2,10 +2,10 @@ use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use std::borrow::Borrow; -use std::collections::hash_map::Entry; use std::hash::Hash; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::IndexEntry; use std::fmt; use rustc_ast::Mutability; @@ -107,18 +107,18 @@ impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { } } -impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> { +impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> { #[inline(always)] fn contains_key<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> bool where K: Borrow<Q>, { - FxHashMap::contains_key(self, k) + FxIndexMap::contains_key(self, k) } #[inline(always)] fn insert(&mut self, k: K, v: V) -> Option<V> { - FxHashMap::insert(self, k, v) + FxIndexMap::insert(self, k, v) } #[inline(always)] @@ -126,7 +126,7 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> { where K: Borrow<Q>, { - FxHashMap::remove(self, k) + FxIndexMap::remove(self, k) } #[inline(always)] @@ -148,8 +148,8 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> { #[inline(always)] fn get_mut_or<E>(&mut self, k: K, vacant: impl FnOnce() -> Result<V, E>) -> Result<&mut V, E> { match self.entry(k) { - Entry::Occupied(e) => Ok(e.into_mut()), - Entry::Vacant(e) => { + IndexEntry::Occupied(e) => Ok(e.into_mut()), + IndexEntry::Vacant(e) => { let v = vacant()?; Ok(e.insert(v)) } diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index d9c4ae4d5..1c33e7845 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -100,10 +100,10 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, val: mir::ConstantKind<'tcx>, -) -> InterpResult<'tcx, mir::DestructuredMirConstant<'tcx>> { +) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { trace!("destructure_mir_constant: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.mir_const_to_op(&val, None)?; + let op = ecx.const_to_op(&val, None)?; // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { @@ -129,7 +129,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( .collect::<InterpResult<'tcx, Vec<_>>>()?; let fields = tcx.arena.alloc_from_iter(fields_iter); - Ok(mir::DestructuredMirConstant { variant, fields }) + Ok(mir::DestructuredConstant { variant, fields }) } #[instrument(skip(tcx), level = "debug")] @@ -139,7 +139,7 @@ pub(crate) fn deref_mir_constant<'tcx>( val: mir::ConstantKind<'tcx>, ) -> mir::ConstantKind<'tcx> { let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.mir_const_to_op(&val, None).unwrap(); + let op = ecx.const_to_op(&val, None).unwrap(); let mplace = ecx.deref_operand(&op).unwrap(); if let Some(alloc_id) = mplace.ptr.provenance { assert_eq!( diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index a964fe846..f4da11883 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -212,7 +212,7 @@ fn create_pointee_place<'tcx>( ) -> MPlaceTy<'tcx> { let tcx = ecx.tcx.tcx; - if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty()) { + if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) { // We need to create `Allocation`s for custom DSTs let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx); @@ -398,7 +398,7 @@ fn valtree_into_mplace<'tcx>( let mut place_inner = match ty.kind() { ty::Str | ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(), - _ if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty()) + _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) && i == branches.len() - 1 => { // Note: For custom DSTs we need to manually process the last unsized field. |