diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 9a6c45ae98d5f..8ffb59a6dd642 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -64,6 +64,12 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { err ); } + ErrorHandled::Silent(_) => { + span_bug!( + constant.span, + "codegen encountered silent error", + ); + } } } } diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 205498acc3187..5e374b7db2776 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -334,7 +334,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: &Alloca cx.const_struct(&llvals, true) } -pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId) -> Result<(RValue<'gcc>, &'tcx Allocation), ErrorHandled> { +pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId) -> Result<(RValue<'gcc>, &'tcx Allocation), ErrorHandled<'tcx>> { let alloc = cx.tcx.eval_static_initializer(def_id)?; Ok((const_alloc_to_gcc(cx, alloc), alloc)) } diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index d43c7c6065179..168b983a95817 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -130,7 +130,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> pub fn codegen_static_initializer<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, def_id: DefId, -) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> { +) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled<'tcx>> { let alloc = cx.tcx.eval_static_initializer(def_id)?; Ok((const_alloc_to_llvm(cx, alloc), alloc)) } diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 93b39dc8e9ee1..faca33a736dd3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -14,7 +14,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &self, bx: &mut Bx, constant: &mir::Constant<'tcx>, - ) -> Result, ErrorHandled> { + ) -> Result, ErrorHandled<'tcx>> { let val = self.eval_mir_constant(constant)?; let ty = self.monomorphize(constant.ty()); Ok(OperandRef::from_const(bx, val, ty)) @@ -23,7 +23,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_mir_constant( &self, constant: &mir::Constant<'tcx>, - ) -> Result, ErrorHandled> { + ) -> Result, ErrorHandled<'tcx>> { let ct = self.monomorphize(constant.literal); let ct = match ct { mir::ConstantKind::Ty(ct) => ct, @@ -53,7 +53,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &Bx, span: Span, ty: Ty<'tcx>, - constant: Result, ErrorHandled>, + constant: Result, ErrorHandled<'tcx>>, ) -> (Bx::Value, Ty<'tcx>) { constant .map(|val| { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 1ef863e84af7f..7dae4482183eb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -189,7 +189,10 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // errored or at least linted ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {} ErrorHandled::TooGeneric => { - span_bug!(const_.span, "codgen encountered polymorphic constant: {:?}", err) + span_bug!(const_.span, "codegen encountered polymorphic constant: {:?}", err) + } + ErrorHandled::Silent(_) => { + span_bug!(const_.span, "silent error during codegen") } } } diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 87298023980ed..4b04d27b21cba 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -1,16 +1,13 @@ use std::error::Error; use std::fmt; -use rustc_errors::{DiagnosticBuilder, ErrorReported}; -use rustc_hir as hir; +use rustc_middle::mir::interpret::ConstEvalErr; use rustc_middle::mir::AssertKind; -use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt}; +use rustc_middle::ty::ConstInt; use rustc_span::{Span, Symbol}; use super::InterpCx; -use crate::interpret::{ - struct_error, ErrorHandled, FrameInfo, InterpError, InterpErrorInfo, Machine, MachineStopType, -}; +use crate::interpret::{InterpErrorInfo, Machine, MachineStopType}; /// The CTFE machine has some custom error kinds. #[derive(Clone, Debug)] @@ -63,13 +60,11 @@ impl Error for ConstEvalErrKind {} /// When const-evaluation errors, this type is constructed with the resulting information, /// and then used to emit the error as a lint or hard error. #[derive(Debug)] -pub struct ConstEvalErr<'tcx> { - pub span: Span, - pub error: InterpError<'tcx>, - pub stacktrace: Vec>, +pub struct ConstEvalError<'tcx> { + inner: ConstEvalErr<'tcx>, } -impl<'tcx> ConstEvalErr<'tcx> { +impl<'tcx> ConstEvalError<'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! @@ -77,131 +72,22 @@ impl<'tcx> ConstEvalErr<'tcx> { ecx: &InterpCx<'mir, 'tcx, M>, error: InterpErrorInfo<'tcx>, span: Option, - ) -> ConstEvalErr<'tcx> + ) -> ConstEvalError<'tcx> where 'tcx: 'mir, { error.print_backtrace(); let stacktrace = ecx.generate_stacktrace(); - ConstEvalErr { + let inner = ConstEvalErr { error: error.into_kind(), stacktrace, span: span.unwrap_or_else(|| ecx.cur_span()), - } - } - - pub fn struct_error( - &self, - tcx: TyCtxtAt<'tcx>, - message: &str, - emit: impl FnOnce(DiagnosticBuilder<'_>), - ) -> ErrorHandled { - self.struct_generic(tcx, message, emit, None) - } - - pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled { - self.struct_error(tcx, message, |mut e| e.emit()) - } - - pub fn report_as_lint( - &self, - tcx: TyCtxtAt<'tcx>, - message: &str, - lint_root: hir::HirId, - span: Option, - ) -> ErrorHandled { - self.struct_generic( - tcx, - message, - |mut lint: DiagnosticBuilder<'_>| { - // 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, ""); - } - } - } - lint.emit(); - }, - 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 - /// information before handing control back to `emit` to do any final processing. - /// It's the caller's responsibility to call emit(), stash(), etc. within the `emit` - /// function to dispose of the diagnostic properly. - /// - /// 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.) - fn struct_generic( - &self, - tcx: TyCtxtAt<'tcx>, - message: &str, - emit: impl FnOnce(DiagnosticBuilder<'_>), - lint_root: Option, - ) -> ErrorHandled { - let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option| { - trace!("reporting const eval failure at {:?}", self.span); - if let Some(span_msg) = span_msg { - err.span_label(self.span, span_msg); - } - // Add spans for the stacktrace. Don't print a single-line backtrace though. - if self.stacktrace.len() > 1 { - for frame_info in &self.stacktrace { - err.span_label(frame_info.span, frame_info.to_string()); - } - } - // Let the caller finish the job. - emit(err) }; - // Special handling for certain errors - match &self.error { - // Don't emit a new diagnostic for these errors - err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { - return ErrorHandled::TooGeneric; - } - err_inval!(AlreadyReported(error_reported)) => { - return ErrorHandled::Reported(*error_reported); - } - err_inval!(Layout(LayoutError::SizeOverflow(_))) => { - // We must *always* hard error on these, even if the caller wants just a lint. - // The `message` makes little sense here, this is a more serious error than the - // caller thinks anyway. - // See . - finish(struct_error(tcx, &self.error.to_string()), None); - return ErrorHandled::Reported(ErrorReported); - } - _ => {} - }; - - let err_msg = self.error.to_string(); + ConstEvalError { inner } + } - // 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| finish(lint.build(message), Some(err_msg)), - ); - ErrorHandled::Linted - } else { - // Report as hard error. - finish(struct_error(tcx, message), Some(err_msg)); - ErrorHandled::Reported(ErrorReported) - } + pub fn into_inner(self) -> ConstEvalErr<'tcx> { + self.inner } } 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 c5412affafe23..175685fcfa2ee 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -1,4 +1,4 @@ -use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr, MemoryExtra}; +use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalError, MemoryExtra}; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, @@ -10,15 +10,16 @@ use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::mir; -use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::mir::interpret::{ + ConstDedupError, ConstDedupResult, ConstErrorEmitted, ConstEvalErr, ConstOrigin, ErrorHandled, +}; use rustc_middle::mir::pretty::display_allocation; use rustc_middle::traits::Reveal; -use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, subst::Subst, TyCtxt}; use rustc_span::source_map::Span; use rustc_target::abi::Abi; -use std::borrow::Cow; use std::convert::TryInto; pub fn note_on_undefined_behavior_error() -> &'static str { @@ -28,6 +29,7 @@ pub fn note_on_undefined_behavior_error() -> &'static str { } // Returns a pointer to where the result lives +#[instrument(skip(ecx, body), level = "debug")] fn eval_body_using_ecx<'mir, 'tcx>( ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, cid: GlobalId<'tcx>, @@ -66,6 +68,8 @@ fn eval_body_using_ecx<'mir, 'tcx>( StackPopCleanup::None { cleanup: false }, )?; + debug!("returned from push_stack_frame"); + // The main interpreter loop. ecx.run()?; @@ -160,6 +164,7 @@ pub(super) fn op_to_const<'tcx>( ConstValue::Scalar(Scalar::ZST) } }; + match immediate { Ok(ref mplace) => to_const_value(mplace), // see comment on `let try_as_immediate` above @@ -212,81 +217,99 @@ fn turn_into_const_value<'tcx>( op_to_const(&ecx, &mplace.into()) } +#[instrument(skip(tcx), level = "debug")] pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { assert!(key.param_env.constness() == hir::Constness::Const); - // see comment in eval_to_allocation_raw_provider for what we're doing here - if key.param_env.reveal() == Reveal::All { - let mut key = key; - key.param_env = key.param_env.with_user_facing(); - match tcx.eval_to_const_value_raw(key) { - // try again with reveal all as requested - Err(ErrorHandled::TooGeneric) => {} - // deduplicate calls - other => return other, - } - } + let (param_env, id) = key.into_parts(); + let reveal = param_env.reveal(); // We call `const_eval` for zero arg intrinsics, too, in order to cache their value. // Catch such calls and evaluate them instead of trying to load a constant's MIR. if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def { - let ty = key.value.instance.ty(tcx, key.param_env); + let ty = key.value.instance.ty(tcx, param_env); let substs = match ty.kind() { ty::FnDef(_, substs) => substs, _ => bug!("intrinsic with type {:?}", ty), }; - return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| { - let span = tcx.def_span(def_id); - let error = ConstEvalErr { error: error.into_kind(), stacktrace: vec![], span }; - error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic") - }); + match eval_nullary_intrinsic(tcx, param_env, def_id, substs) { + Ok(val) => { + // store result for deduplication + let res = ConstDedupResult::new(reveal, Ok(val), None); + tcx.save_const_value_for_dedup(id, res); + + return Ok(val); + } + Err(e) => { + let span = tcx.def_span(def_id); + let error = ConstEvalErr { error: e.into_kind(), stacktrace: vec![], span }; + + let error_handled = tcx.handle_err_for_dedup( + id, + ConstOrigin::ConstValue, + error, + reveal, + span, + |e| { + tcx.report_and_add_error( + id, + e, + span, + "could not evaluate nullary intrinsic", + ) + }, + ); + + return Err(error_handled); + } + } } - tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key)) + let result = + tcx.dedup_eval_alloc_raw(key, None).map(|val| turn_into_const_value(tcx, val, key)); + + // store result for deduplication + let val = ConstDedupResult::new( + reveal, + result.map_err(|e| ConstDedupError::new_handled(e, reveal)), + None, + ); + tcx.save_const_value_for_dedup(id, val); + + result } +#[instrument(skip(tcx), level = "debug")] pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { assert!(key.param_env.constness() == hir::Constness::Const); - // Because the constant is computed twice (once per value of `Reveal`), we are at risk of - // reporting the same error twice here. To resolve this, we check whether we can evaluate the - // constant in the more restrictive `Reveal::UserFacing`, which most likely already was - // computed. For a large percentage of constants that will already have succeeded. Only - // associated constants of generic functions will fail due to not enough monomorphization - // information being available. - - // In case we fail in the `UserFacing` variant, we just do the real computation. - if key.param_env.reveal() == Reveal::All { - let mut key = key; - key.param_env = key.param_env.with_user_facing(); - match tcx.eval_to_allocation_raw(key) { - // try again with reveal all as requested - Err(ErrorHandled::TooGeneric) => {} - // deduplicate calls - other => return other, - } - } + let (param_env, cid) = key.into_parts(); + let reveal = param_env.reveal(); + if cfg!(debug_assertions) { // Make sure we format the instance even if we do not print it. // This serves as a regression test against an ICE on printing. // The next two lines concatenated contain some discussion: // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/ // subject/anon_const_instance_printing/near/135980032 - let instance = with_no_trimmed_paths(|| key.value.instance.to_string()); + let instance = with_no_trimmed_paths(|| cid.instance.to_string()); trace!("const eval: {:?} ({})", key, instance); } - let cid = key.value; let def = cid.instance.def.with_opt_param(); if let Some(def) = def.as_local() { if tcx.has_typeck_results(def.did) { if let Some(error_reported) = tcx.typeck_opt_const_arg(def).tainted_by_errors { - return Err(ErrorHandled::Reported(error_reported)); + let err = ConstErrorEmitted::Emitted(ErrorHandled::Reported(error_reported)); + let err_handled = + tcx.handle_reported_error_for_dedup(cid, ConstOrigin::Alloc, err, reveal); + + return Err(err_handled); } } if !tcx.is_mir_available(def.did) { @@ -294,10 +317,19 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx.def_span(def.did), &format!("no MIR body is available for {:?}", def.did), ); - return Err(ErrorHandled::Reported(ErrorReported {})); + + let err = ConstErrorEmitted::Emitted(ErrorHandled::Reported(ErrorReported {})); + let err_handled = + tcx.handle_reported_error_for_dedup(cid, ConstOrigin::Alloc, err, reveal); + + return Err(err_handled); } if let Some(error_reported) = tcx.mir_const_qualif_opt_const_arg(def).error_occured { - return Err(ErrorHandled::Reported(error_reported)); + let err = ConstErrorEmitted::Emitted(ErrorHandled::Reported(error_reported)); + let err_handled = + tcx.handle_reported_error_for_dedup(cid, ConstOrigin::Alloc, err, reveal); + + return Err(err_handled); } } @@ -316,46 +348,41 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let res = ecx.load_mir(cid.instance.def, cid.promoted); 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 - // . - 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() - } 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") - } 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") + debug!("error from eval_body_using_ecx: {:?}", error); + if reveal == Reveal::Selection { + match error.kind() { + err_inval!(Layout(LayoutError::Unknown(_))) + | err_inval!(TooGeneric) + | err_inval!(AlreadyReported(_)) => { + // We do want to report these errors } - }; + _ => { + let err = ConstEvalError::new(&ecx, error, None); + let error_handled = tcx.handle_err_for_dedup( + cid, + ConstOrigin::Alloc, + err.into_inner(), + reveal, + ecx.cur_span(), + |_e| ErrorHandled::Silent(cid), + ); - Err(err.report_as_error(ecx.tcx.at(ecx.cur_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), - )) + return Err(error_handled); + } + } } + + let err = ConstEvalError::new(&ecx, error, None); + let err_handled = tcx.handle_err_for_dedup( + cid, + ConstOrigin::Alloc, + err.into_inner(), + reveal, + ecx.cur_span(), + |e| tcx.report_alloc_error(cid, param_env, e, is_static, def, ecx.cur_span()), + ); + + Err(err_handled) } Ok(mplace) => { // Since evaluation had no errors, validate the resulting constant. @@ -377,27 +404,49 @@ pub fn eval_to_allocation_raw_provider<'tcx>( } }; let alloc_id = mplace.ptr.provenance.unwrap(); + if let Err(error) = validation { // Validation failed, report an error. This is always a hard error. - let err = ConstEvalErr::new(&ecx, error, None); - Err(err.struct_error( - ecx.tcx, - "it is undefined behavior to use this value", - |mut diag| { - diag.note(note_on_undefined_behavior_error()); - diag.note(&format!( - "the raw bytes of the constant ({}", - display_allocation( - *ecx.tcx, - ecx.tcx.global_alloc(alloc_id).unwrap_memory() - ) - )); - diag.emit(); + let err = ConstEvalError::new(&ecx, error, None).into_inner(); + + // FIXME: Do we also want to keep these silent with Reveal::Selection? + let error_handled = tcx.handle_err_for_dedup( + cid, + ConstOrigin::Alloc, + err, + reveal, + ecx.cur_span(), + |e| { + e.struct_error( + ecx.tcx, + "it is undefined behavior to use this value", + |mut diag| { + diag.note(note_on_undefined_behavior_error()); + diag.note(&format!( + "the raw bytes of the constant ({}", + display_allocation( + *ecx.tcx, + ecx.tcx.global_alloc(alloc_id).unwrap_memory() + ) + )); + diag.emit(); + }, + ) + .get_error() }, - )) + ); + + Err(error_handled) } else { // Convert to raw constant - Ok(ConstAlloc { alloc_id, ty: mplace.layout.ty }) + let const_alloc = ConstAlloc { alloc_id, ty: mplace.layout.ty }; + let result = Ok(const_alloc); + let val = ConstDedupResult::new(reveal, result, None); + + // store result in order to deduplicate later + tcx.save_alloc_for_dedup(cid, val); + + Ok(const_alloc) } } } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 246807a112a40..b063abf768ddf 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -1,13 +1,12 @@ use std::cell::Cell; -use std::fmt; use std::mem; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; +use rustc_hir::def_id::DefId; use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_middle::mir; -use rustc_middle::mir::interpret::{InterpError, InvalidProgramInfo}; +use rustc_middle::mir::interpret::{FrameInfo, InterpError, InvalidProgramInfo}; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, @@ -18,7 +17,7 @@ use rustc_middle::ty::{ use rustc_mir_dataflow::storage::AlwaysLiveLocals; use rustc_query_system::ich::StableHashingContext; use rustc_session::Limit; -use rustc_span::{Pos, Span}; +use rustc_span::Span; use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout}; use super::{ @@ -129,14 +128,6 @@ pub struct Frame<'mir, 'tcx, Tag: Provenance = AllocId, Extra = ()> { pub(super) loc: Result, } -/// What we store about a frame in an interpreter backtrace. -#[derive(Debug)] -pub struct FrameInfo<'tcx> { - pub instance: ty::Instance<'tcx>, - pub span: Span, - pub lint_root: Option, -} - /// Unwind information. #[derive(Clone, Copy, Eq, PartialEq, Debug, HashStable)] pub enum StackPopUnwind { @@ -265,32 +256,6 @@ impl<'mir, 'tcx, Tag: Provenance, Extra> Frame<'mir, 'tcx, Tag, Extra> { } } -impl<'tcx> fmt::Display for FrameInfo<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| { - if tcx.def_key(self.instance.def_id()).disambiguated_data.data - == DefPathData::ClosureExpr - { - write!(f, "inside closure")?; - } else { - write!(f, "inside `{}`", self.instance)?; - } - if !self.span.is_dummy() { - let sm = tcx.sess.source_map(); - let lo = sm.lookup_char_pos(self.span.lo()); - write!( - f, - " at {}:{}:{}", - sm.filename_for_diagnostics(&lo.file.name), - lo.line, - lo.col.to_usize() + 1 - )?; - } - Ok(()) - }) - } -} - impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> { #[inline] fn data_layout(&self) -> &TargetDataLayout { @@ -926,6 +891,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } + #[instrument(skip(self), level = "debug")] pub fn eval_to_allocation( &self, gid: GlobalId<'tcx>, @@ -941,8 +907,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env }; let param_env = param_env.with_const(); - let val = self.tcx.eval_to_allocation_raw(param_env.and(gid))?; - self.raw_const_to_mplace(val) + let val = self.tcx.dedup_eval_alloc_raw(param_env.and(gid), None); + debug!(?val); + + self.raw_const_to_mplace(val?) } #[must_use] diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 2b9fe56599715..22b2e89091002 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -19,7 +19,7 @@ mod visitor; pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here pub use self::eval_context::{ - Frame, FrameInfo, InterpCx, LocalState, LocalValue, StackPopCleanup, StackPopUnwind, + Frame, InterpCx, LocalState, LocalValue, StackPopCleanup, StackPopUnwind, }; pub use self::intern::{intern_const_alloc_recursive, InternKind}; pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index e9a857d09124f..fdf16b337fb97 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,40 +1,45 @@ -use super::{AllocId, ConstAlloc, Pointer, Scalar}; +use super::{AllocId, ConstAlloc, ConstValue, FrameInfo, GlobalId, Pointer, Scalar}; -use crate::mir::interpret::ConstValue; -use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty}; +use crate::ty::layout::LayoutError; +use crate::ty::{query::TyCtxtAt, tls, FnSig, Ty}; use rustc_data_structures::sync::Lock; use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorReported}; +use rustc_hir as hir; use rustc_macros::HashStable; use rustc_session::CtfeBacktrace; use rustc_span::def_id::DefId; +use rustc_span::Span; use rustc_target::abi::{call, Align, Size}; use std::{any::Any, backtrace::Backtrace, fmt}; #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] -pub enum ErrorHandled { +pub enum ErrorHandled<'tcx> { /// Already reported an error for this evaluation, and the compilation is /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. Reported(ErrorReported), /// Already emitted a lint for this evaluation. Linted, + /// Encountered an error without emitting anything. Only returned + /// with `Reveal::Selection`. + Silent(GlobalId<'tcx>), /// Don't emit an error, the evaluation failed because the MIR was generic /// and the substs didn't fully monomorphize it. TooGeneric, } -impl From for ErrorHandled { - fn from(err: ErrorReported) -> ErrorHandled { +impl<'tcx> From for ErrorHandled<'tcx> { + fn from(err: ErrorReported) -> ErrorHandled<'tcx> { ErrorHandled::Reported(err) } } TrivialTypeFoldableAndLiftImpls! { - ErrorHandled, + ErrorHandled<'tcx>, } -pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled>; -pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled>; +pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled<'tcx>>; +pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled<'tcx>>; pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> { struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) @@ -85,10 +90,12 @@ fn print_backtrace(backtrace: &Backtrace) { eprintln!("\n\nAn error occurred in miri:\n{}", backtrace); } -impl From for InterpErrorInfo<'_> { - fn from(err: ErrorHandled) -> Self { +impl<'tcx> From> for InterpErrorInfo<'tcx> { + fn from(err: ErrorHandled<'tcx>) -> Self { match err { - ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => { + ErrorHandled::Reported(ErrorReported) + | ErrorHandled::Linted + | ErrorHandled::Silent(_) => { err_inval!(ReferencedConstant) } ErrorHandled::TooGeneric => err_inval!(TooGeneric), @@ -140,7 +147,7 @@ pub enum InvalidProgramInfo<'tcx> { /// Abort in case errors are already reported. AlreadyReported(ErrorReported), /// An error occurred during layout computation. - Layout(layout::LayoutError<'tcx>), + Layout(LayoutError<'tcx>), /// An error occurred during FnAbi computation: the passed --target lacks FFI support /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. @@ -560,3 +567,150 @@ impl InterpError<'_> { } } } + +#[derive(Debug, Copy, Clone)] +pub enum ConstErrorEmitted<'tcx> { + Emitted(ErrorHandled<'tcx>), + NotEmitted(ErrorHandled<'tcx>), +} + +impl<'tcx> ConstErrorEmitted<'tcx> { + pub fn get_error(self) -> ErrorHandled<'tcx> { + match self { + ConstErrorEmitted::Emitted(e) => e, + ConstErrorEmitted::NotEmitted(e) => e, + } + } +} + +/// When const-evaluation errors, this type is constructed with the resulting information, +/// and then used to emit the error as a lint or hard error. +#[derive(Debug)] +pub struct ConstEvalErr<'tcx> { + pub span: Span, + pub error: InterpError<'tcx>, + pub stacktrace: Vec>, +} + +impl<'tcx> ConstEvalErr<'tcx> { + pub fn struct_error( + &self, + tcx: TyCtxtAt<'tcx>, + message: &str, + emit: impl FnOnce(DiagnosticBuilder<'_>), + ) -> ConstErrorEmitted<'tcx> { + self.struct_generic(tcx, message, emit, None) + } + + pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ConstErrorEmitted<'tcx> { + self.struct_error(tcx, message, |mut e| e.emit()) + } + + pub fn report_as_lint( + &self, + tcx: TyCtxtAt<'tcx>, + message: &str, + lint_root: hir::HirId, + span: Option, + ) -> ConstErrorEmitted<'tcx> { + self.struct_generic( + tcx, + message, + |mut lint: DiagnosticBuilder<'_>| { + // 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, ""); + } + } + } + lint.emit(); + }, + 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 + /// information before handing control back to `emit` to do any final processing. + /// It's the caller's responsibility to call emit(), stash(), etc. within the `emit` + /// function to dispose of the diagnostic properly. + /// + /// 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(tcx, emit, lint_root), level = "debug")] + fn struct_generic( + &self, + tcx: TyCtxtAt<'tcx>, + message: &str, + emit: impl FnOnce(DiagnosticBuilder<'_>), + lint_root: Option, + ) -> ConstErrorEmitted<'tcx> { + debug!("self.error: {:?}", self.error); + + let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option| { + trace!("reporting const eval failure at {:?}", self.span); + if let Some(span_msg) = span_msg { + err.span_label(self.span, span_msg); + } + // Add spans for the stacktrace. Don't print a single-line backtrace though. + if self.stacktrace.len() > 1 { + for frame_info in &self.stacktrace { + err.span_label(frame_info.span, frame_info.to_string()); + } + } + // Let the caller finish the job. + emit(err) + }; + + // Special handling for certain errors + match &self.error { + // Don't emit a new diagnostic for these errors + err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { + debug!("returning TooGeneric"); + return ConstErrorEmitted::NotEmitted(ErrorHandled::TooGeneric); + } + err_inval!(AlreadyReported(error_reported)) => { + debug!("Already Reported"); + return ConstErrorEmitted::NotEmitted(ErrorHandled::Reported(*error_reported)); + } + err_inval!(Layout(LayoutError::SizeOverflow(_))) => { + // We must *always* hard error on these, even if the caller wants just a lint. + // The `message` makes little sense here, this is a more serious error than the + // caller thinks anyway. + // See . + finish(struct_error(tcx, &self.error.to_string()), None); + return ConstErrorEmitted::Emitted(ErrorHandled::Reported(ErrorReported)); + } + _ => {} + }; + + let err_msg = self.error.to_string(); + debug!(?err_msg); + + // 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| finish(lint.build(message), Some(err_msg)), + ); + ConstErrorEmitted::Emitted(ErrorHandled::Linted) + } else { + // Report as hard error. + finish(struct_error(tcx, message), Some(err_msg)); + ConstErrorEmitted::Emitted(ErrorHandled::Reported(ErrorReported)) + } + } +} diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index b762a10da847a..c48d99c71479f 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -95,6 +95,7 @@ mod pointer; mod queries; mod value; +use std::cell::RefCell; use std::convert::TryFrom; use std::fmt; use std::io; @@ -106,21 +107,29 @@ use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_data_structures::tiny_list::TinyList; +use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_macros::HashStable; +use rustc_hir::definitions::DefPathData; +use rustc_middle::traits::Reveal; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_serialize::{Decodable, Encodable}; +use rustc_span::{Pos, Span, DUMMY_SP}; use rustc_target::abi::Endian; use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; +use crate::ty::layout::LayoutError; use crate::ty::subst::GenericArgKind; -use crate::ty::{self, Instance, Ty, TyCtxt}; +use crate::ty::{self, Instance, Ty, TyCtxt, WithOptConstParam}; + +use std::borrow::Cow; pub use self::error::{ - struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, - InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, MachineStopType, - ResourceExhaustionInfo, UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, + struct_error, CheckInAllocMsg, ConstErrorEmitted, ConstEvalErr, ErrorHandled, + EvalToAllocationRawResult, EvalToConstValueResult, InterpError, InterpErrorInfo, InterpResult, + InvalidProgramInfo, MachineStopType, ResourceExhaustionInfo, UndefinedBehaviorInfo, + UninitBytesAccess, UnsupportedOpInfo, }; pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar, ScalarMaybeUninit}; @@ -446,6 +455,206 @@ impl<'tcx> AllocMap<'tcx> { } } +/// What we store about a frame in an interpreter backtrace. +#[derive(Debug)] +pub struct FrameInfo<'tcx> { + pub instance: ty::Instance<'tcx>, + pub span: Span, + pub lint_root: Option, +} + +impl<'tcx> fmt::Display for FrameInfo<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + if tcx.def_key(self.instance.def_id()).disambiguated_data.data + == DefPathData::ClosureExpr + { + write!(f, "inside closure")?; + } else { + write!(f, "inside `{}`", self.instance)?; + } + if !self.span.is_dummy() { + let sm = tcx.sess.source_map(); + let lo = sm.lookup_char_pos(self.span.lo()); + write!( + f, + " at {}:{}:{}", + sm.filename_for_diagnostics(&lo.file.name), + lo.line, + lo.col.to_usize() + 1 + )?; + } + Ok(()) + }) + } +} + +/// Errors that were returned from calls to `eval_to_allocation_raw` or +/// `eval_to_const_value_raw` with `Reveal::Selection`. Since we want to +/// deduplicate from `Reveal::Selection` results, we store the returned +/// `ConstEvalErr` in order to allow us to report those errors on calls +/// with `Reveal::UserFacing` or `Reveal::All`. +#[derive(Debug)] +pub enum SilentError<'tcx> { + ConstErr(ConstEvalErr<'tcx>), + Handled(ErrorHandled<'tcx>), +} + +#[derive(Debug)] +pub enum ConstDedupError<'tcx> { + /// used for errors found in `eval_to_allocation_raw` with `Reveal::Selection` + /// in order to allow deduplication. + Silent(SilentError<'tcx>), + + /// error that was reported in call of `eval_to_allocation_raw`. + Handled(ErrorHandled<'tcx>), +} + +impl<'tcx> ConstDedupError<'tcx> { + pub fn new_handled(e: ErrorHandled<'tcx>, reveal: Reveal) -> Self { + match reveal { + Reveal::Selection => ConstDedupError::Silent(SilentError::Handled(e)), + _ => ConstDedupError::Handled(e), + } + } + + pub fn new_silent(e: SilentError<'tcx>, reveal: Reveal) -> Self { + match reveal { + Reveal::Selection => ConstDedupError::Silent(e), + _ => bug!("can only create a `ConstDedupError::Silent` with `Reveal::Selection`"), + } + } + + pub fn get_const_err(self) -> ConstEvalErr<'tcx> { + match self { + ConstDedupError::Silent(e) => match e { + SilentError::ConstErr(e) => e, + _ => bug!( + "cannot call `get_const_err` on `ConstDedupError::Silent(SilentError::Handled)`" + ), + }, + ConstDedupError::Handled(_) => { + bug!("get_const_err called on ConstDedupError::Handled") + } + } + } + + pub fn get_handled_err(&self) -> ErrorHandled<'tcx> { + match self { + ConstDedupError::Handled(e) => *e, + ConstDedupError::Silent(e) => match e { + SilentError::Handled(e) => *e, + SilentError::ConstErr(_) => { + bug!("get_handled_err called on ConstDedupError::Silent(SilentError::ConstErr)") + } + }, + } + } +} + +#[derive(Debug)] +pub enum ConstDedupResult<'tcx, T: 'tcx> { + // include a Span so that we can report errors when we try to deduplicate calls + // with Reveal::UserFacing from calls with Reveal::Selection, for which we have + // to report the error during the dedup call + Selection((Result>, Span)), + UserFacing(Result>), + All(Result>), +} + +impl<'tcx, T: 'tcx> ConstDedupResult<'tcx, T> { + pub fn new( + reveal: Reveal, + val: Result>, + opt_span: Option, + ) -> Self { + match reveal { + Reveal::Selection => ConstDedupResult::Selection(( + val.map_err(|e| match e { + ConstDedupError::Silent(err) => err, + ConstDedupError::Handled(_) => bug!("expected ConstDedupError::Silent"), + }), + opt_span.unwrap_or(DUMMY_SP), + )), + Reveal::UserFacing => { + ConstDedupResult::UserFacing(val.or_else(|e| Err(e.get_handled_err()))) + } + Reveal::All => ConstDedupResult::All(val.or_else(|e| Err(e.get_handled_err()))), + } + } +} + +#[derive(Copy, Clone, Debug)] +pub enum ConstOrigin { + ConstValue, + Alloc, +} + +/// Used to store results of calls to `eval_to_allocation_raw` and +/// `eval_to_const_value_raw`. +/// +/// Depending on the value of `Reveal` of the `ParamEnv` with which the queries +/// are executed we handle errors differently. We suppress errors with `Reveal::Selection`, +/// and report errors otherwise. +/// Since a large portion of the calls with different `Reveal` arguments leads to +/// duplicate results, we try to only store the result of a call with one specific `Reveal` +/// and use that result for queries with other `Reveal` arguments. +#[derive(Debug)] +pub struct ConstDedupMap<'tcx> { + // interning for deduplication of `eval_to_allocation_raw` + pub alloc_map: RefCell, ConstDedupResult<'tcx, ConstAlloc<'tcx>>>>, + + // interning for deduplication of `eval_to_const_value_raw` + pub const_val_map: RefCell, ConstDedupResult<'tcx, ConstValue<'tcx>>>>, + + // Used to tell whether an error needs to be reported when trying to deduplicate a + // call to `eval_to_allocation_raw` or `eval_to_const_value_raw` with + // `Reveal::UserFacing` or `Reveal::All` from a call with `Reveal::Selection` + pub error_reported_map: RefCell, ErrorHandled<'tcx>>>, +} + +impl<'tcx> ConstDedupMap<'tcx> { + pub fn new() -> Self { + ConstDedupMap { + alloc_map: Default::default(), + const_val_map: Default::default(), + error_reported_map: Default::default(), + } + } + + #[instrument(skip(self), level = "debug")] + fn add_error_reported( + &self, + id: GlobalId<'tcx>, + err: ConstErrorEmitted<'tcx>, + ) -> ConstErrorEmitted<'tcx> { + match err { + ConstErrorEmitted::Emitted(err_handled) => { + let mut error_reported_map = self.error_reported_map.borrow_mut(); + error_reported_map.insert(id, err_handled); + debug!("error_reported_map after update: {:#?}", self.error_reported_map); + + err + } + ConstErrorEmitted::NotEmitted(_) => err, + } + } + + #[instrument(skip(self), level = "debug")] + fn insert_alloc(&self, id: GlobalId<'tcx>, val: ConstDedupResult<'tcx, ConstAlloc<'tcx>>) { + let mut alloc_map = self.alloc_map.borrow_mut(); + alloc_map.insert(id, val); + debug!("alloc_map after update: {:#?}", alloc_map); + } + + #[instrument(skip(self), level = "debug")] + fn insert_const_val(&self, id: GlobalId<'tcx>, val: ConstDedupResult<'tcx, ConstValue<'tcx>>) { + let mut const_val_map = self.const_val_map.borrow_mut(); + const_val_map.insert(id, val); + debug!("const_val_map after update: {:#?}", const_val_map); + } +} + impl<'tcx> TyCtxt<'tcx> { /// Obtains a new allocation ID that can be referenced but does not /// yet have an allocation backing it. @@ -554,6 +763,513 @@ impl<'tcx> TyCtxt<'tcx> { fn set_alloc_id_same_memory(self, id: AllocId, mem: &'tcx Allocation) { self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem)); } + + /// Called after an error has been returned from `eval_to_allocation_raw` + /// or `eval_to_const_value_raw`. We handle this differently based on + /// the `Reveal` argument. With `Reveal::Selection` we don't report the + /// error, otherwise we do. In all cases we cache the error. + #[instrument(skip(self, report_fn), level = "debug")] + pub fn handle_err_for_dedup( + self, + id: GlobalId<'tcx>, + origin: ConstOrigin, + error: ConstEvalErr<'tcx>, + reveal: Reveal, + span: Span, + report_fn: F, + ) -> ErrorHandled<'tcx> + where + F: Fn(&ConstEvalErr<'tcx>) -> ErrorHandled<'tcx>, + { + match reveal { + Reveal::Selection => { + match origin { + ConstOrigin::ConstValue => { + let res = ConstDedupResult::new( + reveal, + Err(ConstDedupError::new_silent(SilentError::ConstErr(error), reveal)), + Some(span), + ); + + self.save_const_value_for_dedup(id, res); + } + ConstOrigin::Alloc => { + let res = ConstDedupResult::new( + reveal, + Err(ConstDedupError::new_silent(SilentError::ConstErr(error), reveal)), + Some(span), + ); + self.save_alloc_for_dedup(id, res); + } + } + + return ErrorHandled::Silent(id); + } + _ => { + let error_handled = report_fn(&error); + debug!(?error_handled); + + match origin { + ConstOrigin::ConstValue => { + let res = ConstDedupResult::new( + reveal, + Err(ConstDedupError::new_handled(error_handled, reveal)), + None, + ); + + self.save_const_value_for_dedup(id, res); + } + ConstOrigin::Alloc => { + let res = ConstDedupResult::new( + reveal, + Err(ConstDedupError::new_handled(error_handled, reveal)), + None, + ); + + self.save_alloc_for_dedup(id, res); + } + } + + error_handled + } + } + } + + /// Stores returned errors from `eval_to_allocation_raw` or `eval_to_const_value_raw` + /// calls that were already reported. + #[instrument(skip(self), level = "debug")] + pub fn handle_reported_error_for_dedup( + self, + id: GlobalId<'tcx>, + origin: ConstOrigin, + err: ConstErrorEmitted<'tcx>, + reveal: Reveal, + ) -> ErrorHandled<'tcx> { + match err { + ConstErrorEmitted::Emitted(error_handled) => { + let dedup_err = ConstDedupError::new_handled(error_handled, reveal); + + match origin { + ConstOrigin::ConstValue => { + let val = ConstDedupResult::new(reveal, Err(dedup_err), None); + self.save_const_value_for_dedup(id, val); + } + ConstOrigin::Alloc => { + let val = ConstDedupResult::new(reveal, Err(dedup_err), None); + self.save_alloc_for_dedup(id, val); + } + } + + let error_handled = self.add_error_reported(id, err).get_error(); + + error_handled + } + ConstErrorEmitted::NotEmitted(_) => bug!( + "`handle_reported_error_for_dedup` should only be called on emitted `ConstErr`s" + ), + } + } + + fn add_error_reported( + self, + id: GlobalId<'tcx>, + err: ConstErrorEmitted<'tcx>, + ) -> ConstErrorEmitted<'tcx> { + let const_dedup_map = self.dedup_const_map.lock(); + const_dedup_map.add_error_reported(id, err) + } + + #[instrument(skip(self), level = "debug")] + pub fn report_and_add_error( + self, + id: GlobalId<'tcx>, + err: &ConstEvalErr<'tcx>, + span: Span, + msg: &str, + ) -> ErrorHandled<'tcx> { + let error_emitted = err.report_as_error(self.at(span), msg); + debug!(?error_emitted); + + let const_dedup_map = self.dedup_const_map.lock(); + let error_handled = const_dedup_map.add_error_reported(id, error_emitted).get_error(); + debug!(?error_handled); + + error_handled + } + + /// Store the result of a call to `eval_to_allocation_raw` in order to + /// allow deduplication. + #[instrument(skip(self), level = "debug")] + pub fn save_alloc_for_dedup( + self, + id: GlobalId<'tcx>, + val: ConstDedupResult<'tcx, ConstAlloc<'tcx>>, + ) { + let dedup_const_map = self.dedup_const_map.lock(); + dedup_const_map.insert_alloc(id, val); + debug!("dedup_const_map after insert: {:#?}", dedup_const_map); + } + + /// Store the result of a call to `eval_to_const_value_raw` in order to deduplicate it. + #[instrument(skip(self), level = "debug")] + pub fn save_const_value_for_dedup( + self, + id: GlobalId<'tcx>, + val: ConstDedupResult<'tcx, ConstValue<'tcx>>, + ) { + let dedup_const_map = self.dedup_const_map.lock(); + dedup_const_map.insert_const_val(id, val); + debug!("dedup_const_map after insert: {:#?}", dedup_const_map); + } + + /// This function reports errors that were returned from calls of + /// `eval_to_allocation_raw` and stores them in order to allow + /// errors to be retrieved in deduplication. + #[instrument(skip(self, dedup_const_map), level = "debug")] + pub fn report_const_alloc_error( + self, + dedup_const_map: &ConstDedupMap<'tcx>, + id: GlobalId<'tcx>, + param_env: ty::ParamEnv<'tcx>, + err: &ConstEvalErr<'tcx>, + is_static: bool, + def: WithOptConstParam, + span: Span, + ) -> ConstErrorEmitted<'tcx> { + // Some CTFE errors raise just a lint, not a hard error; see + // . + let is_hard_err = if let Some(def) = def.as_local() { + // (Associated) consts only emit a lint, since they might be unused. + !matches!(self.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) + // check if the inner InterpError is hard + || err.error.is_hard_err() + } 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") + } 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 = &id.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") + } + }; + + let e = err.report_as_error(self.at(span), &msg); + dedup_const_map.add_error_reported(id, e).get_error(); + + e + } else { + let hir_id = self.hir().local_def_id_to_hir_id(def.as_local().unwrap().did); + let e = err.report_as_lint( + self.at(self.def_span(def.did)), + "any use of this value will cause an error", + hir_id, + Some(err.span), + ); + + dedup_const_map.add_error_reported(id, e).get_error(); + + e + } + } + + /// This function reports errors that were returned from calls of + /// `eval_to_const_value_raw` and stores them in order to allow + /// errors to be retrieved in deduplication. + #[instrument(skip(self), level = "debug")] + fn report_const_val_error_if_not_already_reported( + self, + dedup_const_map: &ConstDedupMap<'tcx>, + id: GlobalId<'tcx>, + error: &ConstEvalErr<'tcx>, + param_env: ty::ParamEnv<'tcx>, + span: Span, + ) -> ErrorHandled<'tcx> { + // FIXME: This is really problematic in that it is tightly coupled to the + // implementation of `eval_to_const_value_raw`. Introducing new errors + // in that function would have to be considered here. Need to find an + // abstraction that makes this coupling explicit. + if let ty::InstanceDef::Intrinsic(_) = id.instance.def { + let contained = dedup_const_map.error_reported_map.borrow().contains_key(&id); + + if !contained { + let error_emitted = + error.report_as_error(self.at(span), "could not evaluate nullary intrinsic"); + let error_handled = + dedup_const_map.add_error_reported(id, error_emitted).get_error(); + + error_handled + } else { + let error_handled = *dedup_const_map.error_reported_map.borrow().get(&id).unwrap(); + error_handled + } + } else { + let def = id.instance.def.with_opt_param(); + + self.report_alloc_error_if_not_already_reported( + dedup_const_map, + id, + error, + def, + param_env, + span, + ) + } + } + + /// Tries to deduplicate a call to `eval_to_allocation_raw`. If deduplication isn't + /// successful `eval_to_allocation_raw` query is executed. + #[instrument(skip(self, opt_span), level = "debug")] + pub fn dedup_eval_alloc_raw( + self, + key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, + opt_span: Option, + ) -> EvalToAllocationRawResult<'tcx> { + use ConstDedupResult::*; + + let (param_env, id) = key.into_parts(); + let def = id.instance.def.with_opt_param(); + + let dedup_const_map = self.dedup_const_map.lock(); + debug!("dedup_const_map: {:#?}", dedup_const_map); + let alloc_map = dedup_const_map.alloc_map.borrow(); + debug!("alloc_map: {:#?}", alloc_map); + + let dedup_result = alloc_map.get(&id); + debug!(?dedup_result); + + match param_env.reveal() { + Reveal::Selection => match dedup_result { + Some(Selection((Ok(alloc), _))) | Some(UserFacing(Ok(alloc))) => { + return Ok(*alloc); + } + Some(Selection((Err(err), span))) => { + match err { + SilentError::ConstErr(const_eval_err) => { + match const_eval_err.error { + err_inval!(Layout(LayoutError::Unknown(_))) + | err_inval!(TooGeneric) + | err_inval!(AlreadyReported(_)) => { + // We do want to report these errors even with `Reveal::Selection` + + let is_static = self.is_static(def.did); + let err_handled = self + .report_const_alloc_error( + &dedup_const_map, + id, + param_env, + const_eval_err, + is_static, + def, + *span, + ) + .get_error(); + + debug!(?err_handled); + + return Err(err_handled); + } + _ => return Err(ErrorHandled::Silent(id)), + } + } + SilentError::Handled(err) => { + return Err(*err); + } + } + } + Some(UserFacing(Err(_)) | All(Err(_))) => { + // these errors were previously reported, so we stay silent here + // and later access the reported errors using `id`. + return Err(ErrorHandled::Silent(id)); + } + _ => {} + }, + Reveal::UserFacing => match dedup_result { + Some(Selection((Ok(alloc), _))) | Some(UserFacing(Ok(alloc))) => { + return Ok(*alloc); + } + Some(UserFacing(Err(e)) | All(Err(e))) => { + return Err(*e); + } + Some(Selection((Err(e), span))) => match e { + SilentError::ConstErr(const_err) => { + let error_handled = self.report_alloc_error_if_not_already_reported( + &dedup_const_map, + id, + const_err, + def, + param_env, + *span, + ); + + return Err(error_handled); + } + SilentError::Handled(error_handled) => return Err(*error_handled), + }, + _ => {} + }, + Reveal::All => match dedup_result { + Some(Selection((Ok(alloc), _)) | UserFacing(Ok(alloc)) | All(Ok(alloc))) => { + return Ok(*alloc); + } + Some(All(Err(e))) => return Err(*e), + Some(UserFacing(Err(e))) => match e { + ErrorHandled::TooGeneric => {} // run query again with Reveal::All + _ => return Err(*e), + }, + _ => {} + }, + } + + // Important to drop the lock here + drop(alloc_map); + drop(dedup_const_map); + + debug!("unable to deduplicate"); + + // We weren't able to deduplicate + match opt_span { + Some(span) => self.at(span).eval_to_allocation_raw(key), + None => self.eval_to_allocation_raw(key), + } + } + + /// Tries to deduplicate a call to `eval_to_const_value_raw`. If deduplication isn't + /// successful, `eval_to_const_value_raw` query is executed. + #[instrument(skip(self), level = "debug")] + pub fn dedup_eval_const_value_raw( + self, + key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, + ) -> EvalToConstValueResult<'tcx> { + use ConstDedupResult::*; + + let (param_env, id) = key.into_parts(); + let dedup_const_map = self.dedup_const_map.lock(); + debug!("dedup_const_map: {:#?}", dedup_const_map); + let const_val_map = dedup_const_map.const_val_map.borrow(); + debug!("const_val_map: {:#?}", const_val_map); + + let dedup_result = const_val_map.get(&id); + debug!(?dedup_result); + + match param_env.reveal() { + Reveal::Selection => match dedup_result { + Some(Selection((Ok(val), _))) | Some(UserFacing(Ok(val))) => { + return Ok(*val); + } + Some(Selection((Err(_), _)) | UserFacing(Err(_)) | All(Err(_))) => { + return Err(ErrorHandled::Silent(id)); + } + _ => {} + }, + Reveal::UserFacing => match dedup_result { + Some(Selection((Ok(val), _))) | Some(UserFacing(Ok(val))) => { + return Ok(*val); + } + Some(UserFacing(Err(e)) | All(Err(e))) => { + return Err(*e); + } + Some(Selection((Err(e), span))) => match e { + SilentError::ConstErr(const_err) => { + let error_handled = self.report_const_val_error_if_not_already_reported( + &dedup_const_map, + id, + const_err, + param_env, + *span, + ); + + return Err(error_handled); + } + SilentError::Handled(error_handled) => return Err(*error_handled), + }, + _ => {} + }, + Reveal::All => match dedup_result { + Some(Selection((Ok(val), _)) | UserFacing(Ok(val)) | All(Ok(val))) => { + return Ok(*val); + } + Some(All(Err(e))) => return Err(*e), + Some(UserFacing(Err(e))) => match e { + ErrorHandled::TooGeneric => {} // run query again with Reveal::All + _ => return Err(*e), + }, + _ => {} + }, + } + + // Important to drop the lock here + drop(const_val_map); + drop(dedup_const_map); + + debug!("unable to deduplicate"); + + // We weren't able to deduplicate + self.eval_to_const_value_raw(key) + } + + #[instrument(skip(self), level = "debug")] + pub fn report_alloc_error( + self, + id: GlobalId<'tcx>, + param_env: ty::ParamEnv<'tcx>, + err: &ConstEvalErr<'tcx>, + is_static: bool, + def: WithOptConstParam, + span: Span, + ) -> ErrorHandled<'tcx> { + let dedup_const_map = self.dedup_const_map.lock(); + let error_handled = self + .report_const_alloc_error(&dedup_const_map, id, param_env, err, is_static, def, span) + .get_error(); + + error_handled + } + + #[instrument(skip(self, dedup_const_map), level = "debug")] + fn report_alloc_error_if_not_already_reported( + self, + dedup_const_map: &ConstDedupMap<'tcx>, + id: GlobalId<'tcx>, + e: &ConstEvalErr<'tcx>, + def: WithOptConstParam, + param_env: ty::ParamEnv<'tcx>, + span: Span, + ) -> ErrorHandled<'tcx> { + let stored_error = dedup_const_map.error_reported_map.borrow().get(&id).cloned(); + match stored_error { + Some(err) => err, + None => { + let is_static = self.is_static(def.did); + let def = id.instance.def.with_opt_param(); + + let error_handled = self + .report_const_alloc_error( + dedup_const_map, + id, + param_env, + e, + is_static, + def, + span, + ) + .get_error(); + + error_handled + } + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index f983185563315..53f253f4cc49a 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -58,6 +58,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Evaluate a constant. + #[instrument(skip(self), level = "debug")] pub fn const_eval_global_id( self, param_env: ty::ParamEnv<'tcx>, @@ -68,18 +69,18 @@ impl<'tcx> TyCtxt<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); - if let Some(span) = span { - self.at(span).eval_to_const_value_raw(inputs) - } else { - self.eval_to_const_value_raw(inputs) - } + + let raw_const = self.dedup_eval_const_value_raw(inputs); + debug!(?raw_const); + + raw_const } /// Evaluate a static's initializer, returning the allocation of the initializer's memory. pub fn eval_static_initializer( self, def_id: DefId, - ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + ) -> Result<&'tcx mir::Allocation, ErrorHandled<'tcx>> { trace!("eval_static_initializer: Need to compute {:?}", def_id); assert!(self.is_static(def_id)); let instance = ty::Instance::mono(self, def_id); @@ -88,14 +89,17 @@ impl<'tcx> TyCtxt<'tcx> { } /// Evaluate anything constant-like, returning the allocation of the final memory. + #[instrument(skip(self), level = "debug")] fn eval_to_allocation( self, gid: GlobalId<'tcx>, param_env: ty::ParamEnv<'tcx>, - ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + ) -> Result<&'tcx mir::Allocation, ErrorHandled<'tcx>> { let param_env = param_env.with_const(); trace!("eval_to_allocation: Need to compute {:?}", gid); - let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; - Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) + let raw_const = self.dedup_eval_alloc_raw(param_env.and(gid), None); + debug!(?raw_const); + + Ok(self.global_alloc(raw_const?.alloc_id).unwrap_memory()) } } diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs index f80beadd6e551..80ac17e006aef 100644 --- a/compiler/rustc_middle/src/thir/abstract_const.rs +++ b/compiler/rustc_middle/src/thir/abstract_const.rs @@ -1,5 +1,6 @@ //! A subset of a mir body used for const evaluatability checking. use crate::mir; +use crate::mir::interpret::GlobalId; use crate::ty::{self, Ty, TyCtxt}; use rustc_errors::ErrorReported; @@ -30,20 +31,21 @@ pub enum Node<'tcx> { } #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] -pub enum NotConstEvaluatable { +pub enum NotConstEvaluatable<'tcx> { Error(ErrorReported), MentionsInfer, MentionsParam, + Silent(GlobalId<'tcx>), } -impl From for NotConstEvaluatable { - fn from(e: ErrorReported) -> NotConstEvaluatable { +impl<'tcx> From for NotConstEvaluatable<'tcx> { + fn from(e: ErrorReported) -> NotConstEvaluatable<'tcx> { NotConstEvaluatable::Error(e) } } TrivialTypeFoldableAndLiftImpls! { - NotConstEvaluatable, + NotConstEvaluatable<'tcx>, } impl<'tcx> TyCtxt<'tcx> { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index de5beffb5c541..a44441d491e23 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -37,6 +37,12 @@ pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner /// more or less conservative. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)] pub enum Reveal { + // Similar to `Reveal::UserFacing`, except that we also do not emit errors + // when failing const evaluation. + // + // Used by `feature(const_evaluatable_checked)` to allow for `ConstEvaluatable` + // predicates to not hold without emitting an error. + Selection, /// At type-checking time, we refuse to project any associated /// type that is marked `default`. Non-`default` ("final") types /// are always projected. This is necessary in general for @@ -450,7 +456,7 @@ pub struct DerivedObligationCause<'tcx> { pub parent_code: Lrc>, } -#[derive(Clone, Debug, TypeFoldable, Lift)] +#[derive(Clone, Debug, TypeFoldable)] pub enum SelectionError<'tcx> { /// The trait is not implemented. Unimplemented, @@ -465,7 +471,7 @@ pub enum SelectionError<'tcx> { /// The trait pointed by `DefId` is not object safe. TraitNotObjectSafe(DefId), /// A given constant couldn't be evaluated. - NotConstEvaluatable(NotConstEvaluatable), + NotConstEvaluatable(NotConstEvaluatable<'tcx>), /// Exceeded the recursion depth during type projection. Overflow, /// Signaling that an error has already been emitted, to avoid diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 5cde54c9328d1..0387ac66a0dd7 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -426,6 +426,7 @@ impl<'tcx> AdtDef { "enum discriminant evaluation failed" } ErrorHandled::TooGeneric => "enum discriminant depends on generics", + ErrorHandled::Silent(_) => return None, }; tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg); None diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 7188eed544551..206473e8c333a 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -3,6 +3,7 @@ use std::fmt; use crate::mir::interpret::{AllocId, ConstValue, Scalar}; use crate::mir::Promoted; +use crate::traits::Reveal; use crate::ty::subst::{InternalSubsts, SubstsRef}; use crate::ty::ParamEnv; use crate::ty::{self, TyCtxt, TypeFoldable}; @@ -160,10 +161,15 @@ impl<'tcx> ConstKind<'tcx> { // Note that we erase regions *before* calling `with_reveal_all_normalized`, // so that we don't try to invoke this query with // any region variables. - let param_env_and = tcx - .erase_regions(param_env) - .with_reveal_all_normalized(tcx) - .and(tcx.erase_regions(unevaluated)); + let param_env_and = match param_env.reveal() { + Reveal::Selection => { + tcx.erase_regions(param_env).and(tcx.erase_regions(unevaluated)) + } + _ => tcx + .erase_regions(param_env) + .with_reveal_all_normalized(tcx) + .and(tcx.erase_regions(unevaluated)), + }; // HACK(eddyb) when the query key would contain inference variables, // attempt using identity substs and `ParamEnv` instead, that will succeed @@ -191,7 +197,9 @@ impl<'tcx> ConstKind<'tcx> { // (which may be identity substs, see above), // can leak through `val` into the const we return. Ok(val) => Some(Ok(val)), - Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => None, + Err(ErrorHandled::TooGeneric | ErrorHandled::Linted | ErrorHandled::Silent(_)) => { + None + } Err(ErrorHandled::Reported(e)) => Some(Err(e)), } } else { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index caa7008f1085e..6086117b8111f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1043,6 +1043,10 @@ pub struct GlobalCtxt<'tcx> { /// Stores memory for globals (statics/consts). pub(crate) alloc_map: Lock>, + /// Used to deduplicate calls to `eval_to_allocation_raw` and + /// `eval_to_const_value_raw`. + pub dedup_const_map: Lock>, + output_filenames: Arc, } @@ -1187,6 +1191,7 @@ impl<'tcx> TyCtxt<'tcx> { stability_interner: Default::default(), const_stability_interner: Default::default(), alloc_map: Lock::new(interpret::AllocMap::new()), + dedup_const_map: Lock::new(interpret::ConstDedupMap::new()), output_filenames: Arc::new(output_filenames), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 37d99766da9d2..a6558e2af2a48 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1237,23 +1237,28 @@ struct ParamTag { } unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag { - const BITS: usize = 2; + const BITS: usize = 3; #[inline] fn into_usize(self) -> usize { match self { - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 0, - Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 1, - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 2, - Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3, + Self { reveal: traits::Reveal::Selection, constness: hir::Constness::NotConst } => 0, + Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 1, + Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 2, + Self { reveal: traits::Reveal::Selection, constness: hir::Constness::Const } => 3, + Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 4, + Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 5, } } + #[inline] unsafe fn from_usize(ptr: usize) -> Self { match ptr { - 0 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, - 1 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, - 2 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, - 3 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const }, + 0 => Self { reveal: traits::Reveal::Selection, constness: hir::Constness::NotConst }, + 1 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, + 2 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, + 3 => Self { reveal: traits::Reveal::Selection, constness: hir::Constness::Const }, + 4 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, + 5 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const }, _ => std::hint::unreachable_unchecked(), } } @@ -1343,6 +1348,11 @@ impl<'tcx> ParamEnv<'tcx> { ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) } } + pub fn with_reveal_selection(mut self) -> Self { + self.packed.set_tag(ParamTag { reveal: Reveal::Selection, ..self.packed.tag() }); + self + } + pub fn with_user_facing(mut self) -> Self { self.packed.set_tag(ParamTag { reveal: Reveal::UserFacing, ..self.packed.tag() }); self @@ -1412,7 +1422,7 @@ impl<'tcx> ParamEnv<'tcx> { /// although the surrounding function is never reachable. pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { match self.reveal() { - Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, + Reveal::Selection | Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, Reveal::All => { if value.is_known_global() { diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 7e56e062fc989..8ec72c2effaca 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -29,7 +29,7 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; use crate::MirPass; -use rustc_const_eval::const_eval::ConstEvalErr; +use rustc_const_eval::const_eval::ConstEvalError; use rustc_const_eval::interpret::{ self, compile_time_machine, AllocId, Allocation, ConstValue, CtfeValidationMode, Frame, ImmTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemPlace, MemoryKind, OpTy, @@ -490,7 +490,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Ok(op) => Some(op), Err(error) => { let tcx = self.ecx.tcx.at(c.span); - let err = ConstEvalErr::new(&self.ecx, error, Some(c.span)); + let err = ConstEvalError::new(&self.ecx, error, Some(c.span)).into_inner(); if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal { ConstantKind::Ty(ct) => match ct.val { @@ -509,12 +509,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if lint_only { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. - err.report_as_lint(tcx, "erroneous constant used", lint_root, Some(c.span)); + err.report_as_lint(tcx, "erroneous constant used", lint_root, Some(c.span)) + .get_error(); } else { - err.report_as_error(tcx, "erroneous constant used"); + err.report_as_error(tcx, "erroneous constant used").get_error(); } } else { - err.report_as_error(tcx, "erroneous constant used"); + err.report_as_error(tcx, "erroneous constant used").get_error(); } None } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index b1fa9041342a6..248a0aa45354e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -731,6 +731,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { "collection encountered polymorphic constant: {:?}", literal ), + Err(ErrorHandled::Silent(_)) => span_bug!( + self.body.source_info(location).span, + "silent error emitted during collection", + ), } } _ => return, @@ -763,6 +767,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { "collection encountered polymorphic constant: {}", substituted_constant ), + Err(ErrorHandled::Silent(_)) => span_bug!( + self.body.source_info(location).span, + "silent error emitted during collection", + ), } } _ => {} diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 0ea3a18ca34fa..192f99438be65 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -32,7 +32,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( uv: ty::Unevaluated<'tcx, ()>, param_env: ty::ParamEnv<'tcx>, span: Span, -) -> Result<(), NotConstEvaluatable> { +) -> Result<(), NotConstEvaluatable<'tcx>> { debug!("is_const_evaluatable({:?})", uv); if infcx.tcx.features().generic_const_exprs { let tcx = infcx.tcx; @@ -147,7 +147,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>( // and hopefully soon change this to an error. // // See #74595 for more details about this. - let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); + let concrete = + infcx.const_eval_resolve(param_env.with_reveal_selection(), uv.expand(), Some(span)); if concrete.is_ok() && uv.substs(infcx.tcx).definitely_has_param_types_or_consts(infcx.tcx) { match infcx.tcx.def_kind(uv.def.did) { @@ -173,6 +174,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Err(NotConstEvaluatable::Error(ErrorReported)) } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Silent(id)) => Err(NotConstEvaluatable::Silent(id)), Ok(_) => Ok(()), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index b5c5724f56edc..87205eaf8214f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -19,6 +19,9 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::GenericParam; use rustc_hir::Item; use rustc_hir::Node; +use rustc_middle::mir::interpret::{ + ConstDedupResult, ConstErrorEmitted, ErrorHandled, SilentError, +}; use rustc_middle::thir::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences}; @@ -238,6 +241,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { error: &SelectionError<'tcx>, fallback_has_occurred: bool, ) { + debug!("report_selection_error(error: {:?})", error); let tcx = self.tcx; let mut span = obligation.cause.span; @@ -795,12 +799,100 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let violations = self.tcx.object_safety_violations(did); report_object_safety_error(self.tcx, span, did, violations) } - SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => { bug!( "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`" ) } + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Silent(id)) => { + // try to report a ConstEvalErr which gives better diagnostics by providing + // information about why the constant couldn't be evaluated. + let const_dedup_map = tcx.dedup_const_map.lock(); + debug!("const_dedup_map: {:#?}", &const_dedup_map); + debug!(?id); + + // FIXME This only reports errors stored as `ConstDedupResult::Selection` + // but we should also report cached errors with other Reveal variants + // here. See e.g. test `ui/const-generics/generic_const_exprs/issue-62504.rs` + // which fails to report the `TooGeneric` error because it was stored + // with `Reveal::All`. + if !const_dedup_map.error_reported_map.borrow().contains_key(&id) { + if let Some(ConstDedupResult::Selection(( + Err(SilentError::ConstErr(err)), + sp, + ))) = const_dedup_map.alloc_map.borrow().get(&id) + { + let def = id.instance.def.with_opt_param(); + let is_static = tcx.is_static(def.did); + + let err_emitted = tcx.report_const_alloc_error( + &const_dedup_map, + id, + obligation.param_env, + err, + is_static, + def, + *sp, + ); + + match err_emitted { + ConstErrorEmitted::NotEmitted(err) => { + if let ErrorHandled::TooGeneric = err { + let selection_err = SelectionError::NotConstEvaluatable( + NotConstEvaluatable::MentionsParam, + ); + + self.report_selection_error( + obligation.clone(), + root_obligation, + &selection_err, + fallback_has_occurred, + ); + } + } + _ => {} + } + } else { + if let Some(ConstDedupResult::Selection(( + Err(SilentError::ConstErr(err)), + sp, + ))) = const_dedup_map.const_val_map.borrow().get(&id) + { + let def = id.instance.def.with_opt_param(); + let is_static = tcx.is_static(def.did); + + let err_emitted = tcx.report_const_alloc_error( + &const_dedup_map, + id, + obligation.param_env, + err, + is_static, + def, + *sp, + ); + + match err_emitted { + ConstErrorEmitted::NotEmitted(err) => { + if let ErrorHandled::TooGeneric = err { + let selection_err = SelectionError::NotConstEvaluatable( + NotConstEvaluatable::MentionsParam, + ); + + self.report_selection_error( + obligation.clone(), + root_obligation, + &selection_err, + fallback_has_occurred, + ); + } + } + _ => {} + } + } + } + } + tcx.sess.struct_span_err(span, "failed to evaluate the given constant") + } SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => { if !self.tcx.features().generic_const_exprs { let mut err = self.tcx.sess.struct_span_err( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 42e3f0db15e53..0716228ded8a3 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -528,12 +528,14 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } ty::PredicateKind::ConstEvaluatable(uv) => { - match const_evaluatable::is_const_evaluatable( + let res = const_evaluatable::is_const_evaluatable( self.selcx.infcx(), uv, - obligation.param_env, + obligation.param_env.with_reveal_selection(), obligation.cause.span, - ) { + ); + + match res { Ok(()) => ProcessResult::Changed(vec![]), Err(NotConstEvaluatable::MentionsInfer) => { pending_obligation.stalled_on.clear(); @@ -546,7 +548,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } Err( e @ NotConstEvaluatable::MentionsParam - | e @ NotConstEvaluatable::Error(_), + | e @ NotConstEvaluatable::Error(_) + | e @ NotConstEvaluatable::Silent(_), ) => ProcessResult::Error(CodeSelectionError( SelectionError::NotConstEvaluatable(e), )), @@ -625,6 +628,13 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { "ConstEquate: const_eval_resolve returned an unexpected error" ) } + (Err(ErrorHandled::Silent(id)), _) | (_, Err(ErrorHandled::Silent(id))) => { + ProcessResult::Error(CodeSelectionError( + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Silent( + id, + )), + )) + } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { ProcessResult::Unchanged diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index a8f26982d2e42..b7660dddc8ce0 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -273,6 +273,7 @@ fn do_normalize_predicates<'tcx>( // FIXME: this is gonna need to be removed ... /// Normalizes the parameter environment, reporting errors if they occur. +#[instrument(skip(tcx), level = "debug")] pub fn normalize_param_env_or_error<'tcx>( tcx: TyCtxt<'tcx>, region_context: DefId, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 23f615a96185d..dbd6cf1bd06d4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -26,6 +26,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; + use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_span::symbol::sym; @@ -296,7 +297,7 @@ where pub(crate) fn needs_normalization<'tcx, T: TypeFoldable<'tcx>>(value: &T, reveal: Reveal) -> bool { match reveal { - Reveal::UserFacing => value + Reveal::Selection | Reveal::UserFacing => value .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION), Reveal::All => value.has_type_flags( ty::TypeFlags::HAS_TY_PROJECTION @@ -394,8 +395,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { - Reveal::UserFacing => ty.super_fold_with(self), - + Reveal::UserFacing | Reveal::Selection => ty.super_fold_with(self), Reveal::All => { let recursion_limit = self.tcx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 26bacf787e2eb..d91a7c00acfe9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -210,8 +210,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { - Reveal::UserFacing => ty.try_super_fold_with(self), - + Reveal::UserFacing | Reveal::Selection => ty.try_super_fold_with(self), Reveal::All => { let substs = substs.try_super_fold_with(self)?; let recursion_limit = self.tcx().recursion_limit(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fa88c8ee37015..fb638d020414b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -654,7 +654,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let ty::ConstKind::Unevaluated(unevaluated) = c.val { self.infcx .const_eval_resolve( - obligation.param_env, + obligation.param_env.with_reveal_selection(), unevaluated, Some(obligation.cause.span), ) @@ -675,8 +675,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(_) => Ok(EvaluatedToErr), } } - (Err(ErrorHandled::Reported(ErrorReported)), _) - | (_, Err(ErrorHandled::Reported(ErrorReported))) => Ok(EvaluatedToErr), + ( + Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Silent(_)), + _, + ) + | ( + _, + Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Silent(_)), + ) => Ok(EvaluatedToErr), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.tcx()), diff --git a/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.rs b/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.rs index 8fe79b97d9ba2..f7af377732dd3 100644 --- a/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.rs +++ b/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.rs @@ -15,6 +15,7 @@ impl Foo for Def { pub fn test() { let _array = [4; ::Y]; //~^ ERROR constant expression depends on a generic parameter + //~| ERROR failed to evaluate } fn main() { diff --git a/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr index 0bc019b2dc875..6fbffddc90df6 100644 --- a/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr +++ b/src/test/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr @@ -6,5 +6,11 @@ LL | let _array = [4; ::Y]; | = note: this may fail depending on what value the parameter takes -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22 + | +LL | let _array = [4; ::Y]; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr index 3fb4ab72fe6d6..e5a2777a47bc5 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr @@ -5,11 +5,6 @@ note: ...which requires simplifying constant for the type system `Tr::A`... | LL | const A: u8 = Self::B; | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `Tr::A`... - --> $DIR/defaults-cyclic-fail.rs:6:5 - | -LL | const A: u8 = Self::B; - | ^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Tr::A`... --> $DIR/defaults-cyclic-fail.rs:6:5 | @@ -21,11 +16,6 @@ note: ...which requires simplifying constant for the type system `Tr::B`... | LL | const B: u8 = Self::A; | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `Tr::B`... - --> $DIR/defaults-cyclic-fail.rs:8:5 - | -LL | const B: u8 = Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Tr::B`... --> $DIR/defaults-cyclic-fail.rs:8:5 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr index 61b16cb9d5811..1ec52e019d4c9 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `IMPL LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `IMPL_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 - | -LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | @@ -20,11 +15,6 @@ note: ...which requires simplifying constant for the type system `::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 - | -LL | const BAR: u32 = IMPL_REF_BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr index 494dc0c0ed447..4a6d0c5019ec5 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `DEFA LL | const DEFAULT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `DEFAULT_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 - | -LL | const DEFAULT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 | @@ -20,11 +15,6 @@ note: ...which requires simplifying constant for the type system `FooDefault::BA | LL | const BAR: u32 = DEFAULT_REF_BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `FooDefault::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 - | -LL | const BAR: u32 = DEFAULT_REF_BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `FooDefault::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 4ff253bffcb32..727c326e594dc 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `TRAI LL | const TRAIT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 - | -LL | const TRAIT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | @@ -20,11 +15,6 @@ note: ...which requires simplifying constant for the type system `::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 - | -LL | const BAR: u32 = TRAIT_REF_BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | diff --git a/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs b/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs index 41a52c7eb0d83..2d6d64bbf4de7 100644 --- a/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs +++ b/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs @@ -1,3 +1,4 @@ struct Foo; //~^ ERROR evaluation of constant value failed +//~| ERROR failed to evaluate fn main() {} diff --git a/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr b/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr index e8ebddade5c16..24ad7a1ad5a67 100644 --- a/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr +++ b/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of constant value failed LL | struct Foo; | ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/default-param-wf-concrete.rs:1:18 + | +LL | struct Foo; + | ^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/defaults/wfness.rs b/src/test/ui/const-generics/defaults/wfness.rs index d366040ba3ea6..e13b07f5ba0cb 100644 --- a/src/test/ui/const-generics/defaults/wfness.rs +++ b/src/test/ui/const-generics/defaults/wfness.rs @@ -1,5 +1,6 @@ struct Ooopsies; //~^ error: evaluation of constant value failed +//~| ERROR failed to evaluate trait Trait {} impl Trait<3> for () {} diff --git a/src/test/ui/const-generics/defaults/wfness.stderr b/src/test/ui/const-generics/defaults/wfness.stderr index facf0ae19f734..a4015479ac488 100644 --- a/src/test/ui/const-generics/defaults/wfness.stderr +++ b/src/test/ui/const-generics/defaults/wfness.stderr @@ -4,8 +4,14 @@ error[E0080]: evaluation of constant value failed LL | struct Ooopsies; | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow +error: failed to evaluate the given constant + --> $DIR/wfness.rs:1:23 + | +LL | struct Ooopsies; + | ^ + error[E0277]: the trait bound `(): Trait<2_u8>` is not satisfied - --> $DIR/wfness.rs:6:47 + --> $DIR/wfness.rs:7:47 | LL | struct WhereClause where (): Trait; | ^^^^^^^^ the trait `Trait<2_u8>` is not implemented for `()` @@ -14,7 +20,7 @@ LL | struct WhereClause where (): Trait; <() as Trait<3_u8>> error[E0277]: the trait bound `(): Trait<1_u8>` is not satisfied - --> $DIR/wfness.rs:14:13 + --> $DIR/wfness.rs:15:13 | LL | fn foo() -> DependentDefaultWfness { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1_u8>` is not implemented for `()` @@ -22,12 +28,12 @@ LL | fn foo() -> DependentDefaultWfness { = help: the following implementations were found: <() as Trait<3_u8>> note: required by a bound in `WhereClause` - --> $DIR/wfness.rs:6:47 + --> $DIR/wfness.rs:7:47 | LL | struct WhereClause where (): Trait; | ^^^^^^^^ required by this bound in `WhereClause` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0080, E0277. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs index 90953145944fe..b0b8574f4a85f 100644 --- a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs +++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs @@ -8,4 +8,6 @@ fn test() -> [u8; N - 1] { fn main() { test::<0>(); + //~^ ERROR failed to evaluate + //~| ERROR failed to evaluate } diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr index 31ccf97969472..c7a33b2571829 100644 --- a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr @@ -4,6 +4,30 @@ error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed LL | fn test() -> [u8; N - 1] { | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/from-sig-fail.rs:10:5 + | +LL | test::<0>(); + | ^^^^^^^^^ + | +note: required by a bound in `test` + --> $DIR/from-sig-fail.rs:4:35 + | +LL | fn test() -> [u8; N - 1] { + | ^^^^^ required by this bound in `test` + +error: failed to evaluate the given constant + --> $DIR/from-sig-fail.rs:10:5 + | +LL | test::<0>(); + | ^^^^^^^^^^^ + | +note: required by a bound in `test` + --> $DIR/from-sig-fail.rs:4:35 + | +LL | fn test() -> [u8; N - 1] { + | ^^^^^ required by this bound in `test` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 5d45e302888d4..e032a80a95e05 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -7,13 +7,11 @@ LL | ArrayHolder([0; Self::SIZE]) = note: expected array `[u32; X]` found array `[u32; _]` -error: constant expression depends on a generic parameter +error: failed to evaluate the given constant --> $DIR/issue-62504.rs:18:25 | LL | ArrayHolder([0; Self::SIZE]) | ^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs b/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs index a97f4b8ff3131..c182c33df78c2 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs +++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs @@ -18,7 +18,7 @@ impl ArrayHolder { ArrayHolder([0; Self::SIZE]) //~^ ERROR mismatched types //[full]~^^ ERROR unconstrained generic constant - //[min]~^^^ ERROR constant expression depends on a generic parameter + //[min]~^^^ ERROR failed to evaluate } } diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs b/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs index 275f69953024c..83e3f6f718372 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -29,4 +29,5 @@ where fn main() { let dst = Inline::::new(0); //~ ERROR //~^ ERROR + //~| ERROR failed to evaluate } diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr index 56cb11bacbe6b..ca8126e47ada1 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,17 +1,3 @@ -error[E0080]: evaluation of `Inline::::{constant#0}` failed - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | -LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | size_of called on unsized type `dyn Debug` - | inside `std::mem::size_of::` at $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - ::: $DIR/issue-80742.rs:22:10 - | -LL | [u8; size_of::() + 1]: , - | -------------- inside `Inline::::{constant#0}` at $DIR/issue-80742.rs:22:10 - error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied --> $DIR/issue-80742.rs:30:36 | @@ -35,6 +21,23 @@ LL | pub trait Debug { = note: the following trait bounds were not satisfied: `dyn Debug: Sized` +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/issue-80742.rs:30:15 + | +LL | let dst = Inline::::new(0); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by a bound in `Inline` + --> $DIR/issue-80742.rs:12:15 + | +LL | struct Inline + | ^ required by this bound in `Inline` +help: consider relaxing the implicit `Sized` restriction + | +LL | struct Inline + | ++++++++ + error[E0080]: evaluation of `Inline::::{constant#0}` failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | @@ -49,22 +52,20 @@ LL | intrinsics::size_of::() LL | [u8; size_of::() + 1]: , | -------------- inside `Inline::::{constant#0}` at $DIR/issue-80742.rs:14:10 -error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time +error: failed to evaluate the given constant --> $DIR/issue-80742.rs:30:15 | LL | let dst = Inline::::new(0); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^^ | - = help: the trait `Sized` is not implemented for `dyn Debug` note: required by a bound in `Inline` - --> $DIR/issue-80742.rs:12:15 + --> $DIR/issue-80742.rs:14:10 | LL | struct Inline - | ^ required by this bound in `Inline` -help: consider relaxing the implicit `Sized` restriction - | -LL | struct Inline - | ++++++++ + | ------ required by a bound in this +LL | where +LL | [u8; size_of::() + 1]: , + | ^^^^^^^^^^^^^^^^^^ required by this bound in `Inline` error: aborting due to 4 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs index c47a350c7fb43..6a78a6b23cf23 100644 --- a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs +++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs @@ -11,4 +11,6 @@ fn test() -> Arr where [u8; N - 1]: Sized { fn main() { test::<0>(); + //~^ ERROR failed to evaluate + //~| ERROR failed to evaluate } diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr index 99fc92fb4f0ad..e3b493c4c8833 100644 --- a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr @@ -4,12 +4,30 @@ error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed LL | fn test() -> Arr where [u8; N - 1]: Sized { | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow +error: failed to evaluate the given constant + --> $DIR/simple_fail.rs:13:5 + | +LL | test::<0>(); + | ^^^^^^^^^ + | +note: required by a bound in `test` + --> $DIR/simple_fail.rs:7:48 + | +LL | fn test() -> Arr where [u8; N - 1]: Sized { + | ^^^^^ required by this bound in `test` + error[E0080]: evaluation of `Arr::<0_usize>::{constant#0}` failed --> $DIR/simple_fail.rs:4:33 | LL | type Arr = [u8; N - 1]; | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow -error: aborting due to 2 previous errors +error: failed to evaluate the given constant + --> $DIR/simple_fail.rs:13:5 + | +LL | test::<0>(); + | ^^^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/issues/issue-62878.full.stderr b/src/test/ui/const-generics/issues/issue-62878.full.stderr index f074a65313f12..b159fc54a8d0e 100644 --- a/src/test/ui/const-generics/issues/issue-62878.full.stderr +++ b/src/test/ui/const-generics/issues/issue-62878.full.stderr @@ -4,13 +4,25 @@ error[E0770]: the type of const parameters must not depend on other generic para LL | fn foo() {} | ^ the type must not depend on the parameter `N` +error: failed to evaluate the given constant + --> $DIR/issue-62878.rs:10:14 + | +LL | foo::<_, {[1]}>(); + | ^^^^^ + +error: failed to evaluate the given constant + --> $DIR/issue-62878.rs:10:14 + | +LL | foo::<_, {[1]}>(); + | ^^^^^ + error[E0308]: mismatched types --> $DIR/issue-62878.rs:10:15 | LL | foo::<_, {[1]}>(); | ^^^ expected `usize`, found array `[{integer}; 1]` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0308, E0770. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs index 38f5ff77b56a9..c606b667c1ecf 100644 --- a/src/test/ui/const-generics/issues/issue-62878.rs +++ b/src/test/ui/const-generics/issues/issue-62878.rs @@ -9,4 +9,6 @@ fn foo() {} fn main() { foo::<_, {[1]}>(); //[full]~^ ERROR mismatched types + //[full]~| ERROR failed to evaluate + //[full]~| ERROR failed to evaluate } diff --git a/src/test/ui/const-generics/issues/issue-67739.min.stderr b/src/test/ui/const-generics/issues/issue-67739.min.stderr index dcbe5b94a6281..d89492f6a6ac5 100644 --- a/src/test/ui/const-generics/issues/issue-67739.min.stderr +++ b/src/test/ui/const-generics/issues/issue-67739.min.stderr @@ -6,5 +6,11 @@ LL | [0u8; mem::size_of::()]; | = note: this may fail depending on what value the parameter takes -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-67739.rs:11:15 + | +LL | [0u8; mem::size_of::()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs index de0eb7f509ae5..26f06d7fcd0c1 100644 --- a/src/test/ui/const-generics/issues/issue-67739.rs +++ b/src/test/ui/const-generics/issues/issue-67739.rs @@ -9,8 +9,9 @@ pub trait Trait { fn associated_size(&self) -> usize { [0u8; mem::size_of::()]; - //[min]~^ ERROR constant expression depends on a generic parameter - //[full]~^^ ERROR unconstrained generic constant + //[full]~^ ERROR unconstrained generic constant + //[min]~^^ ERROR constant expression depends on a generic parameter + //[min]~| ERROR failed to evaluate 0 } } diff --git a/src/test/ui/const-generics/issues/issue-71169.full.stderr b/src/test/ui/const-generics/issues/issue-71169.full.stderr index 1f5880f368ee2..d735d39ae1820 100644 --- a/src/test/ui/const-generics/issues/issue-71169.full.stderr +++ b/src/test/ui/const-generics/issues/issue-71169.full.stderr @@ -4,6 +4,18 @@ error[E0770]: the type of const parameters must not depend on other generic para LL | fn foo() {} | ^^^ the type must not depend on the parameter `LEN` -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-71169.rs:10:14 + | +LL | foo::<4, DATA>(); + | ^^^^ + +error: failed to evaluate the given constant + --> $DIR/issue-71169.rs:10:14 + | +LL | foo::<4, DATA>(); + | ^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/issues/issue-71169.rs b/src/test/ui/const-generics/issues/issue-71169.rs index 617149a841893..fb96513d0c27c 100644 --- a/src/test/ui/const-generics/issues/issue-71169.rs +++ b/src/test/ui/const-generics/issues/issue-71169.rs @@ -8,4 +8,6 @@ fn foo() {} fn main() { const DATA: [u8; 4] = *b"ABCD"; foo::<4, DATA>(); + //[full]~^ ERROR failed to evaluate + //[full]~| ERROR failed to evaluate } diff --git a/src/test/ui/const-generics/issues/issue-86530.rs b/src/test/ui/const-generics/issues/issue-86530.rs index b024decd4e11c..94a8dc104fb73 100644 --- a/src/test/ui/const-generics/issues/issue-86530.rs +++ b/src/test/ui/const-generics/issues/issue-86530.rs @@ -15,6 +15,7 @@ where fn unit_literals() { z(" "); //~^ ERROR: the trait bound `&str: X` is not satisfied + //~| ERROR failed to evaluate } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-86530.stderr b/src/test/ui/const-generics/issues/issue-86530.stderr index c63857b2314e9..2eccc6a0e0bd5 100644 --- a/src/test/ui/const-generics/issues/issue-86530.stderr +++ b/src/test/ui/const-generics/issues/issue-86530.stderr @@ -15,6 +15,21 @@ LL | where LL | T: X, | ^ required by this bound in `z` -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-86530.rs:16:5 + | +LL | z(" "); + | ^ + | +note: required by a bound in `z` + --> $DIR/issue-86530.rs:11:10 + | +LL | fn z(t: T) + | - required by a bound in this +... +LL | [(); T::Y]: , + | ^^^^ required by this bound in `z` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/legacy-const-generics-bad.rs b/src/test/ui/const-generics/legacy-const-generics-bad.rs index 538eee337cc6d..6d137e873d065 100644 --- a/src/test/ui/const-generics/legacy-const-generics-bad.rs +++ b/src/test/ui/const-generics/legacy-const-generics-bad.rs @@ -6,11 +6,13 @@ fn foo() { let a = 1; legacy_const_generics::foo(0, a, 2); //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR failed to evaluate legacy_const_generics::foo(0, N, 2); legacy_const_generics::foo(0, N + 1, 2); //~^ ERROR generic parameters may not be used in const operations + //~| ERROR failed to evaluate } fn main() {} diff --git a/src/test/ui/const-generics/legacy-const-generics-bad.stderr b/src/test/ui/const-generics/legacy-const-generics-bad.stderr index 3c78dd6c78023..bb9982a8eca7d 100644 --- a/src/test/ui/const-generics/legacy-const-generics-bad.stderr +++ b/src/test/ui/const-generics/legacy-const-generics-bad.stderr @@ -7,7 +7,7 @@ LL | legacy_const_generics::foo(0, a, 2); | ^ non-constant value error: generic parameters may not be used in const operations - --> $DIR/legacy-const-generics-bad.rs:12:35 + --> $DIR/legacy-const-generics-bad.rs:13:35 | LL | legacy_const_generics::foo(0, N + 1, 2); | ^ cannot perform const operation using `N` @@ -15,6 +15,18 @@ LL | legacy_const_generics::foo(0, N + 1, 2); = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error: aborting due to 2 previous errors +error: failed to evaluate the given constant + --> $DIR/legacy-const-generics-bad.rs:7:35 + | +LL | legacy_const_generics::foo(0, a, 2); + | ^ + +error: failed to evaluate the given constant + --> $DIR/legacy-const-generics-bad.rs:13:35 + | +LL | legacy_const_generics::foo(0, N + 1, 2); + | ^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs index e12e07a28e763..1c30fbdb2c9ee 100644 --- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs +++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs @@ -4,6 +4,7 @@ const BAR: usize = 42; fn a() { foo::(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn b() { // FIXME(const_generics): these diagnostics are awful, because trait objects without `dyn` were @@ -18,30 +19,38 @@ fn c() { } fn d() { foo::(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn e() { foo::(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn f() { foo::<100 - BAR>(); //~ ERROR expressions must be enclosed in braces } fn g() { foo::()>(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn h() { foo::()>(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn i() { foo::() + BAR>(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn j() { foo::() - BAR>(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn k() { foo::()>(); //~ ERROR expected one of + //~| ERROR failed to evaluate } fn l() { foo::()>(); //~ ERROR expected one of + //~| ERROR failed to evaluate } const fn bar() -> usize { diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr index d9bcc523b1fc4..038b3b271c175 100644 --- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr +++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr @@ -10,7 +10,7 @@ LL | foo::<{ BAR + 3 }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:17:11 + --> $DIR/const-expression-suggest-missing-braces.rs:18:11 | LL | foo::<3 + 3>(); | ^^^^^ @@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:20:15 + --> $DIR/const-expression-suggest-missing-braces.rs:21:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:23:15 + --> $DIR/const-expression-suggest-missing-braces.rs:25:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -43,7 +43,7 @@ LL | foo::<{ BAR - BAR }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:26:11 + --> $DIR/const-expression-suggest-missing-braces.rs:29:11 | LL | foo::<100 - BAR>(); | ^^^^^^^^^ @@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:29:19 + --> $DIR/const-expression-suggest-missing-braces.rs:32:19 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -65,7 +65,7 @@ LL | foo::<{ bar() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:32:21 + --> $DIR/const-expression-suggest-missing-braces.rs:36:21 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -76,7 +76,7 @@ LL | foo::<{ bar::() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:35:21 + --> $DIR/const-expression-suggest-missing-braces.rs:40:21 | LL | foo::() + BAR>(); | ^ expected one of `,` or `>` @@ -87,7 +87,7 @@ LL | foo::<{ bar::() + BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:38:21 + --> $DIR/const-expression-suggest-missing-braces.rs:44:21 | LL | foo::() - BAR>(); | ^ expected one of `,` or `>` @@ -98,7 +98,7 @@ LL | foo::<{ bar::() - BAR }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:41:15 + --> $DIR/const-expression-suggest-missing-braces.rs:48:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::() }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:44:15 + --> $DIR/const-expression-suggest-missing-braces.rs:52:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -120,24 +120,78 @@ LL | foo::<{ BAR - bar::() }>(); | + + error[E0404]: expected trait, found constant `BAR` - --> $DIR/const-expression-suggest-missing-braces.rs:11:11 + --> $DIR/const-expression-suggest-missing-braces.rs:12:11 | LL | foo::(); | ^^^ not a trait error[E0404]: expected trait, found constant `BAR` - --> $DIR/const-expression-suggest-missing-braces.rs:11:17 + --> $DIR/const-expression-suggest-missing-braces.rs:12:17 | LL | foo::(); | ^^^ not a trait +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:6:11 + | +LL | foo::(); + | ^^^^^^^ + error[E0747]: type provided when a constant was expected - --> $DIR/const-expression-suggest-missing-braces.rs:11:11 + --> $DIR/const-expression-suggest-missing-braces.rs:12:11 | LL | foo::(); | ^^^^^^^^^ -error: aborting due to 14 previous errors +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:21:11 + | +LL | foo::(); + | ^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:25:11 + | +LL | foo::(); + | ^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:32:11 + | +LL | foo::()>(); + | ^^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:36:11 + | +LL | foo::()>(); + | ^^^^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:40:11 + | +LL | foo::() + BAR>(); + | ^^^^^^^^^^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:44:11 + | +LL | foo::() - BAR>(); + | ^^^^^^^^^^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:48:11 + | +LL | foo::()>(); + | ^^^^^^^^^^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/const-expression-suggest-missing-braces.rs:52:11 + | +LL | foo::()>(); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 23 previous errors Some errors have detailed explanations: E0404, E0747. For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index 415a53a56274a..5d7f4394c1fbe 100644 --- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr @@ -4,26 +4,50 @@ error[E0308]: mismatched types LL | get_flag::(); | ^^^^ expected `char`, found `u8` +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:29:21 + | +LL | get_flag::(); + | ^^^^ + error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:14 + --> $DIR/invalid-patterns.rs:32:14 | LL | get_flag::<7, 'c'>(); | ^ expected `bool`, found integer +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:32:14 + | +LL | get_flag::<7, 'c'>(); + | ^ + error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 + --> $DIR/invalid-patterns.rs:35:14 | LL | get_flag::<42, 0x5ad>(); | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:18 + --> $DIR/invalid-patterns.rs:35:18 | LL | get_flag::<42, 0x5ad>(); | ^^^^^ expected `char`, found `u8` +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:35:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ + +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:35:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ + error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:38:21 + --> $DIR/invalid-patterns.rs:42:21 | LL | get_flag::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) @@ -33,8 +57,14 @@ LL | get_flag::(); __ __ __ __ │ ░░░░ } +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:42:21 + | +LL | get_flag::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:40:14 + --> $DIR/invalid-patterns.rs:45:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean @@ -44,8 +74,14 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); 42 │ B } +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:45:14 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:42:14 + --> $DIR/invalid-patterns.rs:48:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean @@ -56,7 +92,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:42:47 + --> $DIR/invalid-patterns.rs:48:47 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) @@ -66,7 +102,19 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character __ __ __ __ │ ░░░░ } -error: aborting due to 8 previous errors +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:48:14 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: failed to evaluate the given constant + --> $DIR/invalid-patterns.rs:48:47 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 16 previous errors Some errors have detailed explanations: E0080, E0308. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs index 682e0eced9dff..54dabfb3446e6 100644 --- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs @@ -28,18 +28,26 @@ fn main() { assert!(get_flag::().is_none()); get_flag::(); //~^ ERROR mismatched types + //~| ERROR failed to evaluate get_flag::<7, 'c'>(); //~^ ERROR mismatched types + //~| ERROR failed to evaluate get_flag::<42, 0x5ad>(); //~^ ERROR mismatched types + //~| ERROR failed to evaluate + //~| ERROR failed to evaluate //~| ERROR mismatched types get_flag::(); //~^ ERROR it is undefined behavior + //~| ERROR failed to evaluate get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); //~^ ERROR it is undefined behavior + //~| ERROR failed to evaluate get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); //~^ ERROR it is undefined behavior //~| ERROR it is undefined behavior + //~| ERROR failed to evaluate + //~| ERROR failed to evaluate } diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr index 9f0b2efae96ce..fbfc0f71a5037 100644 --- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr +++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr @@ -1,11 +1,11 @@ error: generic parameters with a default must be trailing - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:12 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:9:12 | LL | struct Bar(T); | ^ error[E0128]: generic parameters with a default cannot use forward declared identifiers - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:9:21 | LL | struct Bar(T); | ^ defaulted generic parameters cannot be forward declared diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr index a5e70f6b9e648..05328c3344ac8 100644 --- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr +++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr @@ -1,5 +1,5 @@ error: generic parameters with a default must be trailing - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:12 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:9:12 | LL | struct Bar(T); | ^ @@ -14,11 +14,23 @@ LL | struct Foo()]>(T, U); = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0128]: generic parameters with a default cannot use forward declared identifiers - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:9:21 | LL | struct Bar(T); | ^ defaulted generic parameters cannot be forward declared -error: aborting due to 3 previous errors +error: failed to evaluate the given constant + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:5:15 + | +LL | struct Foo()]>(T, U); + | ^ + +error: failed to evaluate the given constant + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:9:12 + | +LL | struct Bar(T); + | ^ + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs index b24a7afabd90f..8abb22069cd81 100644 --- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs +++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs @@ -4,9 +4,11 @@ struct Foo()]>(T, U); //[min]~^ ERROR generic parameters may not be used in const operations +//[min]~| ERROR failed to evaluate struct Bar(T); //~^ ERROR generic parameters with a default cannot use forward declared identifiers //~| ERROR generic parameters with a default +//[min]~| ERROR failed to evaluate fn main() {} diff --git a/src/test/ui/const-generics/sneaky-array-repeat-expr.rs b/src/test/ui/const-generics/sneaky-array-repeat-expr.rs index b147c246bdac8..0e86246dbc630 100644 --- a/src/test/ui/const-generics/sneaky-array-repeat-expr.rs +++ b/src/test/ui/const-generics/sneaky-array-repeat-expr.rs @@ -10,6 +10,7 @@ impl Trait for () { pub const fn foo() where (): Trait { let bar = [(); <()>::Assoc]; //~^ error: constant expression depends on a generic parameter + //~| ERROR failed to evaluate } trait Trait2 { @@ -24,6 +25,7 @@ impl Trait2 for () { pub const fn foo2() where (): Trait2 { let bar2 = [(); <()>::Assoc2]; //~^ error: constant expression depends on a generic parameter + //~| ERROR failed to evaluate } fn main() { diff --git a/src/test/ui/const-generics/sneaky-array-repeat-expr.stderr b/src/test/ui/const-generics/sneaky-array-repeat-expr.stderr index 5c77375d39934..4eab6b2e6a53a 100644 --- a/src/test/ui/const-generics/sneaky-array-repeat-expr.stderr +++ b/src/test/ui/const-generics/sneaky-array-repeat-expr.stderr @@ -6,13 +6,25 @@ LL | let bar = [(); <()>::Assoc]; | = note: this may fail depending on what value the parameter takes +error: failed to evaluate the given constant + --> $DIR/sneaky-array-repeat-expr.rs:11:20 + | +LL | let bar = [(); <()>::Assoc]; + | ^^^^^^^^^^^ + error: constant expression depends on a generic parameter - --> $DIR/sneaky-array-repeat-expr.rs:25:21 + --> $DIR/sneaky-array-repeat-expr.rs:26:21 | LL | let bar2 = [(); <()>::Assoc2]; | ^^^^^^^^^^^^ | = note: this may fail depending on what value the parameter takes -error: aborting due to 2 previous errors +error: failed to evaluate the given constant + --> $DIR/sneaky-array-repeat-expr.rs:26:21 + | +LL | let bar2 = [(); <()>::Assoc2]; + | ^^^^^^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3.rs index bcc966dc9621c..89e0011b7d10c 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3.rs +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3.rs @@ -17,6 +17,7 @@ const A_I8_I : [u32; (i8::MAX as usize) + 1] = [0; (i8::MAX + 1) as usize]; //~^ ERROR evaluation of constant value failed +//~| ERROR failed to evaluate the given constant fn main() { foo(&A_I8_I[..]); diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr index 73f421b5b1465..2d1cd5459125b 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of constant value failed LL | = [0; (i8::MAX + 1) as usize]; | ^^^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/const-eval-overflow-3.rs:18:11 + | +LL | = [0; (i8::MAX + 1) as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs index 480069e67fa28..20590026ad5b5 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs @@ -16,6 +16,7 @@ const A_I8_I = [0; (i8::MAX + 1u8) as usize]; //~^ ERROR mismatched types //~| ERROR cannot add `u8` to `i8` +//~| ERROR failed to evaluate fn main() { foo(&A_I8_I[..]); diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr index 2b96b66819286..249ac865b0e59 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -12,7 +12,13 @@ LL | = [0; (i8::MAX + 1u8) as usize]; | = help: the trait `Add` is not implemented for `i8` -error: aborting due to 2 previous errors +error: failed to evaluate the given constant + --> $DIR/const-eval-overflow-3b.rs:16:11 + | +LL | = [0; (i8::MAX + 1u8) as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr new file mode 100644 index 0000000000000..72e54f8ec21da --- /dev/null +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -0,0 +1,237 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:25:5 + | +LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc2, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:28:43 + | +LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:31:45 + | +LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:34:45 + | +LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:37:5 + | +LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc24, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:40:5 + | +LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:43:43 + | +LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:46:45 + | +LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:49:45 + | +LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:52:5 + | +LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc50, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:55:5 + | +LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:58:45 + | +LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:61:5 + | +LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc64, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:64:47 + | +LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; + | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:67:47 + | +LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; + | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:70:39 + | +LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; + | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:73:41 + | +LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:76:41 + | +LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:79:5 + | +LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc98, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:82:43 + | +LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:85:39 + | +LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; + | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:88:41 + | +LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:91:41 + | +LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:94:5 + | +LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc125, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:97:43 + | +LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:100:41 + | +LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-pointer-values-in-various-types.rs:103:5 + | +LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc140, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:106:43 + | +LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:109:43 + | +LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + +error: aborting due to 29 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index 14a573ccf5ac6..08cf043e867ab 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -1,11 +1,12 @@ fn main() { // Tests the Collatz conjecture with an incorrect base case (0 instead of 1). // The value of `n` will loop indefinitely (4 - 2 - 1 - 4). - let _ = [(); { + let _ = [(); { //~ ERROR failed to evaluate the given constant let mut n = 113383; // #20 in https://oeis.org/A006884 while n != 0 { n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; //~^ ERROR evaluation of constant value failed + //~| ERROR evaluation of constant value failed } n }]; diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 3b5a0f22f28be..9770435678984 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -4,6 +4,25 @@ error[E0080]: evaluation of constant value failed LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/infinite_loop.rs:4:18 + | +LL | let _ = [(); { + | __________________^ +LL | | let mut n = 113383; // #20 in https://oeis.org/A006884 +LL | | while n != 0 { +LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; +... | +LL | | n +LL | | }]; + | |_____^ + +error[E0080]: evaluation of constant value failed + --> $DIR/infinite_loop.rs:7:20 + | +LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; + | ^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index ce65407bbab0b..fe5d52e4b1e49 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -1,9 +1,11 @@ fn main() { - let _ = [(); { + let _ = [(); { //~ ERROR failed to evaluate the given constant let mut x = &0; let mut n = 0; while n < 5 { - n = (n + 1) % 5; //~ ERROR evaluation of constant value failed + n = (n + 1) % 5; + //~^ ERROR evaluation of constant value failed + //~| ERROR evaluation of constant value failed x = &0; // Materialize a new AllocId } 0 diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 8536ff02c6dae..aa09c2925c1f3 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -4,6 +4,25 @@ error[E0080]: evaluation of constant value failed LL | n = (n + 1) % 5; | ^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-52475.rs:2:18 + | +LL | let _ = [(); { + | __________________^ +LL | | let mut x = &0; +LL | | let mut n = 0; +LL | | while n < 5 { +... | +LL | | 0 +LL | | }]; + | |_____^ + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-52475.rs:6:17 + | +LL | n = (n + 1) % 5; + | ^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 4af97b5487929..7f2a2ed9a0f96 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -3,6 +3,7 @@ fn main() { // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw // bytes. let _: [u8; 0] = [4; { + //~^ ERROR failed to evaluate match &1 as *const i32 as usize { //~^ ERROR pointers cannot be cast to integers during const eval 0 => 42, diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index 05c3951c1284b..f9ca25f9f9997 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -1,5 +1,5 @@ error: pointers cannot be cast to integers during const eval - --> $DIR/match-test-ptr-null.rs:6:15 + --> $DIR/match-test-ptr-null.rs:7:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,5 +7,18 @@ LL | match &1 as *const i32 as usize { = note: at compile-time, pointers do not have an integer value = note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/match-test-ptr-null.rs:5:26 + | +LL | let _: [u8; 0] = [4; { + | __________________________^ +LL | | +LL | | match &1 as *const i32 as usize { +LL | | +... | +LL | | } +LL | | }]; + | |_____^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr index 4f7dd5cdf7c73..0d7d1f691ed0e 100644 --- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr @@ -13,22 +13,22 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:27:1 | LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .: encountered pointer to alloc9, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .: encountered pointer to alloc11, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc9────────╼ │ ╾──────╼ + ╾───────alloc11───────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:30:1 | LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0.: encountered pointer to alloc13, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0.: encountered pointer to alloc15, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc13───────╼ │ ╾──────╼ + ╾───────alloc15───────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value @@ -46,22 +46,22 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:44:1 | LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .: encountered pointer to alloc19, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .: encountered pointer to alloc21, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc19───────╼ │ ╾──────╼ + ╾───────alloc21───────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:47:1 | LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0.: encountered pointer to alloc23, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0.: encountered pointer to alloc25, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc23───────╼ │ ╾──────╼ + ╾───────alloc25───────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value @@ -79,11 +79,11 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:60:1 | LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .: encountered pointer to alloc29, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .: encountered pointer to alloc31, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc29───────╼ │ ╾──────╼ + ╾───────alloc31───────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 1067eb003f7c7..82fed16e06ca6 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `Foo: LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `Foo::bytes::{constant#0}`... - --> $DIR/const-size_of-cycle.rs:4:17 - | -LL | bytes: [u8; std::mem::size_of::()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... --> $DIR/const-size_of-cycle.rs:4:17 | diff --git a/src/test/ui/consts/issue-3521.fixed b/src/test/ui/consts/issue-3521.fixed index f76106dfff187..47f9c90b37629 100644 --- a/src/test/ui/consts/issue-3521.fixed +++ b/src/test/ui/consts/issue-3521.fixed @@ -7,6 +7,7 @@ fn main() { enum Stuff { Bar = foo //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR failed to evaluate } println!("{:?}", Stuff::Bar); diff --git a/src/test/ui/consts/issue-3521.rs b/src/test/ui/consts/issue-3521.rs index c425a22df9173..1c754019d2fdf 100644 --- a/src/test/ui/consts/issue-3521.rs +++ b/src/test/ui/consts/issue-3521.rs @@ -7,6 +7,7 @@ fn main() { enum Stuff { Bar = foo //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR failed to evaluate } println!("{:?}", Stuff::Bar); diff --git a/src/test/ui/consts/issue-3521.stderr b/src/test/ui/consts/issue-3521.stderr index aa42772f12d8a..5a50db450716f 100644 --- a/src/test/ui/consts/issue-3521.stderr +++ b/src/test/ui/consts/issue-3521.stderr @@ -7,6 +7,12 @@ LL | let foo: isize = 100; LL | Bar = foo | ^^^ non-constant value -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-3521.rs:8:15 + | +LL | Bar = foo + | ^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/consts/issue-36163.stderr b/src/test/ui/consts/issue-36163.stderr index 113f86cf0f99f..915cf4fafd7bd 100644 --- a/src/test/ui/consts/issue-36163.stderr +++ b/src/test/ui/consts/issue-36163.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `Foo: LL | B = A, | ^ | -note: ...which requires simplifying constant for the type system `Foo::B::{constant#0}`... - --> $DIR/issue-36163.rs:4:9 - | -LL | B = A, - | ^ note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`... --> $DIR/issue-36163.rs:4:9 | @@ -20,11 +15,6 @@ note: ...which requires simplifying constant for the type system `A`... | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `A`... - --> $DIR/issue-36163.rs:1:1 - | -LL | const A: isize = Foo::B as isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-36163.rs:1:1 | diff --git a/src/test/ui/consts/issue-44415.stderr b/src/test/ui/consts/issue-44415.stderr index 9e3db5ce9a402..4a9df8206ded1 100644 --- a/src/test/ui/consts/issue-44415.stderr +++ b/src/test/ui/consts/issue-44415.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `Foo: LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^ | -note: ...which requires simplifying constant for the type system `Foo::bytes::{constant#0}`... - --> $DIR/issue-44415.rs:6:17 - | -LL | bytes: [u8; unsafe { intrinsics::size_of::() }], - | ^^^^^^ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... --> $DIR/issue-44415.rs:6:17 | diff --git a/src/test/ui/consts/issue-52060.rs b/src/test/ui/consts/issue-52060.rs index 13b914c0331d1..c7983194f91bc 100644 --- a/src/test/ui/consts/issue-52060.rs +++ b/src/test/ui/consts/issue-52060.rs @@ -3,5 +3,6 @@ static A: &'static [u32] = &[1]; static B: [u32; 1] = [0; A.len()]; //~^ ERROR [E0013] +//~| ERROR failed to evaluate fn main() {} diff --git a/src/test/ui/consts/issue-52060.stderr b/src/test/ui/consts/issue-52060.stderr index 95e5f2a8282cb..0f73af6dffabb 100644 --- a/src/test/ui/consts/issue-52060.stderr +++ b/src/test/ui/consts/issue-52060.stderr @@ -6,6 +6,12 @@ LL | static B: [u32; 1] = [0; A.len()]; | = help: consider extracting the value of the `static` to a `const`, and referring to that -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-52060.rs:4:26 + | +LL | static B: [u32; 1] = [0; A.len()]; + | ^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/issue-66693-panic-in-array-len.rs b/src/test/ui/consts/issue-66693-panic-in-array-len.rs index fc0dcd7a44daa..b929bd3f351cf 100644 --- a/src/test/ui/consts/issue-66693-panic-in-array-len.rs +++ b/src/test/ui/consts/issue-66693-panic-in-array-len.rs @@ -9,6 +9,8 @@ fn main() { // ensure that conforming panics are handled correctly let _ = [false; panic!()]; //~^ ERROR: evaluation of constant value failed + //~| ERROR: evaluation of constant value failed + //~| ERROR failed to evaluate the given constant // typechecking halts before getting to this one let _ = ['a', panic!("panic in array len")]; diff --git a/src/test/ui/consts/issue-66693-panic-in-array-len.stderr b/src/test/ui/consts/issue-66693-panic-in-array-len.stderr index 4ccbeb73c8a25..1ff69c1faef0f 100644 --- a/src/test/ui/consts/issue-66693-panic-in-array-len.stderr +++ b/src/test/ui/consts/issue-66693-panic-in-array-len.stderr @@ -14,6 +14,22 @@ LL | let _ = [false; panic!()]; | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: failed to evaluate the given constant + --> $DIR/issue-66693-panic-in-array-len.rs:10:21 + | +LL | let _ = [false; panic!()]; + | ^^^^^^^^ + | + = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-66693-panic-in-array-len.rs:10:21 + | +LL | let _ = [false; panic!()]; + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:10:21 + | + = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/issue-91434.rs b/src/test/ui/consts/issue-91434.rs index fc7731291b371..20e37adbde606 100644 --- a/src/test/ui/consts/issue-91434.rs +++ b/src/test/ui/consts/issue-91434.rs @@ -3,4 +3,5 @@ fn main() { //~^ ERROR: expected at least one digit in exponent //~| ERROR: cannot find value `h` in this scope [E0425] //~| ERROR: constant expression depends on a generic parameter + //~| ERROR failed to evaluate } diff --git a/src/test/ui/consts/issue-91434.stderr b/src/test/ui/consts/issue-91434.stderr index 9d3fe5f201656..b5c9e09bd4c46 100644 --- a/src/test/ui/consts/issue-91434.stderr +++ b/src/test/ui/consts/issue-91434.stderr @@ -18,6 +18,12 @@ LL | [9; [[9E; h]]]; | = note: this may fail depending on what value the parameter takes -error: aborting due to 3 previous errors +error: failed to evaluate the given constant + --> $DIR/issue-91434.rs:2:9 + | +LL | [9; [[9E; h]]]; + | ^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/consts/recursive-zst-static.default.stderr b/src/test/ui/consts/recursive-zst-static.default.stderr index 03f8f5c5a0e5d..8d2cfd284e20f 100644 --- a/src/test/ui/consts/recursive-zst-static.default.stderr +++ b/src/test/ui/consts/recursive-zst-static.default.stderr @@ -4,12 +4,7 @@ error[E0391]: cycle detected when const-evaluating + checking `FOO` LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `FOO`... - --> $DIR/recursive-zst-static.rs:10:1 - | -LL | static FOO: () = FOO; - | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle + = note: ...which immediately requires const-evaluating + checking `FOO` again = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/consts/recursive-zst-static.unleash.stderr b/src/test/ui/consts/recursive-zst-static.unleash.stderr index 03f8f5c5a0e5d..8d2cfd284e20f 100644 --- a/src/test/ui/consts/recursive-zst-static.unleash.stderr +++ b/src/test/ui/consts/recursive-zst-static.unleash.stderr @@ -4,12 +4,7 @@ error[E0391]: cycle detected when const-evaluating + checking `FOO` LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `FOO`... - --> $DIR/recursive-zst-static.rs:10:1 - | -LL | static FOO: () = FOO; - | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle + = note: ...which immediately requires const-evaluating + checking `FOO` again = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/consts/too_generic_eval_ice.rs b/src/test/ui/consts/too_generic_eval_ice.rs index af494e3734914..a7eabbdc668de 100644 --- a/src/test/ui/consts/too_generic_eval_ice.rs +++ b/src/test/ui/consts/too_generic_eval_ice.rs @@ -6,7 +6,8 @@ impl Foo { pub fn crash() -> bool { [5; Self::HOST_SIZE] == [6; 0] //~^ ERROR constant expression depends on a generic parameter - //~| ERROR constant expression depends on a generic parameter + //~| ERROR failed to evaluate + //~| ERROR failed to evaluate //~| ERROR can't compare `[{integer}; _]` with `[{integer}; 0]` } } diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index ac104ed4a5a58..ec9c518313a7f 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -6,13 +6,17 @@ LL | [5; Self::HOST_SIZE] == [6; 0] | = note: this may fail depending on what value the parameter takes -error: constant expression depends on a generic parameter +error: failed to evaluate the given constant + --> $DIR/too_generic_eval_ice.rs:7:13 + | +LL | [5; Self::HOST_SIZE] == [6; 0] + | ^^^^^^^^^^^^^^^ + +error: failed to evaluate the given constant --> $DIR/too_generic_eval_ice.rs:7:30 | LL | [5; Self::HOST_SIZE] == [6; 0] | ^^ - | - = note: this may fail depending on what value the parameter takes error[E0277]: can't compare `[{integer}; _]` with `[{integer}; 0]` --> $DIR/too_generic_eval_ice.rs:7:30 @@ -22,6 +26,6 @@ LL | [5; Self::HOST_SIZE] == [6; 0] | = help: the trait `PartialEq<[{integer}; 0]>` is not implemented for `[{integer}; _]` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/write-to-static-mut-in-static.stderr b/src/test/ui/consts/write-to-static-mut-in-static.stderr index 789919bd1668d..8916ea3283565 100644 --- a/src/test/ui/consts/write-to-static-mut-in-static.stderr +++ b/src/test/ui/consts/write-to-static-mut-in-static.stderr @@ -10,12 +10,7 @@ error[E0391]: cycle detected when const-evaluating + checking `C` LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `C`... - --> $DIR/write-to-static-mut-in-static.rs:5:1 - | -LL | pub static mut C: u32 = unsafe { C = 1; 0 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `C`, completing the cycle + = note: ...which immediately requires const-evaluating + checking `C` again = note: cycle used when running analysis passes on this crate error: aborting due to 2 previous errors diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs index f927dd189038a..4dc28c7533221 100644 --- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs @@ -8,6 +8,7 @@ enum MyWeirdOption { None = 0, Some(T) = std::mem::size_of::(), //~^ ERROR generic parameters may not be used in const operations + //~| ERROR failed to evaluate } fn main() { diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr index e4e10468d5348..eb250529e0c22 100644 --- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr @@ -7,5 +7,11 @@ LL | Some(T) = std::mem::size_of::(), = note: type parameters may not be used in const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:15 + | +LL | Some(T) = std::mem::size_of::(), + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs index a0fb788a5109c..e3ae2ea57927a 100644 --- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs @@ -9,6 +9,7 @@ enum MyWeirdOption { None = 0, Some = std::mem::size_of::(), //~^ ERROR generic parameters may not be used in const operations + //~| ERROR failed to evaluate } fn main() { diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr index 7ea8a39129ead..2d1d9edb07e27 100644 --- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr @@ -7,6 +7,12 @@ LL | Some = std::mem::size_of::(), = note: type parameters may not be used in const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions +error: failed to evaluate the given constant + --> $DIR/issue-70453-generics-in-discr-ice.rs:10:12 + | +LL | Some = std::mem::size_of::(), + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0392]: parameter `T` is never used --> $DIR/issue-70453-generics-in-discr-ice.rs:7:20 | @@ -16,6 +22,6 @@ LL | enum MyWeirdOption { = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: usize` instead -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs index e62582fb5161a..2c7b53e791ffd 100644 --- a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs +++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs @@ -8,6 +8,7 @@ enum MyWeirdOption { None = 0, Some(T) = core::mem::size_of::<*mut T>(), //~^ ERROR generic parameters may not be used + //~| ERROR failed to evaluate } fn main() { diff --git a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr index 0a7a631606ee4..d0bc47daf2aff 100644 --- a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr +++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr @@ -7,5 +7,11 @@ LL | Some(T) = core::mem::size_of::<*mut T>(), = note: type parameters may not be used in const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-70453-polymorphic-ctfe.rs:9:15 + | +LL | Some(T) = core::mem::size_of::<*mut T>(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/enum/issue-67945-1.rs b/src/test/ui/enum/issue-67945-1.rs index f4697344cc7a4..5a757eff110a5 100644 --- a/src/test/ui/enum/issue-67945-1.rs +++ b/src/test/ui/enum/issue-67945-1.rs @@ -1,6 +1,8 @@ enum Bug { //~ ERROR parameter `S` is never used Var = { - let x: S = 0; //~ ERROR generic parameters may not be used + //~^ ERROR failed to evaluate the given + let x: S = 0; + //~^ ERROR generic parameters may not be used 0 }, } diff --git a/src/test/ui/enum/issue-67945-1.stderr b/src/test/ui/enum/issue-67945-1.stderr index 8f1b5b38e4c35..c45a9d4ccbb04 100644 --- a/src/test/ui/enum/issue-67945-1.stderr +++ b/src/test/ui/enum/issue-67945-1.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/issue-67945-1.rs:3:16 + --> $DIR/issue-67945-1.rs:4:16 | LL | let x: S = 0; | ^ cannot perform const operation using `S` @@ -7,6 +7,18 @@ LL | let x: S = 0; = note: type parameters may not be used in const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions +error: failed to evaluate the given constant + --> $DIR/issue-67945-1.rs:2:11 + | +LL | Var = { + | ___________^ +LL | | +LL | | let x: S = 0; +LL | | +LL | | 0 +LL | | }, + | |_____^ + error[E0392]: parameter `S` is never used --> $DIR/issue-67945-1.rs:1:10 | @@ -16,6 +28,6 @@ LL | enum Bug { = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `S` to be a const parameter, use `const S: usize` instead -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/enum/issue-67945-2.rs b/src/test/ui/enum/issue-67945-2.rs index e5044468da129..d271a809af843 100644 --- a/src/test/ui/enum/issue-67945-2.rs +++ b/src/test/ui/enum/issue-67945-2.rs @@ -3,6 +3,7 @@ enum Bug { //~ ERROR parameter `S` is never used Var = 0: S, //~^ ERROR generic parameters may not be used + //~| ERROR failed to evaluate the given } fn main() {} diff --git a/src/test/ui/enum/issue-67945-2.stderr b/src/test/ui/enum/issue-67945-2.stderr index 4f5e236a37b45..c601c9a47fc4c 100644 --- a/src/test/ui/enum/issue-67945-2.stderr +++ b/src/test/ui/enum/issue-67945-2.stderr @@ -7,6 +7,12 @@ LL | Var = 0: S, = note: type parameters may not be used in const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions +error: failed to evaluate the given constant + --> $DIR/issue-67945-2.rs:4:11 + | +LL | Var = 0: S, + | ^^^^ + error[E0392]: parameter `S` is never used --> $DIR/issue-67945-2.rs:3:10 | @@ -16,6 +22,6 @@ LL | enum Bug { = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `S` to be a const parameter, use `const S: usize` instead -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/generics/param-in-ct-in-ty-param-default.rs b/src/test/ui/generics/param-in-ct-in-ty-param-default.rs index 3c62e47381c0b..fabf304a32eed 100644 --- a/src/test/ui/generics/param-in-ct-in-ty-param-default.rs +++ b/src/test/ui/generics/param-in-ct-in-ty-param-default.rs @@ -1,4 +1,5 @@ struct Foo()]>(T, U); //~^ ERROR generic parameters may not be used in const operations +//~| ERROR failed to evaluate fn main() {} diff --git a/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr b/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr index ab09ebcae7197..6039e90ffbec9 100644 --- a/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr +++ b/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr @@ -7,5 +7,11 @@ LL | struct Foo()]>(T, U); = note: type parameters may not be used in const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/param-in-ct-in-ty-param-default.rs:1:15 + | +LL | struct Foo()]>(T, U); + | ^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index 1148577016ab4..86e81a0784830 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -5,11 +5,6 @@ note: ...which requires simplifying constant for the type system `FOO`... | LL | const FOO: usize = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `FOO`... - --> $DIR/issue-17252.rs:1:1 - | -LL | const FOO: usize = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `FOO`... --> $DIR/issue-17252.rs:1:1 | diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index d3a1993536a00..b71d07f10ea9c 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `X::A LL | A = X::A as isize, | ^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `X::A::{constant#0}`... - --> $DIR/issue-23302-1.rs:4:9 - | -LL | A = X::A as isize, - | ^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `X::A::{constant#0}`... --> $DIR/issue-23302-1.rs:4:9 | diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index d3b78ea1af5f5..94c68b6ae5e14 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `Y::A LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `Y::A::{constant#0}`... - --> $DIR/issue-23302-2.rs:4:9 - | -LL | A = Y::B as isize, - | ^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Y::A::{constant#0}`... --> $DIR/issue-23302-2.rs:4:9 | diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index 5233b832ecc79..441fcdcea04c4 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `A` LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ | -note: ...which requires simplifying constant for the type system `A`... - --> $DIR/issue-23302-3.rs:1:1 - | -LL | const A: i32 = B; - | ^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-23302-3.rs:1:1 | @@ -20,11 +15,6 @@ note: ...which requires simplifying constant for the type system `B`... | LL | const B: i32 = A; | ^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `B`... - --> $DIR/issue-23302-3.rs:3:1 - | -LL | const B: i32 = A; - | ^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `B`... --> $DIR/issue-23302-3.rs:3:1 | diff --git a/src/test/ui/issues/issue-39211.rs b/src/test/ui/issues/issue-39211.rs index c7b6f1d58f33d..b3d599844e5a7 100644 --- a/src/test/ui/issues/issue-39211.rs +++ b/src/test/ui/issues/issue-39211.rs @@ -10,6 +10,7 @@ trait Mat { fn m() { let a = [3; M::Row::DIM]; //~^ ERROR constant expression depends on a generic parameter + //~| ERROR failed to evaluate } fn main() { } diff --git a/src/test/ui/issues/issue-39211.stderr b/src/test/ui/issues/issue-39211.stderr index c555983ea68e0..aedfa7e3994d6 100644 --- a/src/test/ui/issues/issue-39211.stderr +++ b/src/test/ui/issues/issue-39211.stderr @@ -6,5 +6,11 @@ LL | let a = [3; M::Row::DIM]; | = note: this may fail depending on what value the parameter takes -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-39211.rs:11:17 + | +LL | let a = [3; M::Row::DIM]; + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs index 2c5257ce063cb..299ed39575873 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs @@ -19,4 +19,6 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` fn main() { let _ = [0; B::VALUE]; + //~^ ERROR evaluation of constant value failed + //~| ERROR failed to evaluate the given } diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr index 8ae0f8b804c93..91fa286cdd071 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr @@ -13,7 +13,19 @@ LL | type MyA: TraitA; LL | impl TraitB for B { | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation -error: aborting due to 2 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 + | +LL | let _ = [0; B::VALUE]; + | ^^^^^^^^ referenced constant has errors + +error: failed to evaluate the given constant + --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 + | +LL | let _ = [0; B::VALUE]; + | ^^^^^^^^ + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0046, E0437. +Some errors have detailed explanations: E0046, E0080, E0437. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index 966d76d148af3..43e75194ec93e 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,5 +1,6 @@ fn main() { [1; >::VAL]; + //~^ ERROR failed to evaluate } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index 97bd5ab36b65d..b72063678487a 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:9:9 + --> $DIR/issue-77919.rs:10:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:11:63 + --> $DIR/issue-77919.rs:12:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:11:1 + --> $DIR/issue-77919.rs:12:1 | LL | const VAL: T; | ------------- `VAL` from trait @@ -26,7 +26,13 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: aborting due to 3 previous errors +error: failed to evaluate the given constant + --> $DIR/issue-77919.rs:2:9 + | +LL | [1; >::VAL]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/mir/issue-80742.rs b/src/test/ui/mir/issue-80742.rs new file mode 100644 index 0000000000000..bf7d4e9ab3131 --- /dev/null +++ b/src/test/ui/mir/issue-80742.rs @@ -0,0 +1,34 @@ +// check-fail + +// This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +use std::fmt::Debug; +use std::marker::PhantomData; +use std::mem::size_of; + +struct Inline +where + [u8; size_of::() + 1]: , +{ + _phantom: PhantomData, + buf: [u8; size_of::() + 1], +} + +impl Inline +where + [u8; size_of::() + 1]: , +{ + pub fn new(val: T) -> Inline { + todo!() + } +} + +fn main() { + let dst = Inline::::new(0); + //~^ ERROR the function or associated item `new` exists for struct + //~| ERROR the size for values of type + //~| ERROR failed to evaluate +} diff --git a/src/test/ui/mir/issue-80742.stderr b/src/test/ui/mir/issue-80742.stderr new file mode 100644 index 0000000000000..ca8126e47ada1 --- /dev/null +++ b/src/test/ui/mir/issue-80742.stderr @@ -0,0 +1,73 @@ +error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied + --> $DIR/issue-80742.rs:30:36 + | +LL | / struct Inline +LL | | where +LL | | [u8; size_of::() + 1]: , +LL | | { +LL | | _phantom: PhantomData, +LL | | buf: [u8; size_of::() + 1], +LL | | } + | |_- function or associated item `new` not found for this +... +LL | let dst = Inline::::new(0); + | ^^^ function or associated item cannot be called on `Inline` due to unsatisfied trait bounds + | + ::: $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | +LL | pub trait Debug { + | --------------- doesn't satisfy `dyn Debug: Sized` + | + = note: the following trait bounds were not satisfied: + `dyn Debug: Sized` + +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/issue-80742.rs:30:15 + | +LL | let dst = Inline::::new(0); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by a bound in `Inline` + --> $DIR/issue-80742.rs:12:15 + | +LL | struct Inline + | ^ required by this bound in `Inline` +help: consider relaxing the implicit `Sized` restriction + | +LL | struct Inline + | ++++++++ + +error[E0080]: evaluation of `Inline::::{constant#0}` failed + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | +LL | intrinsics::size_of::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | size_of called on unsized type `dyn Debug` + | inside `std::mem::size_of::` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + ::: $DIR/issue-80742.rs:14:10 + | +LL | [u8; size_of::() + 1]: , + | -------------- inside `Inline::::{constant#0}` at $DIR/issue-80742.rs:14:10 + +error: failed to evaluate the given constant + --> $DIR/issue-80742.rs:30:15 + | +LL | let dst = Inline::::new(0); + | ^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `Inline` + --> $DIR/issue-80742.rs:14:10 + | +LL | struct Inline + | ------ required by a bound in this +LL | where +LL | [u8; size_of::() + 1]: , + | ^^^^^^^^^^^^^^^^^^ required by this bound in `Inline` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0080, E0277, E0599. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/recursion/recursive-static-definition.stderr b/src/test/ui/recursion/recursive-static-definition.stderr index ee73b026a0b75..56767f391531b 100644 --- a/src/test/ui/recursion/recursive-static-definition.stderr +++ b/src/test/ui/recursion/recursive-static-definition.stderr @@ -4,12 +4,7 @@ error[E0391]: cycle detected when const-evaluating + checking `FOO` LL | pub static FOO: u32 = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `FOO`... - --> $DIR/recursive-static-definition.rs:1:1 - | -LL | pub static FOO: u32 = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle + = note: ...which immediately requires const-evaluating + checking `FOO` again = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-50599.rs b/src/test/ui/resolve/issue-50599.rs index 00588735b9a59..00ce288fde019 100644 --- a/src/test/ui/resolve/issue-50599.rs +++ b/src/test/ui/resolve/issue-50599.rs @@ -2,4 +2,5 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; + //~^ ERROR failed to evaluate } diff --git a/src/test/ui/resolve/issue-50599.stderr b/src/test/ui/resolve/issue-50599.stderr index 7ec567a06f09d..d37c42f5565a3 100644 --- a/src/test/ui/resolve/issue-50599.stderr +++ b/src/test/ui/resolve/issue-50599.stderr @@ -11,6 +11,12 @@ LL | use std::f32::consts::LOG10_2; LL | use std::f64::consts::LOG10_2; | -error: aborting due to previous error +error: failed to evaluate the given constant + --> $DIR/issue-50599.rs:4:29 + | +LL | let mut digits = [0u32; M]; + | ^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.rs b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs index 4f076fa069383..f87109e317b3c 100644 --- a/src/test/ui/return/issue-86188-return-not-in-fn-body.rs +++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs @@ -8,6 +8,7 @@ const C: [(); 42] = { [(); return || { //~^ ERROR: return statement outside of function body [E0572] + //~| ERROR: failed to evaluate the given constant let tx; }] }; diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr index d7eeb3a729099..b134eb492832e 100644 --- a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr +++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr @@ -4,12 +4,24 @@ error[E0572]: return statement outside of function body LL | [(); return || { | __________^ LL | | +LL | | +LL | | let tx; +LL | | }] + | |_____^ + +error: failed to evaluate the given constant + --> $DIR/issue-86188-return-not-in-fn-body.rs:9:10 + | +LL | [(); return || { + | __________^ +LL | | +LL | | LL | | let tx; LL | | }] | |_____^ error[E0572]: return statement outside of function body - --> $DIR/issue-86188-return-not-in-fn-body.rs:20:14 + --> $DIR/issue-86188-return-not-in-fn-body.rs:21:14 | LL | / fn bar() { LL | | @@ -21,7 +33,7 @@ LL | | } | |_____- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-86188-return-not-in-fn-body.rs:28:14 + --> $DIR/issue-86188-return-not-in-fn-body.rs:29:14 | LL | / fn foo() { LL | | @@ -33,7 +45,7 @@ LL | | } | |_____- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-86188-return-not-in-fn-body.rs:36:10 + --> $DIR/issue-86188-return-not-in-fn-body.rs:37:10 | LL | / fn main() { LL | | @@ -47,6 +59,6 @@ LL | || }]; LL | | } | |_- ...not the enclosing function body -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0572`. diff --git a/src/test/ui/treat-err-as-bug/err.stderr b/src/test/ui/treat-err-as-bug/err.stderr index 8f67571c2990e..40dc0a8685b20 100644 --- a/src/test/ui/treat-err-as-bug/err.stderr +++ b/src/test/ui/treat-err-as-bug/err.stderr @@ -8,5 +8,5 @@ error: internal compiler error: unexpected panic query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `C` -#1 [eval_to_allocation_raw] const-evaluating + checking `C` +#1 [analysis] running analysis passes on this crate end of query stack diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr index 277f4e8424030..c0f67b2889a99 100644 --- a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -4,11 +4,6 @@ error[E0391]: cycle detected when simplifying constant for the type system `Alph LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^ | -note: ...which requires simplifying constant for the type system `Alpha::V3::{constant#0}`... - --> $DIR/self-in-enum-definition.rs:5:10 - | -LL | V3 = Self::V1 {} as u8 + 2, - | ^^^^^^^^ note: ...which requires const-evaluating + checking `Alpha::V3::{constant#0}`... --> $DIR/self-in-enum-definition.rs:5:10 | diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 074ba9e92ba4d..d3b251705b604 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -134,7 +134,7 @@ fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { fn is_value_unfrozen_raw<'tcx>( cx: &LateContext<'tcx>, - result: Result, ErrorHandled>, + result: Result, ErrorHandled<'tcx>>, ty: Ty<'tcx>, ) -> bool { fn inner<'tcx>(cx: &LateContext<'tcx>, val: &'tcx Const<'tcx>) -> bool {