mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-02 01:52:51 +00:00
move required_consts check to general post-mono-check function
This commit is contained in:
parent
ccf817b9bb
commit
89ac57db4d
@ -2,6 +2,7 @@
|
||||
|
||||
use rustc_ast::InlineAsmOptions;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
@ -250,13 +251,22 @@ pub(crate) fn verify_func(
|
||||
}
|
||||
|
||||
fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
||||
if !crate::constant::check_constants(fx) {
|
||||
match fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c))) {
|
||||
Ok(()) => {}
|
||||
Err(ErrorHandled::TooGeneric(span)) => {
|
||||
span_bug!(span, "codegen encountered polymorphic constant");
|
||||
}
|
||||
Err(ErrorHandled::Reported(info, span)) => {
|
||||
if !info.is_tainted_by_errors() {
|
||||
fx.tcx.sess.span_err(span, "erroneous constant encountered");
|
||||
}
|
||||
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
||||
// compilation should have been aborted
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let arg_uninhabited = fx
|
||||
.mir
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::interpret::{
|
||||
read_target_uint, AllocId, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
|
||||
};
|
||||
use rustc_middle::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalAlloc, Scalar};
|
||||
|
||||
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) {
|
||||
let mut constants_cx = ConstantCx::new();
|
||||
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>(
|
||||
fx: &FunctionCx<'_, '_, 'tcx>,
|
||||
constant: &Constant<'tcx>,
|
||||
) -> Option<(ConstValue<'tcx>, Ty<'tcx>)> {
|
||||
) -> (ConstValue<'tcx>, Ty<'tcx>) {
|
||||
let cv = fx.monomorphize(constant.literal);
|
||||
// This cannot fail because we checked all required_consts in advance.
|
||||
let val = cv
|
||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
|
||||
.map_err(|err| match err {
|
||||
ErrorHandled::Reported(_) => {
|
||||
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()))
|
||||
.expect("erroneous constant not captured by required_consts");
|
||||
(val, cv.ty())
|
||||
}
|
||||
|
||||
pub(crate) fn codegen_constant_operand<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
constant: &Constant<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let (const_val, ty) = eval_mir_constant(fx, constant).unwrap_or_else(|| {
|
||||
span_bug!(constant.span, "erroneous constant not captured by required_consts")
|
||||
});
|
||||
|
||||
let (const_val, ty) = eval_mir_constant(fx, constant);
|
||||
codegen_const_value(fx, const_val, ty)
|
||||
}
|
||||
|
||||
@ -459,7 +437,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
|
||||
operand: &Operand<'tcx>,
|
||||
) -> Option<ConstValue<'tcx>> {
|
||||
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
|
||||
// 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.
|
||||
|
@ -242,8 +242,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Const { ref value } => {
|
||||
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value)
|
||||
.unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved"));
|
||||
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value);
|
||||
let value = rustc_codegen_ssa::common::asm_const_to_str(
|
||||
fx.tcx,
|
||||
span,
|
||||
|
@ -1088,9 +1088,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
InlineAsmOperandRef::InOut { reg, late, in_value, out_place }
|
||||
}
|
||||
mir::InlineAsmOperand::Const { ref value } => {
|
||||
let const_value = self
|
||||
.eval_mir_constant(value)
|
||||
.unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved"));
|
||||
let const_value = self.eval_mir_constant(value);
|
||||
let string = common::asm_const_to_str(
|
||||
bx.tcx(),
|
||||
span,
|
||||
|
@ -14,34 +14,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
&self,
|
||||
bx: &mut Bx,
|
||||
constant: &mir::Constant<'tcx>,
|
||||
) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
|
||||
let val = self.eval_mir_constant(constant)?;
|
||||
) -> OperandRef<'tcx, Bx::Value> {
|
||||
let val = self.eval_mir_constant(constant);
|
||||
let ty = self.monomorphize(constant.ty());
|
||||
Ok(OperandRef::from_const(bx, val, ty))
|
||||
OperandRef::from_const(bx, val, ty)
|
||||
}
|
||||
|
||||
pub fn eval_mir_constant(
|
||||
&self,
|
||||
constant: &mir::Constant<'tcx>,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> ConstValue<'tcx> {
|
||||
self.monomorphize(constant.literal)
|
||||
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
|
||||
.map_err(|err| {
|
||||
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
|
||||
})
|
||||
.expect("erroneous constant not captured by required_consts")
|
||||
}
|
||||
|
||||
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
|
||||
|
@ -579,23 +579,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
if let Some(dbg_var) = dbg_var {
|
||||
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);
|
||||
let base = Self::spill_operand_to_stack(
|
||||
operand,
|
||||
Some(var.name.to_string()),
|
||||
bx,
|
||||
);
|
||||
let base =
|
||||
Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
|
||||
|
||||
bx.dbg_var_addr(
|
||||
dbg_var,
|
||||
dbg_loc,
|
||||
base.llval,
|
||||
Size::ZERO,
|
||||
&[],
|
||||
fragment,
|
||||
);
|
||||
}
|
||||
bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[], fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::base;
|
||||
use crate::errors;
|
||||
use crate::traits::*;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_index::IndexVec;
|
||||
@ -212,25 +213,22 @@ 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);
|
||||
|
||||
// Evaluate all required consts; codegen later assumes that CTFE will never fail.
|
||||
let mut all_consts_ok = true;
|
||||
for const_ in &mir.required_consts {
|
||||
if let Err(err) = fx.eval_mir_constant(const_) {
|
||||
all_consts_ok = false;
|
||||
match err {
|
||||
// errored or at least linted
|
||||
ErrorHandled::Reported(_) => {}
|
||||
ErrorHandled::TooGeneric => {
|
||||
span_bug!(const_.span, "codegen encountered polymorphic constant: {:?}", err)
|
||||
// Rust post-monomorphization checks; we later rely on them.
|
||||
match mir.post_mono_checks(cx.tcx(), ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c))) {
|
||||
Ok(()) => {}
|
||||
Err(ErrorHandled::TooGeneric(span)) => {
|
||||
cx.tcx().sess.diagnostic().emit_bug(errors::PolymorphicConstantTooGeneric { span });
|
||||
}
|
||||
Err(ErrorHandled::Reported(info, span)) => {
|
||||
if !info.is_tainted_by_errors() {
|
||||
cx.tcx().sess.emit_err(errors::ErroneousConstant { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
// This IR shouldn't ever be emitted, but let's try to guard against any of this code
|
||||
// ever running.
|
||||
start_bx.abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let memory_locals = analyze::non_ssa_locals(&fx);
|
||||
|
||||
|
@ -575,12 +575,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
self.codegen_consume(bx, place.as_ref())
|
||||
}
|
||||
|
||||
mir::Operand::Constant(ref 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")
|
||||
})
|
||||
}
|
||||
mir::Operand::Constant(ref constant) => self.eval_mir_constant_to_operand(bx, constant),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, IntoDiagnostic, IntoDi
|
||||
use rustc_middle::mir::AssertKind;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
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 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
|
||||
// should remain silent.
|
||||
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))) => {
|
||||
ErrorHandled::Reported(guar.into())
|
||||
ErrorHandled::Reported(guar.into(), span.unwrap_or(DUMMY_SP))
|
||||
}
|
||||
// Report remaining errors.
|
||||
_ => {
|
||||
@ -152,7 +152,7 @@ where
|
||||
|
||||
// Use *our* span to label the interp error
|
||||
err.span_label(our_span, msg);
|
||||
ErrorHandled::Reported(err.emit().into())
|
||||
ErrorHandled::Reported(err.emit().into(), span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||
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) => {}
|
||||
Err(ErrorHandled::TooGeneric(_)) => {}
|
||||
// deduplicate calls
|
||||
other => return other,
|
||||
}
|
||||
@ -259,7 +259,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||
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) => {}
|
||||
Err(ErrorHandled::TooGeneric(_)) => {}
|
||||
// deduplicate calls
|
||||
other => return other,
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use hir::CRATE_HIR_ID;
|
||||
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidMetaKind, ReportedErrorInfo};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::layout::{
|
||||
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
|
||||
@ -21,7 +21,7 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou
|
||||
|
||||
use super::{
|
||||
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,
|
||||
};
|
||||
use crate::errors::{self, ErroneousConstUsed};
|
||||
@ -556,7 +556,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
>(
|
||||
&self,
|
||||
value: T,
|
||||
) -> Result<T, InterpError<'tcx>> {
|
||||
) -> Result<T, ErrorHandled> {
|
||||
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,
|
||||
frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>,
|
||||
value: T,
|
||||
) -> Result<T, InterpError<'tcx>> {
|
||||
) -> Result<T, ErrorHandled> {
|
||||
frame
|
||||
.instance
|
||||
.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,
|
||||
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).
|
||||
@ -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).
|
||||
if M::POST_MONO_CHECKS {
|
||||
for ct in &body.required_consts {
|
||||
let span = ct.span;
|
||||
let ct = self.subst_from_current_frame_and_normalize_erasing_regions(ct.literal)?;
|
||||
self.eval_mir_constant(&ct, Some(span), None)?;
|
||||
}
|
||||
// `ctfe_query` does some error message decoration that we want to be in effect here.
|
||||
self.ctfe_query(None, |tcx| {
|
||||
body.post_mono_checks(*tcx, self.param_env, |c| {
|
||||
self.subst_from_current_frame_and_normalize_erasing_regions(c)
|
||||
})
|
||||
})?;
|
||||
}
|
||||
|
||||
// done
|
||||
@ -1059,28 +1060,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
&self,
|
||||
span: Option<Span>,
|
||||
query: impl FnOnce(TyCtxtAt<'tcx>) -> Result<T, ErrorHandled>,
|
||||
) -> InterpResult<'tcx, T> {
|
||||
) -> Result<T, ErrorHandled> {
|
||||
// Use a precise span for better cycle errors.
|
||||
query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| {
|
||||
match err {
|
||||
ErrorHandled::Reported(err) => {
|
||||
if !err.is_tainted_by_errors() && let Some(span) = span {
|
||||
ErrorHandled::Reported(err, reported_span) => {
|
||||
// We trust the provided span more than the one that came out of the query.
|
||||
let span = span.unwrap_or(reported_span);
|
||||
if !err.is_tainted_by_errors() {
|
||||
// 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),
|
||||
ErrorHandled::TooGeneric(_) => {}
|
||||
}
|
||||
.into()
|
||||
err
|
||||
})
|
||||
}
|
||||
|
||||
pub fn eval_global(
|
||||
&self,
|
||||
gid: GlobalId<'tcx>,
|
||||
span: Option<Span>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
) -> 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
|
||||
// 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
|
||||
@ -1091,10 +1093,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
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]
|
||||
pub fn dump_place(
|
||||
&self,
|
||||
|
@ -8,15 +8,14 @@ use either::{Either, Left, Right};
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
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_span::Span;
|
||||
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size};
|
||||
|
||||
use super::{
|
||||
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId,
|
||||
InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer,
|
||||
Projectable, Provenance, Scalar,
|
||||
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, InterpCx,
|
||||
InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable,
|
||||
Provenance, Scalar,
|
||||
};
|
||||
|
||||
/// An `Immediate` represents a single immediate self-contained Rust value.
|
||||
@ -693,54 +692,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
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(
|
||||
&self,
|
||||
val_val: ConstValue<'tcx>,
|
||||
|
@ -1596,9 +1596,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
|
||||
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
|
||||
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() {
|
||||
return Err(ErrorHandled::TooGeneric);
|
||||
return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP)));
|
||||
} else {
|
||||
args = replace_param_and_infer_args_with_placeholder(tcx, args);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use rustc_errors::{
|
||||
};
|
||||
use rustc_macros::HashStable;
|
||||
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 std::borrow::Cow;
|
||||
@ -21,16 +21,25 @@ use std::{any::Any, backtrace::Backtrace, fmt};
|
||||
pub enum ErrorHandled {
|
||||
/// Already reported an error for this evaluation, and the compilation is
|
||||
/// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
|
||||
Reported(ReportedErrorInfo),
|
||||
Reported(ReportedErrorInfo, Span),
|
||||
/// Don't emit an error, the evaluation failed because the MIR was generic
|
||||
/// and the args didn't fully monomorphize it.
|
||||
TooGeneric,
|
||||
TooGeneric(Span),
|
||||
}
|
||||
|
||||
impl From<ErrorGuaranteed> for ErrorHandled {
|
||||
#[inline]
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,6 +171,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> {
|
||||
fn from(kind: InterpError<'tcx>) -> Self {
|
||||
InterpErrorInfo(Box::new(InterpErrorInfoInner {
|
||||
|
@ -61,8 +61,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
let cid = GlobalId { instance, promoted: ct.promoted };
|
||||
self.const_eval_global_id(param_env, cid, span)
|
||||
}
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into())),
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(DUMMY_SP))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,8 +117,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
})
|
||||
}
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into())),
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(DUMMY_SP))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,6 +565,37 @@ impl<'tcx> Body<'tcx> {
|
||||
pub fn is_custom_mir(&self) -> bool {
|
||||
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)).map_err(|e| {
|
||||
// The query results don't always have the span we want.
|
||||
e.with_span(const_.span)
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
@ -2397,10 +2428,10 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
|
||||
match self.eval(tcx, param_env, None) {
|
||||
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()))
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric) => self,
|
||||
Err(ErrorHandled::TooGeneric(_span)) => self,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,8 +478,8 @@ impl<'tcx> AdtDef<'tcx> {
|
||||
}
|
||||
Err(err) => {
|
||||
let msg = match err {
|
||||
ErrorHandled::Reported(_) => "enum discriminant evaluation failed",
|
||||
ErrorHandled::TooGeneric => "enum discriminant depends on generics",
|
||||
ErrorHandled::Reported(..) => "enum discriminant evaluation failed",
|
||||
ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics",
|
||||
};
|
||||
tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg);
|
||||
None
|
||||
|
@ -300,7 +300,7 @@ impl<'tcx> Const<'tcx> {
|
||||
| ConstKind::Infer(_)
|
||||
| ConstKind::Bound(_, _)
|
||||
| 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 {
|
||||
match self.eval(tcx, param_env, None) {
|
||||
Ok(val) => Self::new_value(tcx, val, self.ty()),
|
||||
Err(ErrorHandled::Reported(r)) => Self::new_error(tcx, r.into(), self.ty()),
|
||||
Err(ErrorHandled::TooGeneric) => self,
|
||||
Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into(), self.ty()),
|
||||
Err(ErrorHandled::TooGeneric(_span)) => self,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -566,7 +566,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
pattern
|
||||
}
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
// While `Reported | Linted` cases will have diagnostics emitted already
|
||||
// it is not true for TooGeneric case, so we need to give user more information.
|
||||
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
|
||||
@ -640,14 +640,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
.kind
|
||||
} else {
|
||||
// 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,
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
|
||||
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
|
||||
PatKind::Wild
|
||||
}
|
||||
Err(ErrorHandled::Reported(_)) => PatKind::Wild,
|
||||
Err(ErrorHandled::Reported(..)) => PatKind::Wild,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -752,8 +752,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
let val = match literal.eval(self.tcx, param_env, None) {
|
||||
Ok(v) => v,
|
||||
Err(ErrorHandled::Reported(_)) => return,
|
||||
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||
Err(ErrorHandled::Reported(..)) => return,
|
||||
Err(ErrorHandled::TooGeneric(..)) => span_bug!(
|
||||
self.body.source_info(location).span,
|
||||
"collection encountered polymorphic constant: {:?}",
|
||||
literal
|
||||
|
@ -949,8 +949,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, None) {
|
||||
Ok(ct) => Some(ct),
|
||||
Err(ErrorHandled::Reported(e)) => Some(ty::Const::new_error(self.tcx(), e.into(), ty)),
|
||||
Err(ErrorHandled::TooGeneric) => None,
|
||||
Err(ErrorHandled::Reported(e, _)) => {
|
||||
Some(ty::Const::new_error(self.tcx(), e.into(), ty))
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric(_)) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -793,7 +793,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
span: tcx.def_span(unevaluated.def),
|
||||
unevaluated: unevaluated,
|
||||
});
|
||||
Err(ErrorHandled::Reported(reported.into()))
|
||||
Err(ErrorHandled::Reported(reported.into(), tcx.def_span(unevaluated.def)))
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
|
||||
match concrete {
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
"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(()),
|
||||
}
|
||||
}
|
||||
@ -132,7 +132,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
.emit()
|
||||
}
|
||||
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
let err = if uv.has_non_region_infer() {
|
||||
NotConstEvaluatable::MentionsInfer
|
||||
} else if uv.has_non_region_param() {
|
||||
@ -147,7 +147,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
|
||||
Err(err)
|
||||
}
|
||||
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())),
|
||||
Err(ErrorHandled::Reported(e, _)) => Err(NotConstEvaluatable::Error(e.into())),
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
@ -560,8 +560,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
|
||||
let stalled_on = &mut pending_obligation.stalled_on;
|
||||
|
||||
let mut evaluate =
|
||||
|c: Const<'tcx>| {
|
||||
let mut evaluate = |c: Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
|
||||
match self.selcx.infcx.try_const_eval_resolve(
|
||||
obligation.param_env,
|
||||
@ -570,15 +569,17 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
Some(obligation.cause.span),
|
||||
) {
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => match e {
|
||||
ErrorHandled::TooGeneric => {
|
||||
Err(e) => {
|
||||
match e {
|
||||
ErrorHandled::TooGeneric(..) => {
|
||||
stalled_on.extend(unevaluated.args.iter().filter_map(
|
||||
TyOrConstInferVar::maybe_from_generic_arg,
|
||||
));
|
||||
Err(ErrorHandled::TooGeneric)
|
||||
}
|
||||
_ => Err(e),
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(c)
|
||||
@ -603,13 +604,14 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
),
|
||||
}
|
||||
}
|
||||
(Err(ErrorHandled::Reported(reported)), _)
|
||||
| (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error(
|
||||
(Err(ErrorHandled::Reported(reported, _)), _)
|
||||
| (_, Err(ErrorHandled::Reported(reported, _))) => ProcessResult::Error(
|
||||
CodeSelectionError(SelectionError::NotConstEvaluatable(
|
||||
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() {
|
||||
ProcessResult::Unchanged
|
||||
} else {
|
||||
|
@ -989,9 +989,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Err(_) => Ok(EvaluatedToErr),
|
||||
}
|
||||
}
|
||||
(Err(ErrorHandled::Reported(_)), _)
|
||||
| (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr),
|
||||
(Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
|
||||
(Err(ErrorHandled::Reported(..)), _)
|
||||
| (_, Err(ErrorHandled::Reported(..))) => Ok(EvaluatedToErr),
|
||||
(Err(ErrorHandled::TooGeneric(..)), _)
|
||||
| (_, Err(ErrorHandled::TooGeneric(..))) => {
|
||||
if c1.has_non_region_infer() || c2.has_non_region_infer() {
|
||||
Ok(EvaluatedToAmbig)
|
||||
} else {
|
||||
|
@ -204,7 +204,7 @@ fn is_value_unfrozen_raw<'tcx>(
|
||||
// similar to 2., but with the a frozen variant) (e.g. borrowing
|
||||
// `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).
|
||||
err == ErrorHandled::TooGeneric
|
||||
matches!(err, ErrorHandled::TooGeneric(..))
|
||||
},
|
||||
|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)
|
||||
},
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into())),
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(rustc_span::DUMMY_SP))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,9 +142,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn eval_path_scalar(&self, path: &[&str]) -> Scalar<Provenance> {
|
||||
let this = self.eval_context_ref();
|
||||
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.
|
||||
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:?}")
|
||||
});
|
||||
this.read_scalar(&const_val)
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Cyclic assoc. const defaults don't error unless *used*
|
||||
trait Tr {
|
||||
const A: u8 = Self::B;
|
||||
//~^ cycle detected when const-evaluating + checking `Tr::A`
|
||||
//~^ cycle detected
|
||||
|
||||
const B: u8 = Self::A;
|
||||
}
|
||||
|
@ -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
|
||||
|
|
||||
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`...
|
||||
--> $DIR/defaults-cyclic-fail.rs:8:19
|
||||
|
|
||||
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]`
|
||||
--> $DIR/defaults-cyclic-fail.rs:16:16
|
||||
|
|
||||
|
@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-249
|
||||
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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
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`...
|
||||
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
||||
|
|
||||
|
@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `FooDefault::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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
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
|
||||
|
|
||||
|
@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-249
|
||||
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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
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`...
|
||||
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
note: erroneous constant used
|
||||
--> $DIR/issue-98629.rs:13:10
|
||||
|
|
||||
LL | [(); <i32 as Trait>::N]:,
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `N`
|
||||
--> $DIR/issue-98629.rs:8:1
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
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`...
|
||||
--> $DIR/issue-36163.rs:1:18
|
||||
|
|
||||
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}`
|
||||
--> $DIR/issue-36163.rs:4:9
|
||||
|
|
||||
|
@ -10,6 +10,12 @@ note: type in trait
|
||||
LL | const VALUE: usize;
|
||||
| ^^^^^
|
||||
|
||||
note: erroneous constant used
|
||||
--> $DIR/issue-70942-trait-vs-impl-mismatch.rs:13:18
|
||||
|
|
||||
LL | let _: [i32; Zero::VALUE] = [];
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0326`.
|
||||
|
@ -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
|
||||
|
|
||||
LL | const FOO: usize = FOO;
|
||||
| ^^^
|
||||
|
|
||||
= note: ...which immediately requires const-evaluating + checking `FOO` again
|
||||
= note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle
|
||||
note: cycle used when const-evaluating + checking `main::{constant#0}`
|
||||
--> $DIR/issue-17252.rs:4:18
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
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}`
|
||||
--> $DIR/issue-23302-1.rs:4:9
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
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}`
|
||||
--> $DIR/issue-23302-2.rs:4:9
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
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`...
|
||||
--> $DIR/issue-23302-3.rs:3:16
|
||||
|
|
||||
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`
|
||||
--> $DIR/issue-23302-3.rs:1:1
|
||||
|
|
||||
|
@ -13,6 +13,12 @@ LL | type MyA: TraitA;
|
||||
LL | impl TraitB for B {
|
||||
| ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
|
||||
|
||||
note: erroneous constant used
|
||||
--> $DIR/issue-69602-type-err-during-codegen-ice.rs:12:26
|
||||
|
|
||||
LL | const VALUE: usize = Self::MyA::VALUE;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
note: erroneous constant used
|
||||
--> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user