diff options
author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2023-05-15 00:00:00 +0000 |
---|---|---|
committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2023-05-15 00:00:00 +0000 |
commit | 67f455afe1496a46171099b711bf067d7095395b (patch) | |
tree | 71cb7409230acfa927effbe86d26ac9eee4e2aa0 /compiler | |
parent | 2913ad6db0f72fed5139253faed73200c7af3535 (diff) | |
download | rust-67f455afe1496a46171099b711bf067d7095395b.tar.gz |
Suppress "erroneous constant used" for constants tainted by errors
When constant evaluation fails because its MIR is tainted by errors,
suppress note indicating that erroneous constant was used, since those
errors have to be fixed regardless of the constant being used or not.
Diffstat (limited to 'compiler')
13 files changed, 60 insertions, 26 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index cdef3fb2339..5037c210e7d 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -169,14 +169,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/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 814b67b46ec..58b5755af07 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -382,7 +382,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 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. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index b2197a0aabb..2fa63dc8c93 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,7 +7,7 @@ use either::{Either, Left, Right}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; 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::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, @@ -470,7 +470,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // 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) } @@ -517,7 +517,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { 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())), } } @@ -905,7 +905,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"); } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index a7f66071fe2..e30af165501 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -595,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_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 9a95a9c8375..d49a69dfba5 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1533,7 +1533,7 @@ impl<'tcx> InferCtxt<'tcx> { if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? { let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs)); if let Err(e) = ct.error_reported() { - return Err(ErrorHandled::Reported(e)); + return Err(ErrorHandled::Reported(e.into())); } else if ct.has_non_region_infer() || ct.has_non_region_param() { return Err(ErrorHandled::TooGeneric); } else { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index e45284ca506..d65ceef2472 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -15,15 +15,49 @@ use std::{any::Any, backtrace::Backtrace, fmt}; pub enum ErrorHandled { /// Already reported an error for this evaluation, and the compilation is /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. - Reported(ErrorGuaranteed), + Reported(ReportedErrorInfo), /// Don't emit an error, the evaluation failed because the MIR was generic /// and the substs didn't fully monomorphize it. TooGeneric, } impl From<ErrorGuaranteed> for ErrorHandled { - fn from(err: ErrorGuaranteed) -> ErrorHandled { - ErrorHandled::Reported(err) + #[inline] + fn from(error: ErrorGuaranteed) -> ErrorHandled { + ErrorHandled::Reported(error.into()) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub struct ReportedErrorInfo { + error: ErrorGuaranteed, + is_tainted_by_errors: bool, +} + +impl ReportedErrorInfo { + #[inline] + pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { is_tainted_by_errors: true, error } + } + + /// Returns true if evaluation failed because MIR was tainted by errors. + #[inline] + pub fn is_tainted_by_errors(self) -> bool { + self.is_tainted_by_errors + } +} + +impl From<ErrorGuaranteed> for ReportedErrorInfo { + #[inline] + fn from(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { is_tainted_by_errors: false, error } + } +} + +impl Into<ErrorGuaranteed> for ReportedErrorInfo { + #[inline] + fn into(self) -> ErrorGuaranteed { + self.error } } @@ -89,7 +123,7 @@ fn print_backtrace(backtrace: &Backtrace) { impl From<ErrorGuaranteed> for InterpErrorInfo<'_> { fn from(err: ErrorGuaranteed) -> Self { - InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into() + InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into() } } @@ -125,7 +159,7 @@ pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context. TooGeneric, /// Abort in case errors are already reported. - AlreadyReported(ErrorGuaranteed), + AlreadyReported(ReportedErrorInfo), /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), /// An error occurred during FnAbi computation: the passed --target lacks FFI support @@ -144,7 +178,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { use InvalidProgramInfo::*; match self { TooGeneric => write!(f, "encountered overly generic constant"), - AlreadyReported(ErrorGuaranteed { .. }) => { + AlreadyReported(_) => { write!( f, "an error has already been reported elsewhere (this should not usually be printed)" diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index e5a9766c84d..3620385fab1 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -120,8 +120,8 @@ use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, - MachineStopType, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, - UninitBytesAccess, UnsupportedOpInfo, + MachineStopType, ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, + UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, }; pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar}; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index ed4ee93e97d..ce11dabc195 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -61,7 +61,7 @@ impl<'tcx> TyCtxt<'tcx> { self.const_eval_global_id(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), - Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + Err(err) => Err(ErrorHandled::Reported(err.into())), } } @@ -110,7 +110,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } Ok(None) => Err(ErrorHandled::TooGeneric), - Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + Err(err) => Err(ErrorHandled::Reported(err.into())), } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 2f18b6cc90a..1da94dd7917 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2342,7 +2342,7 @@ impl<'tcx> ConstantKind<'tcx> { match tcx.const_eval_resolve(param_env, uneval, None) { Ok(val) => Self::Val(val, ty), Err(ErrorHandled::TooGeneric) => self, - Err(ErrorHandled::Reported(guar)) => Self::Ty(tcx.const_error(ty, guar)), + Err(ErrorHandled::Reported(guar)) => Self::Ty(tcx.const_error(ty, guar.into())), } } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 1ac2cd13982..a108f6c8947 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -245,7 +245,7 @@ impl<'tcx> ConstKind<'tcx> { // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ValTree(val?))), Err(ErrorHandled::TooGeneric) => None, - Err(ErrorHandled::Reported(e)) => Some(Err(e)), + Err(ErrorHandled::Reported(e)) => Some(Err(e.into())), } } EvalMode::Mir => { @@ -256,7 +256,7 @@ impl<'tcx> ConstKind<'tcx> { // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ConstVal(val))), Err(ErrorHandled::TooGeneric) => None, - Err(ErrorHandled::Reported(e)) => Some(Err(e)), + Err(ErrorHandled::Reported(e)) => Some(Err(e.into())), } } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6b080a132f3..183c2401fc3 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -801,7 +801,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { span: tcx.def_span(unevaluated.def), unevaluated: unevaluated, }); - Err(ErrorHandled::Reported(reported)) + Err(ErrorHandled::Reported(reported.into())) } Err(err) => Err(err), } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 9d99d30d45c..bd1ea43a78e 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -79,7 +79,7 @@ pub fn is_const_evaluatable<'tcx>( "Missing value for constant, but no error reported?", ))) } - Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Ok(_) => Ok(()), } } @@ -147,7 +147,7 @@ pub fn is_const_evaluatable<'tcx>( Err(err) } - Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Ok(_) => Ok(()), } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 43196d1e629..2f85c32b575 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -615,7 +615,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { (Err(ErrorHandled::Reported(reported)), _) | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( CodeSelectionError(SelectionError::NotConstEvaluatable( - NotConstEvaluatable::Error(reported), + NotConstEvaluatable::Error(reported.into()), )), ), (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { |