Auto merge of #115748 - RalfJung:post-mono, r=oli-obk

move required_consts check to general post-mono-check function

This factors some code that is common between the interpreter and the codegen backends into shared helper functions. Also as a side-effect the interpreter now uses the same `eval` functions as everyone else to get the evaluated MIR constants.

Also this is in preparation for another post-mono check that will be needed for (the current hackfix for) https://github.com/rust-lang/rust/issues/115709: ensuring that all locals are dynamically sized.

I didn't expect this to change diagnostics, but it's just cycle errors that change.

r? `@oli-obk`
This commit is contained in:
bors 2023-09-18 19:41:21 +00:00
commit cebb9cfd4f
76 changed files with 385 additions and 361 deletions

View File

@ -250,7 +250,10 @@ pub(crate) fn verify_func(
} }
fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
if !crate::constant::check_constants(fx) { if let Err(err) =
fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
{
err.emit_err(fx.tcx);
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
// compilation should have been aborted // compilation should have been aborted

View File

@ -2,9 +2,7 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{ use rustc_middle::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalAlloc, Scalar};
read_target_uint, AllocId, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
};
use cranelift_module::*; use cranelift_module::*;
@ -33,16 +31,6 @@ impl ConstantCx {
} }
} }
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
let mut all_constants_ok = true;
for constant in &fx.mir.required_consts {
if eval_mir_constant(fx, constant).is_none() {
all_constants_ok = false;
}
}
all_constants_ok
}
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) { pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) {
let mut constants_cx = ConstantCx::new(); let mut constants_cx = ConstantCx::new();
constants_cx.todo.push(TodoItem::Static(def_id)); constants_cx.todo.push(TodoItem::Static(def_id));
@ -76,30 +64,20 @@ pub(crate) fn codegen_tls_ref<'tcx>(
pub(crate) fn eval_mir_constant<'tcx>( pub(crate) fn eval_mir_constant<'tcx>(
fx: &FunctionCx<'_, '_, 'tcx>, fx: &FunctionCx<'_, '_, 'tcx>,
constant: &Constant<'tcx>, constant: &Constant<'tcx>,
) -> Option<(ConstValue<'tcx>, Ty<'tcx>)> { ) -> (ConstValue<'tcx>, Ty<'tcx>) {
let cv = fx.monomorphize(constant.literal); let cv = fx.monomorphize(constant.literal);
// This cannot fail because we checked all required_consts in advance.
let val = cv let val = cv
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
.map_err(|err| match err { .expect("erroneous constant not captured by required_consts");
ErrorHandled::Reported(_) => { (val, cv.ty())
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
}
ErrorHandled::TooGeneric => {
span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
}
})
.ok();
val.map(|val| (val, cv.ty()))
} }
pub(crate) fn codegen_constant_operand<'tcx>( pub(crate) fn codegen_constant_operand<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
constant: &Constant<'tcx>, constant: &Constant<'tcx>,
) -> CValue<'tcx> { ) -> CValue<'tcx> {
let (const_val, ty) = eval_mir_constant(fx, constant).unwrap_or_else(|| { let (const_val, ty) = eval_mir_constant(fx, constant);
span_bug!(constant.span, "erroneous constant not captured by required_consts")
});
codegen_const_value(fx, const_val, ty) codegen_const_value(fx, const_val, ty)
} }
@ -459,7 +437,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
operand: &Operand<'tcx>, operand: &Operand<'tcx>,
) -> Option<ConstValue<'tcx>> { ) -> Option<ConstValue<'tcx>> {
match operand { match operand {
Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).unwrap().0), Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).0),
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
// inside a temporary before being passed to the intrinsic requiring the const argument. // inside a temporary before being passed to the intrinsic requiring the const argument.
// This code tries to find a single constant defining definition of the referenced local. // This code tries to find a single constant defining definition of the referenced local.

View File

@ -242,8 +242,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
} }
} }
InlineAsmOperand::Const { ref value } => { InlineAsmOperand::Const { ref value } => {
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value) let (const_value, ty) = crate::constant::eval_mir_constant(fx, value);
.unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved"));
let value = rustc_codegen_ssa::common::asm_const_to_str( let value = rustc_codegen_ssa::common::asm_const_to_str(
fx.tcx, fx.tcx,
span, span,

View File

@ -19,8 +19,6 @@ codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$e
codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
codegen_ssa_erroneous_constant = erroneous constant encountered
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error} codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)` codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)`
@ -174,8 +172,6 @@ codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric
codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
.note = {$output} .note = {$output}

View File

@ -595,20 +595,6 @@ pub struct InvalidWindowsSubsystem {
pub subsystem: Symbol, pub subsystem: Symbol,
} }
#[derive(Diagnostic)]
#[diag(codegen_ssa_erroneous_constant)]
pub struct ErroneousConstant {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_polymorphic_constant_too_generic)]
pub struct PolymorphicConstantTooGeneric {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(codegen_ssa_shuffle_indices_evaluation)] #[diag(codegen_ssa_shuffle_indices_evaluation)]
pub struct ShuffleIndicesEvaluation { pub struct ShuffleIndicesEvaluation {

View File

@ -1088,9 +1088,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
InlineAsmOperandRef::InOut { reg, late, in_value, out_place } InlineAsmOperandRef::InOut { reg, late, in_value, out_place }
} }
mir::InlineAsmOperand::Const { ref value } => { mir::InlineAsmOperand::Const { ref value } => {
let const_value = self let const_value = self.eval_mir_constant(value);
.eval_mir_constant(value)
.unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved"));
let string = common::asm_const_to_str( let string = common::asm_const_to_str(
bx.tcx(), bx.tcx(),
span, span,

View File

@ -14,34 +14,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&self, &self,
bx: &mut Bx, bx: &mut Bx,
constant: &mir::Constant<'tcx>, constant: &mir::Constant<'tcx>,
) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> { ) -> OperandRef<'tcx, Bx::Value> {
let val = self.eval_mir_constant(constant)?; let val = self.eval_mir_constant(constant);
let ty = self.monomorphize(constant.ty()); let ty = self.monomorphize(constant.ty());
Ok(OperandRef::from_const(bx, val, ty)) OperandRef::from_const(bx, val, ty)
} }
pub fn eval_mir_constant( pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> ConstValue<'tcx> {
&self,
constant: &mir::Constant<'tcx>,
) -> Result<ConstValue<'tcx>, ErrorHandled> {
self.monomorphize(constant.literal) self.monomorphize(constant.literal)
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span)) .eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
.map_err(|err| { .expect("erroneous constant not captured by required_consts")
match err {
ErrorHandled::Reported(_) => {
self.cx
.tcx()
.sess
.emit_err(errors::ErroneousConstant { span: constant.span });
}
ErrorHandled::TooGeneric => {
self.cx.tcx().sess.diagnostic().emit_bug(
errors::PolymorphicConstantTooGeneric { span: constant.span },
);
}
}
err
})
} }
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition /// This is a convenience helper for `simd_shuffle_indices`. It has the precondition

View File

@ -579,23 +579,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if let Some(dbg_var) = dbg_var { if let Some(dbg_var) = dbg_var {
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) { let operand = self.eval_mir_constant_to_operand(bx, &c);
self.set_debug_loc(bx, var.source_info); self.set_debug_loc(bx, var.source_info);
let base = Self::spill_operand_to_stack( let base =
operand, Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
Some(var.name.to_string()),
bx,
);
bx.dbg_var_addr( bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[], fragment);
dbg_var,
dbg_loc,
base.llval,
Size::ZERO,
&[],
fragment,
);
}
} }
} }
} }

View File

@ -3,7 +3,6 @@ use crate::traits::*;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::mir::traversal; use rustc_middle::mir::traversal;
use rustc_middle::mir::UnwindTerminateReason; use rustc_middle::mir::UnwindTerminateReason;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
@ -212,23 +211,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx); fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
// Evaluate all required consts; codegen later assumes that CTFE will never fail. // Rust post-monomorphization checks; we later rely on them.
let mut all_consts_ok = true; if let Err(err) =
for const_ in &mir.required_consts { mir.post_mono_checks(cx.tcx(), ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
if let Err(err) = fx.eval_mir_constant(const_) { {
all_consts_ok = false; err.emit_err(cx.tcx());
match err { // This IR shouldn't ever be emitted, but let's try to guard against any of this code
// errored or at least linted // ever running.
ErrorHandled::Reported(_) => {} start_bx.abort();
ErrorHandled::TooGeneric => {
span_bug!(const_.span, "codegen encountered polymorphic constant: {:?}", err)
}
}
}
}
if !all_consts_ok {
// We leave the IR in some half-built state here, and rely on this code not even being
// submitted to LLVM once an error was raised.
return; return;
} }

View File

@ -575,12 +575,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.codegen_consume(bx, place.as_ref()) self.codegen_consume(bx, place.as_ref())
} }
mir::Operand::Constant(ref constant) => { mir::Operand::Constant(ref constant) => self.eval_mir_constant_to_operand(bx, constant),
// This cannot fail because we checked all required_consts in advance.
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| {
span_bug!(constant.span, "erroneous constant not captured by required_consts")
})
}
} }
} }
} }

View File

@ -83,9 +83,6 @@ const_eval_dyn_call_vtable_mismatch =
const_eval_dyn_star_call_vtable_mismatch = const_eval_dyn_star_call_vtable_mismatch =
`dyn*` call on a pointer whose vtable does not match its type `dyn*` call on a pointer whose vtable does not match its type
const_eval_erroneous_constant =
erroneous constant used
const_eval_error = {$error_kind -> const_eval_error = {$error_kind ->
[static] could not evaluate static initializer [static] could not evaluate static initializer
[const] evaluation of constant value failed [const] evaluation of constant value failed

View File

@ -4,7 +4,7 @@ use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, IntoDiagnostic, IntoDi
use rustc_middle::mir::AssertKind; use rustc_middle::mir::AssertKind;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{layout::LayoutError, ConstInt}; use rustc_middle::ty::{layout::LayoutError, ConstInt};
use rustc_span::{ErrorGuaranteed, Span, Symbol}; use rustc_span::{ErrorGuaranteed, Span, Symbol, DUMMY_SP};
use super::InterpCx; use super::InterpCx;
use crate::errors::{self, FrameNote, ReportErrorExt}; use crate::errors::{self, FrameNote, ReportErrorExt};
@ -134,11 +134,11 @@ where
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or // Don't emit a new diagnostic for these errors, they are already reported elsewhere or
// should remain silent. // should remain silent.
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
ErrorHandled::TooGeneric ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))
} }
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar), err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span.unwrap_or(DUMMY_SP)),
err_inval!(Layout(LayoutError::ReferencesError(guar))) => { err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
ErrorHandled::Reported(guar.into()) ErrorHandled::Reported(guar.into(), span.unwrap_or(DUMMY_SP))
} }
// Report remaining errors. // Report remaining errors.
_ => { _ => {
@ -152,7 +152,7 @@ where
// Use *our* span to label the interp error // Use *our* span to label the interp error
err.span_label(our_span, msg); err.span_label(our_span, msg);
ErrorHandled::Reported(err.emit().into()) ErrorHandled::Reported(err.emit().into(), span)
} }
} }
} }

View File

@ -212,7 +212,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
key.param_env = key.param_env.with_user_facing(); key.param_env = key.param_env.with_user_facing();
match tcx.eval_to_const_value_raw(key) { match tcx.eval_to_const_value_raw(key) {
// try again with reveal all as requested // try again with reveal all as requested
Err(ErrorHandled::TooGeneric) => {} Err(ErrorHandled::TooGeneric(_)) => {}
// deduplicate calls // deduplicate calls
other => return other, other => return other,
} }
@ -259,7 +259,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
key.param_env = key.param_env.with_user_facing(); key.param_env = key.param_env.with_user_facing();
match tcx.eval_to_allocation_raw(key) { match tcx.eval_to_allocation_raw(key) {
// try again with reveal all as requested // try again with reveal all as requested
Err(ErrorHandled::TooGeneric) => {} Err(ErrorHandled::TooGeneric(_)) => {}
// deduplicate calls // deduplicate calls
other => return other, other => return other,
} }

View File

@ -239,13 +239,6 @@ pub struct LongRunningWarn {
pub item_span: Span, pub item_span: Span,
} }
#[derive(Diagnostic)]
#[diag(const_eval_erroneous_constant)]
pub(crate) struct ErroneousConstUsed {
#[primary_span]
pub span: Span,
}
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[note(const_eval_non_const_impl)] #[note(const_eval_non_const_impl)]
pub(crate) struct NonConstImplNote { pub(crate) struct NonConstImplNote {

View File

@ -7,7 +7,7 @@ use hir::CRATE_HIR_ID;
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
use rustc_middle::query::TyCtxtAt; use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{ use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
@ -21,10 +21,10 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou
use super::{ use super::{
AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace,
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, Pointer, PointerArithmetic, MemPlaceMeta, Memory, MemoryKind, OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic,
Projectable, Provenance, Scalar, StackPopJump, Projectable, Provenance, Scalar, StackPopJump,
}; };
use crate::errors::{self, ErroneousConstUsed}; use crate::errors;
use crate::util; use crate::util;
use crate::{fluent_generated as fluent, ReportErrorExt}; use crate::{fluent_generated as fluent, ReportErrorExt};
@ -556,7 +556,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
>( >(
&self, &self,
value: T, value: T,
) -> Result<T, InterpError<'tcx>> { ) -> Result<T, ErrorHandled> {
self.subst_from_frame_and_normalize_erasing_regions(self.frame(), value) self.subst_from_frame_and_normalize_erasing_regions(self.frame(), value)
} }
@ -566,7 +566,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&self, &self,
frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>,
value: T, value: T,
) -> Result<T, InterpError<'tcx>> { ) -> Result<T, ErrorHandled> {
frame frame
.instance .instance
.try_subst_mir_and_normalize_erasing_regions( .try_subst_mir_and_normalize_erasing_regions(
@ -574,7 +574,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.param_env, self.param_env,
ty::EarlyBinder::bind(value), ty::EarlyBinder::bind(value),
) )
.map_err(|_| err_inval!(TooGeneric)) .map_err(|_| ErrorHandled::TooGeneric(self.cur_span()))
} }
/// The `args` are assumed to already be in our interpreter "universe" (param_env). /// The `args` are assumed to already be in our interpreter "universe" (param_env).
@ -750,11 +750,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
if M::POST_MONO_CHECKS { if M::POST_MONO_CHECKS {
for ct in &body.required_consts { // `ctfe_query` does some error message decoration that we want to be in effect here.
let span = ct.span; self.ctfe_query(None, |tcx| {
let ct = self.subst_from_current_frame_and_normalize_erasing_regions(ct.literal)?; body.post_mono_checks(*tcx, self.param_env, |c| {
self.eval_mir_constant(&ct, Some(span), None)?; self.subst_from_current_frame_and_normalize_erasing_regions(c)
} })
})?;
} }
// done // done
@ -1059,28 +1060,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&self, &self,
span: Option<Span>, span: Option<Span>,
query: impl FnOnce(TyCtxtAt<'tcx>) -> Result<T, ErrorHandled>, query: impl FnOnce(TyCtxtAt<'tcx>) -> Result<T, ErrorHandled>,
) -> InterpResult<'tcx, T> { ) -> Result<T, ErrorHandled> {
// Use a precise span for better cycle errors. // Use a precise span for better cycle errors.
query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| { query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| {
match err { err.emit_note(*self.tcx);
ErrorHandled::Reported(err) => { err
if !err.is_tainted_by_errors() && let Some(span) = span {
// To make it easier to figure out where this error comes from, also add a note at the current location.
self.tcx.sess.emit_note(ErroneousConstUsed { span });
}
err_inval!(AlreadyReported(err))
}
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
}
.into()
}) })
} }
pub fn eval_global( pub fn eval_global(
&self, &self,
gid: GlobalId<'tcx>, instance: ty::Instance<'tcx>,
span: Option<Span>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
let gid = GlobalId { instance, promoted: None };
// For statics we pick `ParamEnv::reveal_all`, because statics don't have generics // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
// and thus don't care about the parameter environment. While we could just use // and thus don't care about the parameter environment. While we could just use
// `self.param_env`, that would mean we invoke the query to evaluate the static // `self.param_env`, that would mean we invoke the query to evaluate the static
@ -1091,10 +1083,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} else { } else {
self.param_env self.param_env
}; };
let val = self.ctfe_query(span, |tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?; let val = self.ctfe_query(None, |tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?;
self.raw_const_to_mplace(val) self.raw_const_to_mplace(val)
} }
pub fn eval_mir_constant(
&self,
val: &mir::ConstantKind<'tcx>,
span: Option<Span>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
let const_val = self.ctfe_query(span, |tcx| val.eval(*tcx, self.param_env, span))?;
self.const_val_to_op(const_val, val.ty(), layout)
}
#[must_use] #[must_use]
pub fn dump_place( pub fn dump_place(
&self, &self,

View File

@ -8,15 +8,14 @@ use either::{Either, Left, Right};
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
use rustc_middle::ty::{ConstInt, Ty, ValTree}; use rustc_middle::ty::{ConstInt, Ty};
use rustc_middle::{mir, ty}; use rustc_middle::{mir, ty};
use rustc_span::Span;
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size}; use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size};
use super::{ use super::{
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId, alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, InterpCx,
InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable,
Projectable, Provenance, Scalar, Provenance, Scalar,
}; };
/// An `Immediate` represents a single immediate self-contained Rust value. /// An `Immediate` represents a single immediate self-contained Rust value.
@ -701,54 +700,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(op) Ok(op)
} }
fn eval_ty_constant(
&self,
val: ty::Const<'tcx>,
span: Option<Span>,
) -> InterpResult<'tcx, ValTree<'tcx>> {
Ok(match val.kind() {
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => {
throw_inval!(TooGeneric)
}
// FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated
ty::ConstKind::Expr(_) => throw_inval!(TooGeneric),
ty::ConstKind::Error(reported) => {
throw_inval!(AlreadyReported(reported.into()))
}
ty::ConstKind::Unevaluated(uv) => {
let instance = self.resolve(uv.def, uv.args)?;
let cid = GlobalId { instance, promoted: None };
self.ctfe_query(span, |tcx| tcx.eval_to_valtree(self.param_env.and(cid)))?
.unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"))
}
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {val:?}")
}
ty::ConstKind::Value(valtree) => valtree,
})
}
pub fn eval_mir_constant(
&self,
val: &mir::ConstantKind<'tcx>,
span: Option<Span>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
match *val {
mir::ConstantKind::Ty(ct) => {
let ty = ct.ty();
let valtree = self.eval_ty_constant(ct, span)?;
let const_val = self.tcx.valtree_to_const_val((ty, valtree));
self.const_val_to_op(const_val, ty, layout)
}
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
mir::ConstantKind::Unevaluated(uv, _) => {
let instance = self.resolve(uv.def, uv.args)?;
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
}
}
}
pub(crate) fn const_val_to_op( pub(crate) fn const_val_to_op(
&self, &self,
val_val: ConstValue<'tcx>, val_val: ConstValue<'tcx>,

View File

@ -1600,9 +1600,12 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? { if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args)); let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
if let Err(e) = ct.error_reported() { if let Err(e) = ct.error_reported() {
return Err(ErrorHandled::Reported(e.into())); return Err(ErrorHandled::Reported(
e.into(),
span.unwrap_or(rustc_span::DUMMY_SP),
));
} else if ct.has_non_region_infer() || ct.has_non_region_param() { } else if ct.has_non_region_infer() || ct.has_non_region_param() {
return Err(ErrorHandled::TooGeneric); return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP)));
} else { } else {
args = replace_param_and_infer_args_with_placeholder(tcx, args); args = replace_param_and_infer_args_with_placeholder(tcx, args);
} }

View File

@ -52,6 +52,8 @@ middle_drop_check_overflow =
overflow while adding drop-check rules for {$ty} overflow while adding drop-check rules for {$ty}
.note = overflowed on {$overflow_ty} .note = overflowed on {$overflow_ty}
middle_erroneous_constant = erroneous constant encountered
middle_layout_references_error = middle_layout_references_error =
the type has an unknown layout the type has an unknown layout

View File

@ -144,5 +144,12 @@ pub struct UnsupportedFnAbi {
pub abi: &'static str, pub abi: &'static str,
} }
#[derive(Diagnostic)]
#[diag(middle_erroneous_constant)]
pub struct ErroneousConstant {
#[primary_span]
pub span: Span,
}
/// Used by `rustc_const_eval` /// Used by `rustc_const_eval`
pub use crate::fluent_generated::middle_adjust_for_foreign_abi_error; pub use crate::fluent_generated::middle_adjust_for_foreign_abi_error;

View File

@ -1,8 +1,9 @@
use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar}; use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar};
use crate::error;
use crate::mir::interpret::ConstValue; use crate::mir::interpret::ConstValue;
use crate::query::TyCtxtAt; use crate::query::TyCtxtAt;
use crate::ty::{layout, tls, Ty, ValTree}; use crate::ty::{layout, tls, Ty, TyCtxt, ValTree};
use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::Lock;
use rustc_errors::{ use rustc_errors::{
@ -11,7 +12,7 @@ use rustc_errors::{
}; };
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_session::CtfeBacktrace; use rustc_session::CtfeBacktrace;
use rustc_span::def_id::DefId; use rustc_span::{def_id::DefId, Span, DUMMY_SP};
use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange}; use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange};
use std::borrow::Cow; use std::borrow::Cow;
@ -21,16 +22,51 @@ use std::{any::Any, backtrace::Backtrace, fmt};
pub enum ErrorHandled { pub enum ErrorHandled {
/// Already reported an error for this evaluation, and the compilation is /// Already reported an error for this evaluation, and the compilation is
/// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
Reported(ReportedErrorInfo), Reported(ReportedErrorInfo, Span),
/// Don't emit an error, the evaluation failed because the MIR was generic /// Don't emit an error, the evaluation failed because the MIR was generic
/// and the args didn't fully monomorphize it. /// and the args didn't fully monomorphize it.
TooGeneric, TooGeneric(Span),
} }
impl From<ErrorGuaranteed> for ErrorHandled { impl From<ErrorGuaranteed> for ErrorHandled {
#[inline] #[inline]
fn from(error: ErrorGuaranteed) -> ErrorHandled { fn from(error: ErrorGuaranteed) -> ErrorHandled {
ErrorHandled::Reported(error.into()) ErrorHandled::Reported(error.into(), DUMMY_SP)
}
}
impl ErrorHandled {
pub fn with_span(self, span: Span) -> Self {
match self {
ErrorHandled::Reported(err, _span) => ErrorHandled::Reported(err, span),
ErrorHandled::TooGeneric(_span) => ErrorHandled::TooGeneric(span),
}
}
pub fn emit_err(&self, tcx: TyCtxt<'_>) -> ErrorGuaranteed {
match self {
&ErrorHandled::Reported(err, span) => {
if !err.is_tainted_by_errors && !span.is_dummy() {
tcx.sess.emit_err(error::ErroneousConstant { span });
}
err.error
}
&ErrorHandled::TooGeneric(span) => tcx.sess.delay_span_bug(
span,
"encountered TooGeneric error when monomorphic data was expected",
),
}
}
pub fn emit_note(&self, tcx: TyCtxt<'_>) {
match self {
&ErrorHandled::Reported(err, span) => {
if !err.is_tainted_by_errors && !span.is_dummy() {
tcx.sess.emit_note(error::ErroneousConstant { span });
}
}
&ErrorHandled::TooGeneric(_) => {}
}
} }
} }
@ -45,12 +81,6 @@ impl ReportedErrorInfo {
pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
ReportedErrorInfo { is_tainted_by_errors: true, error } ReportedErrorInfo { is_tainted_by_errors: true, error }
} }
/// Returns true if evaluation failed because MIR was tainted by errors.
#[inline]
pub fn is_tainted_by_errors(self) -> bool {
self.is_tainted_by_errors
}
} }
impl From<ErrorGuaranteed> for ReportedErrorInfo { impl From<ErrorGuaranteed> for ReportedErrorInfo {
@ -162,6 +192,16 @@ impl From<ErrorGuaranteed> for InterpErrorInfo<'_> {
} }
} }
impl From<ErrorHandled> for InterpErrorInfo<'_> {
fn from(err: ErrorHandled) -> Self {
InterpError::InvalidProgram(match err {
ErrorHandled::Reported(r, _span) => InvalidProgramInfo::AlreadyReported(r),
ErrorHandled::TooGeneric(_span) => InvalidProgramInfo::TooGeneric,
})
.into()
}
}
impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> { impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
fn from(kind: InterpError<'tcx>) -> Self { fn from(kind: InterpError<'tcx>) -> Self {
InterpErrorInfo(Box::new(InterpErrorInfoInner { InterpErrorInfo(Box::new(InterpErrorInfoInner {

View File

@ -61,8 +61,10 @@ impl<'tcx> TyCtxt<'tcx> {
let cid = GlobalId { instance, promoted: ct.promoted }; let cid = GlobalId { instance, promoted: ct.promoted };
self.const_eval_global_id(param_env, cid, span) self.const_eval_global_id(param_env, cid, span)
} }
Ok(None) => Err(ErrorHandled::TooGeneric), // For errors during resolution, we deliberately do not point at the usage site of the constant,
Err(err) => Err(ErrorHandled::Reported(err.into())), // since for these errors the place the constant is used shouldn't matter.
Ok(None) => Err(ErrorHandled::TooGeneric(DUMMY_SP)),
Err(err) => Err(ErrorHandled::Reported(err.into(), DUMMY_SP)),
} }
} }
@ -117,8 +119,10 @@ impl<'tcx> TyCtxt<'tcx> {
} }
}) })
} }
Ok(None) => Err(ErrorHandled::TooGeneric), // For errors during resolution, we deliberately do not point at the usage site of the constant,
Err(err) => Err(ErrorHandled::Reported(err.into())), // since for these errors the place the constant is used shouldn't matter.
Ok(None) => Err(ErrorHandled::TooGeneric(DUMMY_SP)),
Err(err) => Err(ErrorHandled::Reported(err.into(), DUMMY_SP)),
} }
} }
@ -143,7 +147,8 @@ impl<'tcx> TyCtxt<'tcx> {
// improve caching of queries. // improve caching of queries.
let inputs = self.erase_regions(param_env.and(cid)); let inputs = self.erase_regions(param_env.and(cid));
if let Some(span) = span { if let Some(span) = span {
self.at(span).eval_to_const_value_raw(inputs) // The query doesn't know where it is being invoked, so we need to fix the span.
self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
} else { } else {
self.eval_to_const_value_raw(inputs) self.eval_to_const_value_raw(inputs)
} }
@ -162,7 +167,8 @@ impl<'tcx> TyCtxt<'tcx> {
let inputs = self.erase_regions(param_env.and(cid)); let inputs = self.erase_regions(param_env.and(cid));
debug!(?inputs); debug!(?inputs);
if let Some(span) = span { if let Some(span) = span {
self.at(span).eval_to_valtree(inputs) // The query doesn't know where it is being invoked, so we need to fix the span.
self.at(span).eval_to_valtree(inputs).map_err(|e| e.with_span(span))
} else { } else {
self.eval_to_valtree(inputs) self.eval_to_valtree(inputs)
} }

View File

@ -565,6 +565,34 @@ impl<'tcx> Body<'tcx> {
pub fn is_custom_mir(&self) -> bool { pub fn is_custom_mir(&self) -> bool {
self.injection_phase.is_some() self.injection_phase.is_some()
} }
/// *Must* be called once the full substitution for this body is known, to ensure that the body
/// is indeed fit for code generation or consumption more generally.
///
/// Sadly there's no nice way to represent an "arbitrary normalizer", so we take one for
/// constants specifically. (`Option<GenericArgsRef>` could be used for that, but the fact
/// that `Instance::args_for_mir_body` is private and instead instance exposes normalization
/// functions makes it seem like exposing the generic args is not the intended strategy.)
///
/// Also sadly, CTFE doesn't even know whether it runs on MIR that is already polymorphic or still monomorphic,
/// so we cannot just immediately ICE on TooGeneric.
///
/// Returns Ok(()) if everything went fine, and `Err` if a problem occurred and got reported.
pub fn post_mono_checks(
&self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
normalize_const: impl Fn(ConstantKind<'tcx>) -> Result<ConstantKind<'tcx>, ErrorHandled>,
) -> Result<(), ErrorHandled> {
// For now, the only thing we have to check is is to ensure that all the constants used in
// the body successfully evaluate.
for &const_ in &self.required_consts {
let c = normalize_const(const_.literal)?;
c.eval(tcx, param_env, Some(const_.span))?;
}
Ok(())
}
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
@ -2397,10 +2425,10 @@ impl<'tcx> ConstantKind<'tcx> {
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
match self.eval(tcx, param_env, None) { match self.eval(tcx, param_env, None) {
Ok(val) => Self::Val(val, self.ty()), Ok(val) => Self::Val(val, self.ty()),
Err(ErrorHandled::Reported(guar)) => { Err(ErrorHandled::Reported(guar, _span)) => {
Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty())) Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty()))
} }
Err(ErrorHandled::TooGeneric) => self, Err(ErrorHandled::TooGeneric(_span)) => self,
} }
} }

View File

@ -478,8 +478,8 @@ impl<'tcx> AdtDef<'tcx> {
} }
Err(err) => { Err(err) => {
let msg = match err { let msg = match err {
ErrorHandled::Reported(_) => "enum discriminant evaluation failed", ErrorHandled::Reported(..) => "enum discriminant evaluation failed",
ErrorHandled::TooGeneric => "enum discriminant depends on generics", ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics",
}; };
tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg); tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg);
None None

View File

@ -300,7 +300,7 @@ impl<'tcx> Const<'tcx> {
| ConstKind::Infer(_) | ConstKind::Infer(_)
| ConstKind::Bound(_, _) | ConstKind::Bound(_, _)
| ConstKind::Placeholder(_) | ConstKind::Placeholder(_)
| ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric), | ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))),
} }
} }
@ -309,8 +309,8 @@ impl<'tcx> Const<'tcx> {
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
match self.eval(tcx, param_env, None) { match self.eval(tcx, param_env, None) {
Ok(val) => Self::new_value(tcx, val, self.ty()), Ok(val) => Self::new_value(tcx, val, self.ty()),
Err(ErrorHandled::Reported(r)) => Self::new_error(tcx, r.into(), self.ty()), Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into(), self.ty()),
Err(ErrorHandled::TooGeneric) => self, Err(ErrorHandled::TooGeneric(_span)) => self,
} }
} }

View File

@ -566,7 +566,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
pattern pattern
} }
} }
Err(ErrorHandled::TooGeneric) => { Err(ErrorHandled::TooGeneric(_)) => {
// While `Reported | Linted` cases will have diagnostics emitted already // While `Reported | Linted` cases will have diagnostics emitted already
// it is not true for TooGeneric case, so we need to give user more information. // it is not true for TooGeneric case, so we need to give user more information.
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
@ -640,14 +640,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.kind .kind
} else { } else {
// If that fails, convert it to an opaque constant pattern. // If that fails, convert it to an opaque constant pattern.
match tcx.const_eval_resolve(self.param_env, uneval, None) { match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) {
Ok(val) => self.const_to_pat(mir::ConstantKind::Val(val, ty), id, span, None).kind, Ok(val) => self.const_to_pat(mir::ConstantKind::Val(val, ty), id, span, None).kind,
Err(ErrorHandled::TooGeneric) => { Err(ErrorHandled::TooGeneric(_)) => {
// If we land here it means the const can't be evaluated because it's `TooGeneric`. // If we land here it means the const can't be evaluated because it's `TooGeneric`.
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
PatKind::Wild PatKind::Wild
} }
Err(ErrorHandled::Reported(_)) => PatKind::Wild, Err(ErrorHandled::Reported(..)) => PatKind::Wild,
} }
} }
} }

View File

@ -752,8 +752,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
let val = match literal.eval(self.tcx, param_env, None) { let val = match literal.eval(self.tcx, param_env, None) {
Ok(v) => v, Ok(v) => v,
Err(ErrorHandled::Reported(_)) => return, Err(ErrorHandled::Reported(..)) => return,
Err(ErrorHandled::TooGeneric) => span_bug!( Err(ErrorHandled::TooGeneric(..)) => span_bug!(
self.body.source_info(location).span, self.body.source_info(location).span,
"collection encountered polymorphic constant: {:?}", "collection encountered polymorphic constant: {:?}",
literal literal

View File

@ -956,8 +956,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, None) { match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, None) {
Ok(ct) => Some(ct), Ok(ct) => Some(ct),
Err(ErrorHandled::Reported(e)) => Some(ty::Const::new_error(self.tcx(), e.into(), ty)), Err(ErrorHandled::Reported(e, _)) => {
Err(ErrorHandled::TooGeneric) => None, Some(ty::Const::new_error(self.tcx(), e.into(), ty))
}
Err(ErrorHandled::TooGeneric(_)) => None,
} }
} }

View File

@ -793,7 +793,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
span: tcx.def_span(unevaluated.def), span: tcx.def_span(unevaluated.def),
unevaluated: unevaluated, unevaluated: unevaluated,
}); });
Err(ErrorHandled::Reported(reported.into())) Err(ErrorHandled::Reported(reported.into(), tcx.def_span(unevaluated.def)))
} }
Err(err) => Err(err), Err(err) => Err(err),
} }

View File

@ -73,13 +73,13 @@ pub fn is_const_evaluatable<'tcx>(
ty::ConstKind::Unevaluated(uv) => { ty::ConstKind::Unevaluated(uv) => {
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
match concrete { match concrete {
Err(ErrorHandled::TooGeneric) => { Err(ErrorHandled::TooGeneric(_)) => {
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug( Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
span, span,
"Missing value for constant, but no error reported?", "Missing value for constant, but no error reported?",
))) )))
} }
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Err(ErrorHandled::Reported(e, _)) => Err(NotConstEvaluatable::Error(e.into())),
Ok(_) => Ok(()), Ok(_) => Ok(()),
} }
} }
@ -132,7 +132,7 @@ pub fn is_const_evaluatable<'tcx>(
.emit() .emit()
} }
Err(ErrorHandled::TooGeneric) => { Err(ErrorHandled::TooGeneric(_)) => {
let err = if uv.has_non_region_infer() { let err = if uv.has_non_region_infer() {
NotConstEvaluatable::MentionsInfer NotConstEvaluatable::MentionsInfer
} else if uv.has_non_region_param() { } else if uv.has_non_region_param() {
@ -147,7 +147,7 @@ pub fn is_const_evaluatable<'tcx>(
Err(err) Err(err)
} }
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Err(ErrorHandled::Reported(e, _)) => Err(NotConstEvaluatable::Error(e.into())),
Ok(_) => Ok(()), Ok(_) => Ok(()),
} }
} }

View File

@ -560,30 +560,31 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
let stalled_on = &mut pending_obligation.stalled_on; let stalled_on = &mut pending_obligation.stalled_on;
let mut evaluate = let mut evaluate = |c: Const<'tcx>| {
|c: Const<'tcx>| { if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() { match self.selcx.infcx.try_const_eval_resolve(
match self.selcx.infcx.try_const_eval_resolve( obligation.param_env,
obligation.param_env, unevaluated,
unevaluated, c.ty(),
c.ty(), Some(obligation.cause.span),
Some(obligation.cause.span), ) {
) { Ok(val) => Ok(val),
Ok(val) => Ok(val), Err(e) => {
Err(e) => match e { match e {
ErrorHandled::TooGeneric => { ErrorHandled::TooGeneric(..) => {
stalled_on.extend(unevaluated.args.iter().filter_map( stalled_on.extend(unevaluated.args.iter().filter_map(
TyOrConstInferVar::maybe_from_generic_arg, TyOrConstInferVar::maybe_from_generic_arg,
)); ));
Err(ErrorHandled::TooGeneric)
} }
_ => Err(e), _ => {}
}, }
Err(e)
} }
} else {
Ok(c)
} }
}; } else {
Ok(c)
}
};
match (evaluate(c1), evaluate(c2)) { match (evaluate(c1), evaluate(c2)) {
(Ok(c1), Ok(c2)) => { (Ok(c1), Ok(c2)) => {
@ -603,13 +604,14 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
), ),
} }
} }
(Err(ErrorHandled::Reported(reported)), _) (Err(ErrorHandled::Reported(reported, _)), _)
| (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( | (_, Err(ErrorHandled::Reported(reported, _))) => ProcessResult::Error(
CodeSelectionError(SelectionError::NotConstEvaluatable( CodeSelectionError(SelectionError::NotConstEvaluatable(
NotConstEvaluatable::Error(reported.into()), NotConstEvaluatable::Error(reported.into()),
)), )),
), ),
(Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { (Err(ErrorHandled::TooGeneric(_)), _)
| (_, Err(ErrorHandled::TooGeneric(_))) => {
if c1.has_non_region_infer() || c2.has_non_region_infer() { if c1.has_non_region_infer() || c2.has_non_region_infer() {
ProcessResult::Unchanged ProcessResult::Unchanged
} else { } else {

View File

@ -989,9 +989,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Err(_) => Ok(EvaluatedToErr), Err(_) => Ok(EvaluatedToErr),
} }
} }
(Err(ErrorHandled::Reported(_)), _) (Err(ErrorHandled::Reported(..)), _)
| (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr), | (_, Err(ErrorHandled::Reported(..))) => Ok(EvaluatedToErr),
(Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { (Err(ErrorHandled::TooGeneric(..)), _)
| (_, Err(ErrorHandled::TooGeneric(..))) => {
if c1.has_non_region_infer() || c2.has_non_region_infer() { if c1.has_non_region_infer() || c2.has_non_region_infer() {
Ok(EvaluatedToAmbig) Ok(EvaluatedToAmbig)
} else { } else {

View File

@ -204,7 +204,7 @@ fn is_value_unfrozen_raw<'tcx>(
// similar to 2., but with the a frozen variant) (e.g. borrowing // similar to 2., but with the a frozen variant) (e.g. borrowing
// `borrow_interior_mutable_const::enums::AssocConsts::TO_BE_FROZEN_VARIANT`). // `borrow_interior_mutable_const::enums::AssocConsts::TO_BE_FROZEN_VARIANT`).
// I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none). // I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none).
err == ErrorHandled::TooGeneric matches!(err, ErrorHandled::TooGeneric(..))
}, },
|val| val.map_or(true, |val| inner(cx, val, ty)), |val| val.map_or(true, |val| inner(cx, val, ty)),
) )
@ -244,8 +244,8 @@ pub fn const_eval_resolve<'tcx>(
}; };
tcx.const_eval_global_id_for_typeck(param_env, cid, span) tcx.const_eval_global_id_for_typeck(param_env, cid, span)
}, },
Ok(None) => Err(ErrorHandled::TooGeneric), Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))),
Err(err) => Err(ErrorHandled::Reported(err.into())), Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(rustc_span::DUMMY_SP))),
} }
} }

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of `main::{constant#3}` failed
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
note: erroneous constant used note: erroneous constant encountered
--> $DIR/test.rs:37:5 --> $DIR/test.rs:37:5
| |
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.

View File

@ -24,7 +24,7 @@ error[E0080]: evaluation of `main::{constant#3}` failed
LL | const { &ARR[idx4()] }; LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
note: erroneous constant used note: erroneous constant encountered
--> $DIR/indexing_slicing_index.rs:48:5 --> $DIR/indexing_slicing_index.rs:48:5
| |
LL | const { &ARR[idx4()] }; LL | const { &ARR[idx4()] };

View File

@ -142,9 +142,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn eval_path_scalar(&self, path: &[&str]) -> Scalar<Provenance> { fn eval_path_scalar(&self, path: &[&str]) -> Scalar<Provenance> {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
let instance = this.resolve_path(path, Namespace::ValueNS); let instance = this.resolve_path(path, Namespace::ValueNS);
let cid = GlobalId { instance, promoted: None };
// We don't give a span -- this isn't actually used directly by the program anyway. // We don't give a span -- this isn't actually used directly by the program anyway.
let const_val = this.eval_global(cid, None).unwrap_or_else(|err| { let const_val = this.eval_global(instance).unwrap_or_else(|err| {
panic!("failed to evaluate required Rust item: {path:?}\n{err:?}") panic!("failed to evaluate required Rust item: {path:?}\n{err:?}")
}); });
this.read_scalar(&const_val) this.read_scalar(&const_val)

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed
LL | ptr.read(); LL | ptr.read();
| ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required | ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-ub-checks.rs:LL:CC --> $DIR/const-ub-checks.rs:LL:CC
| |
LL | let _x = UNALIGNED_READ; LL | let _x = UNALIGNED_READ;

View File

@ -6,7 +6,7 @@ LL | const VOID: ! = panic!();
| |
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/erroneous_const.rs:LL:CC --> $DIR/erroneous_const.rs:LL:CC
| |
LL | let _ = PrintName::<T>::VOID; LL | let _ = PrintName::<T>::VOID;

View File

@ -4,13 +4,13 @@ error[E0080]: evaluation of constant value failed
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow | ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow
note: erroneous constant used note: erroneous constant encountered
--> $DIR/erroneous_const2.rs:LL:CC --> $DIR/erroneous_const2.rs:LL:CC
| |
LL | println!("{}", FOO); LL | println!("{}", FOO);
| ^^^ | ^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/erroneous_const2.rs:LL:CC --> $DIR/erroneous_const2.rs:LL:CC
| |
LL | println!("{}", FOO); LL | println!("{}", FOO);

View File

@ -3,7 +3,7 @@
// Cyclic assoc. const defaults don't error unless *used* // Cyclic assoc. const defaults don't error unless *used*
trait Tr { trait Tr {
const A: u8 = Self::B; const A: u8 = Self::B;
//~^ cycle detected when const-evaluating + checking `Tr::A` //~^ cycle detected
const B: u8 = Self::A; const B: u8 = Self::A;
} }

View File

@ -1,15 +1,25 @@
error[E0391]: cycle detected when const-evaluating + checking `Tr::A` error[E0391]: cycle detected when simplifying constant for the type system `Tr::A`
--> $DIR/defaults-cyclic-fail.rs:5:5
|
LL | const A: u8 = Self::B;
| ^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `Tr::A`...
--> $DIR/defaults-cyclic-fail.rs:5:19 --> $DIR/defaults-cyclic-fail.rs:5:19
| |
LL | const A: u8 = Self::B; LL | const A: u8 = Self::B;
| ^^^^^^^ | ^^^^^^^
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`... note: ...which requires const-evaluating + checking `Tr::B`...
--> $DIR/defaults-cyclic-fail.rs:8:19 --> $DIR/defaults-cyclic-fail.rs:8:19
| |
LL | const B: u8 = Self::A; LL | const B: u8 = Self::A;
| ^^^^^^^ | ^^^^^^^
= note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle = note: ...which again requires simplifying constant for the type system `Tr::A`, completing the cycle
note: cycle used when const-evaluating + checking `main::promoted[1]` note: cycle used when const-evaluating + checking `main::promoted[1]`
--> $DIR/defaults-cyclic-fail.rs:16:16 --> $DIR/defaults-cyclic-fail.rs:16:16
| |

View File

@ -4,13 +4,13 @@ error[E0080]: evaluation of `<() as Tr>::B` failed
LL | const B: u8 = Self::A + 1; LL | const B: u8 = Self::A + 1;
| ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
note: erroneous constant used note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:16 --> $DIR/defaults-not-assumed-fail.rs:33:16
| |
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:5 --> $DIR/defaults-not-assumed-fail.rs:33:5
| |
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
@ -18,7 +18,7 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| |
= note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:5 --> $DIR/defaults-not-assumed-fail.rs:33:5
| |
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above LL | assert_eq!(<() as Tr>::B, 0); // causes the error above

View File

@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-249
LL | const BAR: u32 = IMPL_REF_BAR; LL | const BAR: u32 = IMPL_REF_BAR;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
note: ...which requires const-evaluating + checking `IMPL_REF_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 simplifying constant for the type system `IMPL_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
| |
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
@ -14,6 +19,11 @@ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
| |
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
note: ...which requires simplifying constant for the type system `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::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 `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`... note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
| |

View File

@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `FooDefault::BAR`
LL | const BAR: u32 = DEFAULT_REF_BAR; LL | const BAR: u32 = DEFAULT_REF_BAR;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
note: ...which requires const-evaluating + checking `DEFAULT_REF_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 = <GlobalDefaultRef>::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 --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
| |
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
@ -14,6 +19,11 @@ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
| |
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::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`... note: ...which requires const-evaluating + checking `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
| |

View File

@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-249
LL | const BAR: u32 = TRAIT_REF_BAR; LL | const BAR: u32 = TRAIT_REF_BAR;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
note: ...which requires const-evaluating + checking `TRAIT_REF_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 = <GlobalTraitRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
| |
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
@ -14,6 +19,11 @@ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
| |
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires simplifying constant for the type system `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::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 `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`... note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
| |

View File

@ -16,7 +16,7 @@ LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-81899.rs:4:23 --> $DIR/issue-81899.rs:4:23
| |
LL | const _CONST: &[u8] = &f(&[], |_| {}); LL | const _CONST: &[u8] = &f(&[], |_| {});

View File

@ -16,7 +16,7 @@ LL | const _CONST: &() = &f(&|_| {});
| ^^^^^^^^^^ | ^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-88434-minimal-example.rs:3:21 --> $DIR/issue-88434-minimal-example.rs:3:21
| |
LL | const _CONST: &() = &f(&|_| {}); LL | const _CONST: &() = &f(&|_| {});

View File

@ -16,7 +16,7 @@ LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:23 --> $DIR/issue-88434-removal-index-should-be-less.rs:3:23
| |
LL | const _CONST: &[u8] = &f(&[], |_| {}); LL | const _CONST: &[u8] = &f(&[], |_| {});

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of `S::<i32>::FOO` failed
LL | const FOO: u8 = [5u8][1]; LL | const FOO: u8 = [5u8][1];
| ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-err-late.rs:19:16 --> $DIR/const-err-late.rs:19:16
| |
LL | black_box((S::<i32>::FOO, S::<u32>::FOO)); LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
@ -16,13 +16,13 @@ error[E0080]: evaluation of `S::<u32>::FOO` failed
LL | const FOO: u8 = [5u8][1]; LL | const FOO: u8 = [5u8][1];
| ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-err-late.rs:19:31 --> $DIR/const-err-late.rs:19:31
| |
LL | black_box((S::<i32>::FOO, S::<u32>::FOO)); LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-err-late.rs:19:16 --> $DIR/const-err-late.rs:19:16
| |
LL | black_box((S::<i32>::FOO, S::<u32>::FOO)); LL | black_box((S::<i32>::FOO, S::<u32>::FOO));

View File

@ -4,19 +4,19 @@ error[E0080]: evaluation of constant value failed
LL | pub const A: i8 = -i8::MIN; LL | pub const A: i8 = -i8::MIN;
| ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-err-multi.rs:3:19 --> $DIR/const-err-multi.rs:3:19
| |
LL | pub const B: i8 = A; LL | pub const B: i8 = A;
| ^ | ^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-err-multi.rs:5:19 --> $DIR/const-err-multi.rs:5:19
| |
LL | pub const C: u8 = A as u8; LL | pub const C: u8 = A as u8;
| ^ | ^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-err-multi.rs:7:24 --> $DIR/const-err-multi.rs:7:24
| |
LL | pub const D: i8 = 50 - A; LL | pub const D: i8 = 50 - A;

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
LL | const VOID: () = [()][2]; LL | const VOID: () = [()][2];
| ^^^^^^^ index out of bounds: the length is 1 but the index is 2 | ^^^^^^^ index out of bounds: the length is 1 but the index is 2
note: erroneous constant used note: erroneous constant encountered
--> $DIR/erroneous-const.rs:13:13 --> $DIR/erroneous-const.rs:13:13
| |
LL | PrintName::<T>::VOID; LL | PrintName::<T>::VOID;

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
LL | const VOID: () = [()][2]; LL | const VOID: () = [()][2];
| ^^^^^^^ index out of bounds: the length is 1 but the index is 2 | ^^^^^^^ index out of bounds: the length is 1 but the index is 2
note: erroneous constant used note: erroneous constant encountered
--> $DIR/erroneous-const2.rs:13:9 --> $DIR/erroneous-const2.rs:13:9
| |
LL | PrintName::<i32>::VOID; LL | PrintName::<i32>::VOID;

View File

@ -4,13 +4,13 @@ error[E0080]: evaluation of `<Bar<u16, u8> as Foo>::AMT` failed
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-44578.rs:25:20 --> $DIR/issue-44578.rs:25:20
| |
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-44578.rs:25:20 --> $DIR/issue-44578.rs:25:20
| |
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
@ -18,7 +18,7 @@ LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| |
= note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-44578.rs:25:20 --> $DIR/issue-44578.rs:25:20
| |
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of `<A<()> as Foo<()>>::BAR` failed
LL | const BAR: usize = [5, 6, 7][T::BOO]; LL | const BAR: usize = [5, 6, 7][T::BOO];
| ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 | ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-50814-2.rs:18:6 --> $DIR/issue-50814-2.rs:18:6
| |
LL | &<A<T> as Foo<T>>::BAR LL | &<A<T> as Foo<T>>::BAR

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
LL | const MAX: u8 = A::MAX + B::MAX; LL | const MAX: u8 = A::MAX + B::MAX;
| ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow | ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-50814.rs:20:6 --> $DIR/issue-50814.rs:20:6
| |
LL | &Sum::<U8, U8>::MAX LL | &Sum::<U8, U8>::MAX

View File

@ -11,5 +11,5 @@ impl PrintName {
} }
fn main() { fn main() {
let _ = PrintName::VOID; //~ erroneous constant used let _ = PrintName::VOID; //~ erroneous constant encountered
} }

View File

@ -6,13 +6,13 @@ LL | const VOID: ! = panic!();
| |
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/panic-assoc-never-type.rs:14:13 --> $DIR/panic-assoc-never-type.rs:14:13
| |
LL | let _ = PrintName::VOID; LL | let _ = PrintName::VOID;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/panic-assoc-never-type.rs:14:13 --> $DIR/panic-assoc-never-type.rs:14:13
| |
LL | let _ = PrintName::VOID; LL | let _ = PrintName::VOID;

View File

@ -341,7 +341,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
╾ALLOC_ID╼ │ ╾──╼ ╾ALLOC_ID╼ │ ╾──╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/raw-bytes.rs:160:40 --> $DIR/raw-bytes.rs:160:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
@ -358,7 +358,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
╾ALLOC_ID╼ │ ╾──╼ ╾ALLOC_ID╼ │ ╾──╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/raw-bytes.rs:166:42 --> $DIR/raw-bytes.rs:166:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
@ -375,7 +375,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
╾ALLOC_ID╼ │ ╾──╼ ╾ALLOC_ID╼ │ ╾──╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/raw-bytes.rs:170:42 --> $DIR/raw-bytes.rs:170:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);

View File

@ -341,7 +341,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
╾ALLOC_ID╼ │ ╾──────╼ ╾ALLOC_ID╼ │ ╾──────╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/raw-bytes.rs:160:40 --> $DIR/raw-bytes.rs:160:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
@ -358,7 +358,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
╾ALLOC_ID╼ │ ╾──────╼ ╾ALLOC_ID╼ │ ╾──────╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/raw-bytes.rs:166:42 --> $DIR/raw-bytes.rs:166:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
@ -375,7 +375,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
╾ALLOC_ID╼ │ ╾──────╼ ╾ALLOC_ID╼ │ ╾──────╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/raw-bytes.rs:170:42 --> $DIR/raw-bytes.rs:170:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);

View File

@ -60,7 +60,7 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
= help: this code performed an operation that depends on the underlying bytes representing a pointer = help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
note: erroneous constant used note: erroneous constant encountered
--> $DIR/ub-ref-ptr.rs:36:38 --> $DIR/ub-ref-ptr.rs:36:38
| |
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
@ -75,7 +75,7 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
= help: this code performed an operation that depends on the underlying bytes representing a pointer = help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
note: erroneous constant used note: erroneous constant encountered
--> $DIR/ub-ref-ptr.rs:39:85 --> $DIR/ub-ref-ptr.rs:39:85
| |
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };

View File

@ -139,7 +139,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
HEX_DUMP HEX_DUMP
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/ub-wide-ptr.rs:85:40 --> $DIR/ub-wide-ptr.rs:85:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
@ -156,7 +156,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
HEX_DUMP HEX_DUMP
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/ub-wide-ptr.rs:92:42 --> $DIR/ub-wide-ptr.rs:92:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
@ -173,7 +173,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
HEX_DUMP HEX_DUMP
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/ub-wide-ptr.rs:96:42 --> $DIR/ub-wide-ptr.rs:96:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);

View File

@ -4,13 +4,13 @@ error[E0080]: evaluation of constant value failed
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; LL | const FIELD3: Field3 = unsafe { UNION.field3 };
| ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
note: erroneous constant used note: erroneous constant encountered
--> $DIR/union-const-eval-field.rs:31:5 --> $DIR/union-const-eval-field.rs:31:5
| |
LL | FIELD3 LL | FIELD3
| ^^^^^^ | ^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/union-const-eval-field.rs:31:5 --> $DIR/union-const-eval-field.rs:31:5
| |
LL | FIELD3 LL | FIELD3

View File

@ -30,25 +30,25 @@ LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:35:34 --> $DIR/const-float-bits-reject-conv.rs:35:34
| |
LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:36:34 --> $DIR/const-float-bits-reject-conv.rs:36:34
| |
LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:42:34 --> $DIR/const-float-bits-reject-conv.rs:42:34
| |
LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:43:34 --> $DIR/const-float-bits-reject-conv.rs:43:34
| |
LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
@ -86,25 +86,25 @@ LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:57:34 --> $DIR/const-float-bits-reject-conv.rs:57:34
| |
LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:58:34 --> $DIR/const-float-bits-reject-conv.rs:58:34
| |
LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:61:34 --> $DIR/const-float-bits-reject-conv.rs:61:34
| |
LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-float-bits-reject-conv.rs:62:34 --> $DIR/const-float-bits-reject-conv.rs:62:34
| |
LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed
LL | const LEN: usize = ONE - TWO; LL | const LEN: usize = ONE - TWO;
| ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-len-underflow-separate-spans.rs:14:17 --> $DIR/const-len-underflow-separate-spans.rs:14:17
| |
LL | let a: [i8; LEN] = unimplemented!(); LL | let a: [i8; LEN] = unimplemented!();

View File

@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed
LL | const LEN: usize = ONE - TWO; LL | const LEN: usize = ONE - TWO;
| ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
note: erroneous constant used note: erroneous constant encountered
--> $DIR/const-len-underflow-separate-spans.rs:14:17 --> $DIR/const-len-underflow-separate-spans.rs:14:17
| |
LL | let a: [i8; LEN] = unimplemented!(); LL | let a: [i8; LEN] = unimplemented!();

View File

@ -9,13 +9,13 @@ LL | fn main() {
╾─alloc7──╼ │ ╾──╼ ╾─alloc7──╼ │ ╾──╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/invalid-union.rs:43:25 --> $DIR/invalid-union.rs:43:25
| |
LL | let _: &'static _ = &C; LL | let _: &'static _ = &C;
| ^^ | ^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/invalid-union.rs:43:25 --> $DIR/invalid-union.rs:43:25
| |
LL | let _: &'static _ = &C; LL | let _: &'static _ = &C;

View File

@ -9,13 +9,13 @@ LL | fn main() {
╾───────alloc7────────╼ │ ╾──────╼ ╾───────alloc7────────╼ │ ╾──────╼
} }
note: erroneous constant used note: erroneous constant encountered
--> $DIR/invalid-union.rs:43:25 --> $DIR/invalid-union.rs:43:25
| |
LL | let _: &'static _ = &C; LL | let _: &'static _ = &C;
| ^^ | ^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/invalid-union.rs:43:25 --> $DIR/invalid-union.rs:43:25
| |
LL | let _: &'static _ = &C; LL | let _: &'static _ = &C;

View File

@ -1,15 +1,25 @@
error[E0391]: cycle detected when const-evaluating + checking `Foo::B::{constant#0}` error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}`
--> $DIR/issue-36163.rs:4:9 --> $DIR/issue-36163.rs:4:9
| |
LL | B = A, LL | B = A,
| ^ | ^
| |
note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`...
--> $DIR/issue-36163.rs:4:9
|
LL | B = A,
| ^
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`... note: ...which requires const-evaluating + checking `A`...
--> $DIR/issue-36163.rs:1:18 --> $DIR/issue-36163.rs:1:18
| |
LL | const A: isize = Foo::B as isize; LL | const A: isize = Foo::B as isize;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating + checking `Foo::B::{constant#0}`, completing the cycle = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle
note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}` note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}`
--> $DIR/issue-36163.rs:4:9 --> $DIR/issue-36163.rs:4:9
| |

View File

@ -13,13 +13,13 @@ note: inside `<String as Bar<Vec<u32>, String>>::F`
LL | const F: u32 = (U::X, 42).1; LL | const F: u32 = (U::X, 42).1;
| ^ | ^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/assoc_const.rs:29:13 --> $DIR/assoc_const.rs:29:13
| |
LL | let y = <String as Bar<Vec<u32>, String>>::F; LL | let y = <String as Bar<Vec<u32>, String>>::F;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/assoc_const.rs:29:13 --> $DIR/assoc_const.rs:29:13
| |
LL | let y = <String as Bar<Vec<u32>, String>>::F; LL | let y = <String as Bar<Vec<u32>, String>>::F;

View File

@ -4,13 +4,13 @@ error[E0080]: evaluation of `<std::string::String as Bar<std::string::String>>::
LL | const F: u32 = 100 / U::X; LL | const F: u32 = 100 / U::X;
| ^^^^^^^^^^ attempt to divide `100_u32` by zero | ^^^^^^^^^^ attempt to divide `100_u32` by zero
note: erroneous constant used note: erroneous constant encountered
--> $DIR/assoc_const_2.rs:27:13 --> $DIR/assoc_const_2.rs:27:13
| |
LL | let y = <String as Bar<String>>::F; LL | let y = <String as Bar<String>>::F;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/assoc_const_2.rs:27:13 --> $DIR/assoc_const_2.rs:27:13
| |
LL | let y = <String as Bar<String>>::F; LL | let y = <String as Bar<String>>::F;

View File

@ -645,13 +645,13 @@ note: inside `<i32 as Const>::CONSTANT`
LL | const CONSTANT: i32 = unsafe { fake_type() }; LL | const CONSTANT: i32 = unsafe { fake_type() };
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/uninhabited-const-issue-61744.rs:18:10 --> $DIR/uninhabited-const-issue-61744.rs:18:10
| |
LL | dbg!(i32::CONSTANT); LL | dbg!(i32::CONSTANT);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/uninhabited-const-issue-61744.rs:18:10 --> $DIR/uninhabited-const-issue-61744.rs:18:10
| |
LL | dbg!(i32::CONSTANT); LL | dbg!(i32::CONSTANT);

View File

@ -1,10 +1,15 @@
error[E0391]: cycle detected when const-evaluating + checking `FOO` error[E0391]: cycle detected when 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:20 --> $DIR/issue-17252.rs:1:20
| |
LL | const FOO: usize = FOO; LL | const FOO: usize = FOO;
| ^^^ | ^^^
| = note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle
= note: ...which immediately requires const-evaluating + checking `FOO` again
note: cycle used when const-evaluating + checking `main::{constant#0}` note: cycle used when const-evaluating + checking `main::{constant#0}`
--> $DIR/issue-17252.rs:4:18 --> $DIR/issue-17252.rs:4:18
| |

View File

@ -1,10 +1,15 @@
error[E0391]: cycle detected when const-evaluating + checking `X::A::{constant#0}` error[E0391]: cycle detected when simplifying constant for the type system `X::A::{constant#0}`
--> $DIR/issue-23302-1.rs:4:9 --> $DIR/issue-23302-1.rs:4:9
| |
LL | A = X::A as isize, LL | A = X::A as isize,
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
= note: ...which immediately requires const-evaluating + checking `X::A::{constant#0}` again note: ...which requires const-evaluating + checking `X::A::{constant#0}`...
--> $DIR/issue-23302-1.rs:4:9
|
LL | A = X::A as isize,
| ^^^^^^^^^^^^^
= note: ...which again requires simplifying constant for the type system `X::A::{constant#0}`, completing the cycle
note: cycle used when simplifying constant for the type system `X::A::{constant#0}` note: cycle used when simplifying constant for the type system `X::A::{constant#0}`
--> $DIR/issue-23302-1.rs:4:9 --> $DIR/issue-23302-1.rs:4:9
| |

View File

@ -1,10 +1,15 @@
error[E0391]: cycle detected when const-evaluating + checking `Y::A::{constant#0}` error[E0391]: cycle detected when simplifying constant for the type system `Y::A::{constant#0}`
--> $DIR/issue-23302-2.rs:4:9 --> $DIR/issue-23302-2.rs:4:9
| |
LL | A = Y::B as isize, LL | A = Y::B as isize,
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
= note: ...which immediately requires const-evaluating + checking `Y::A::{constant#0}` again note: ...which requires const-evaluating + checking `Y::A::{constant#0}`...
--> $DIR/issue-23302-2.rs:4:9
|
LL | A = Y::B as isize,
| ^^^^^^^^^^^^^
= note: ...which again requires simplifying constant for the type system `Y::A::{constant#0}`, completing the cycle
note: cycle used when simplifying constant for the type system `Y::A::{constant#0}` note: cycle used when simplifying constant for the type system `Y::A::{constant#0}`
--> $DIR/issue-23302-2.rs:4:9 --> $DIR/issue-23302-2.rs:4:9
| |

View File

@ -1,15 +1,25 @@
error[E0391]: cycle detected when const-evaluating + checking `A` error[E0391]: cycle detected when 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:16 --> $DIR/issue-23302-3.rs:1:16
| |
LL | const A: i32 = B; LL | const A: i32 = B;
| ^ | ^
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`... note: ...which requires const-evaluating + checking `B`...
--> $DIR/issue-23302-3.rs:3:16 --> $DIR/issue-23302-3.rs:3:16
| |
LL | const B: i32 = A; LL | const B: i32 = A;
| ^ | ^
= note: ...which again requires const-evaluating + checking `A`, completing the cycle = note: ...which again requires simplifying constant for the type system `A`, completing the cycle
note: cycle used when simplifying constant for the type system `A` note: cycle used when simplifying constant for the type system `A`
--> $DIR/issue-23302-3.rs:1:1 --> $DIR/issue-23302-3.rs:1:1
| |

View File

@ -13,7 +13,7 @@ LL | type MyA: TraitA;
LL | impl TraitB for B { LL | impl TraitB for B {
| ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17
| |
LL | let _ = [0; B::VALUE]; LL | let _ = [0; B::VALUE];

View File

@ -11,7 +11,7 @@ note: inside `main`
LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-55878.rs:7:26 --> $DIR/issue-55878.rs:7:26
| |
LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
@ -19,7 +19,7 @@ LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
| |
= note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used note: erroneous constant encountered
--> $DIR/issue-55878.rs:7:26 --> $DIR/issue-55878.rs:7:26
| |
LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());