Skip to content

Commit

Permalink
Rollup merge of rust-lang#111602 - tmiasko:erroneous-constant-used, r…
Browse files Browse the repository at this point in the history
…=oli-obk

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.

Fixes rust-lang#110891.
  • Loading branch information
Noratrieb authored May 16, 2023
2 parents e620b29 + 67f455a commit 0ae644d
Show file tree
Hide file tree
Showing 33 changed files with 76 additions and 248 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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())),
}
}

Expand Down Expand Up @@ -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");
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1534,7 +1534,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 {
Expand Down
46 changes: 40 additions & 6 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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()
}
}

Expand Down Expand Up @@ -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
Expand All @@ -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)"
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())),
}
}

Expand Down Expand Up @@ -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())),
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/consts/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -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())),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(()),
}
}
Expand Down Expand Up @@ -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(()),
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) => {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ pub fn report_error<'tcx, 'mir>(
(None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
],
InvalidProgram(
InvalidProgramInfo::AlreadyReported(rustc_errors::ErrorGuaranteed { .. })
InvalidProgramInfo::AlreadyReported(_)
) => {
// This got already reported. No point in reporting it again.
return None;
Expand Down
1 change: 0 additions & 1 deletion src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ extern crate rustc_ast;
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
Expand Down
56 changes: 0 additions & 56 deletions tests/ui/consts/const-eval/format.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -43,62 +43,6 @@ LL | println!("{:?}", 0);
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
--> $DIR/format.rs:2:12
|
LL | panic!("{:?}", 0);
| ^^^^^^

note: erroneous constant used
--> $DIR/format.rs:2:12
|
LL | panic!("{:?}", 0);
| ^^^^^^

note: erroneous constant used
--> $DIR/format.rs:2:20
|
LL | panic!("{:?}", 0);
| ^
|
= note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
--> $DIR/format.rs:2:20
|
LL | panic!("{:?}", 0);
| ^
|
= note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
--> $DIR/format.rs:8:14
|
LL | println!("{:?}", 0);
| ^^^^^^

note: erroneous constant used
--> $DIR/format.rs:8:14
|
LL | println!("{:?}", 0);
| ^^^^^^

note: erroneous constant used
--> $DIR/format.rs:8:22
|
LL | println!("{:?}", 0);
| ^
|
= note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
--> $DIR/format.rs:8:22
|
LL | println!("{:?}", 0);
| ^
|
= note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0015`.
10 changes: 0 additions & 10 deletions tests/ui/consts/const-integer-bool-ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const X: usize = 42 && 39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR: [i32; X] = [99; 34];
//~^ constant

const X1: usize = 42 || 39;
//~^ ERROR mismatched types
Expand All @@ -16,7 +15,6 @@ const X1: usize = 42 || 39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR1: [i32; X1] = [99; 47];
//~^ constant

const X2: usize = -42 || -39;
//~^ ERROR mismatched types
Expand All @@ -26,7 +24,6 @@ const X2: usize = -42 || -39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR2: [i32; X2] = [99; 18446744073709551607];
//~^ constant

const X3: usize = -42 && -39;
//~^ ERROR mismatched types
Expand All @@ -36,43 +33,36 @@ const X3: usize = -42 && -39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR3: [i32; X3] = [99; 6];
//~^ constant

const Y: usize = 42.0 == 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR: [i32; Y] = [99; 1];
//~^ constant

const Y1: usize = 42.0 >= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR1: [i32; Y1] = [99; 1];
//~^ constant

const Y2: usize = 42.0 <= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR2: [i32; Y2] = [99; 1];
//~^ constant

const Y3: usize = 42.0 > 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR3: [i32; Y3] = [99; 0];
//~^ constant

const Y4: usize = 42.0 < 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR4: [i32; Y4] = [99; 0];
//~^ constant

const Y5: usize = 42.0 != 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR5: [i32; Y5] = [99; 0];
//~^ constant

fn main() {
let _ = ARR;
Expand Down
Loading

0 comments on commit 0ae644d

Please sign in to comment.