Auto merge of #53821 - oli-obk:sanity_query, r=RalfJung

Report const eval error inside the query

Functional changes: We no longer warn about bad constants embedded in unused types. This relied on being able to report just a warning, not a hard error on that case, which we cannot do any more now that error reporting is consistently centralized.

r? @RalfJung

fixes #53561
This commit is contained in:
bors 2018-10-26 11:05:00 +00:00
commit 694cf75298
148 changed files with 1133 additions and 1232 deletions

View file

@ -530,6 +530,7 @@ define_dep_nodes!( <'tcx>
[] UsedTraitImports(DefId),
[] HasTypeckTables(DefId),
[] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
[] ConstEvalRaw { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
[] CheckMatch(DefId),
[] SymbolName(DefId),
[] InstanceSymbolName { instance: Instance<'tcx> },

View file

@ -43,7 +43,7 @@ pub struct FnLikeNode<'a> { node: Node<'a> }
/// MaybeFnLike wraps a method that indicates if an object
/// corresponds to some FnLikeNode.
pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
impl MaybeFnLike for ast::Item {
fn is_fn_like(&self) -> bool {

View file

@ -483,10 +483,9 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
val
});
impl_stable_hash_for!(struct ::mir::interpret::ConstEvalErr<'tcx> {
span,
stacktrace,
error
impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
Reported,
TooGeneric
});
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
@ -503,8 +502,6 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
predicates
});
impl_stable_hash_for!(struct ::mir::interpret::EvalError<'tcx> { kind });
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
for ::mir::interpret::EvalErrorKind<'gcx, O> {
fn hash_stable<W: StableHasherResult>(&self,
@ -543,7 +540,6 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
UnimplementedTraitSelection |
TypeckError |
TooGeneric |
CheckMatchError |
DerefFunctionPointer |
ExecuteMemory |
OverflowNeg |
@ -551,6 +547,7 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
DivisionByZero |
GeneratorResumedAfterReturn |
GeneratorResumedAfterPanic |
ReferencedConstant |
InfiniteLoop => {}
ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
InvalidDiscriminant(val) => val.hash_stable(hcx, hasher),
@ -560,7 +557,6 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
line.hash_stable(hcx, hasher);
col.hash_stable(hcx, hasher);
},
ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
MachineError(ref err) => err.hash_stable(hcx, hasher),
FunctionAbiMismatch(a, b) => {
a.hash_stable(hcx, hasher);

View file

@ -12,8 +12,7 @@ use std::{fmt, env};
use mir;
use ty::{Ty, layout};
use ty::layout::{Size, Align};
use rustc_data_structures::sync::Lrc;
use ty::layout::{Size, Align, LayoutError};
use rustc_target::spec::abi::Abi;
use super::{
@ -30,7 +29,26 @@ use syntax_pos::Span;
use syntax::ast;
use syntax::symbol::Symbol;
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ErrorHandled {
/// Already reported a lint or an error for this evaluation
Reported,
/// Don't emit an error, the evaluation failed because the MIR was generic
/// and the substs didn't fully monomorphize it.
TooGeneric,
}
impl ErrorHandled {
pub fn assert_reported(self) {
match self {
ErrorHandled::Reported => {},
ErrorHandled::TooGeneric => bug!("MIR interpretation failed without reporting an error \
even though it was fully monomorphized"),
}
}
}
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ConstEvalErr<'tcx> {
@ -50,7 +68,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
pub fn struct_error(&self,
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
message: &str)
-> Option<DiagnosticBuilder<'tcx>>
-> Result<DiagnosticBuilder<'tcx>, ErrorHandled>
{
self.struct_generic(tcx, message, None)
}
@ -58,10 +76,14 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
pub fn report_as_error(&self,
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
message: &str
) {
) -> ErrorHandled {
let err = self.struct_error(tcx, message);
if let Some(mut err) = err {
err.emit();
match err {
Ok(mut err) => {
err.emit();
ErrorHandled::Reported
},
Err(err) => err,
}
}
@ -69,14 +91,18 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
message: &str,
lint_root: ast::NodeId,
) {
) -> ErrorHandled {
let lint = self.struct_generic(
tcx,
message,
Some(lint_root),
);
if let Some(mut lint) = lint {
lint.emit();
match lint {
Ok(mut lint) => {
lint.emit();
ErrorHandled::Reported
},
Err(err) => err,
}
}
@ -85,15 +111,12 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
message: &str,
lint_root: Option<ast::NodeId>,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
match self.error.kind {
::mir::interpret::EvalErrorKind::TypeckError |
::mir::interpret::EvalErrorKind::TooGeneric |
::mir::interpret::EvalErrorKind::CheckMatchError |
::mir::interpret::EvalErrorKind::Layout(_) => return None,
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
inner.struct_generic(tcx, "referenced constant has errors", lint_root)?.emit();
},
EvalErrorKind::Layout(LayoutError::Unknown(_)) |
EvalErrorKind::TooGeneric => return Err(ErrorHandled::TooGeneric),
EvalErrorKind::Layout(LayoutError::SizeOverflow(_)) |
EvalErrorKind::TypeckError => return Err(ErrorHandled::Reported),
_ => {},
}
trace!("reporting const eval failure at {:?}", self.span);
@ -117,7 +140,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
for FrameInfo { span, location, .. } in &self.stacktrace {
err.span_label(*span, format!("inside call to `{}`", location));
}
Some(err)
Ok(err)
}
}
@ -279,10 +302,9 @@ pub enum EvalErrorKind<'tcx, O> {
TypeckError,
/// Resolution can fail if we are in a too generic context
TooGeneric,
CheckMatchError,
/// Cannot compute this constant because it depends on another one
/// which already produced an error
ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
ReferencedConstant,
GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic,
InfiniteLoop,
@ -407,9 +429,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
"encountered constants with type errors, stopping evaluation",
TooGeneric =>
"encountered overly generic constant",
CheckMatchError =>
"match checking failed",
ReferencedConstant(_) =>
ReferencedConstant =>
"referenced constant has errors",
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",

View file

@ -20,7 +20,7 @@ mod value;
pub use self::error::{
EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
FrameInfo, ConstEvalResult,
FrameInfo, ConstEvalResult, ErrorHandled,
};
pub use self::value::{Scalar, ConstValue};
@ -176,7 +176,7 @@ impl<'tcx, Tag> Pointer<Tag> {
Pointer { alloc_id, offset, tag }
}
pub fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> Self {
pub fn wrapping_signed_offset(self, i: i64, cx: impl HasDataLayout) -> Self {
Pointer::new_with_tag(
self.alloc_id,
Size::from_bytes(cx.data_layout().wrapping_signed_offset(self.offset.bytes(), i)),
@ -184,12 +184,12 @@ impl<'tcx, Tag> Pointer<Tag> {
)
}
pub fn overflowing_signed_offset<C: HasDataLayout>(self, i: i128, cx: C) -> (Self, bool) {
pub fn overflowing_signed_offset(self, i: i128, cx: impl HasDataLayout) -> (Self, bool) {
let (res, over) = cx.data_layout().overflowing_signed_offset(self.offset.bytes(), i);
(Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
}
pub fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
pub fn signed_offset(self, i: i64, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
Ok(Pointer::new_with_tag(
self.alloc_id,
Size::from_bytes(cx.data_layout().signed_offset(self.offset.bytes(), i)?),
@ -197,12 +197,12 @@ impl<'tcx, Tag> Pointer<Tag> {
))
}
pub fn overflowing_offset<C: HasDataLayout>(self, i: Size, cx: C) -> (Self, bool) {
pub fn overflowing_offset(self, i: Size, cx: impl HasDataLayout) -> (Self, bool) {
let (res, over) = cx.data_layout().overflowing_offset(self.offset.bytes(), i.bytes());
(Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
}
pub fn offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
pub fn offset(self, i: Size, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
Ok(Pointer::new_with_tag(
self.alloc_id,
Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?),

View file

@ -880,18 +880,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.tcx.report_object_safety_error(span, did, violations)
}
ConstEvalFailure(ref err) => {
match err.struct_error(
self.tcx.at(span),
"could not evaluate constant expression",
) {
Some(err) => err,
None => {
self.tcx.sess.delay_span_bug(span,
&format!("constant in type had an ignored error: {:?}", err));
return;
}
}
// already reported in the query
ConstEvalFailure(_) => {
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
return;
}
Overflow => {

View file

@ -9,15 +9,13 @@
// except according to those terms.
use infer::InferCtxt;
use mir::interpret::GlobalId;
use mir::interpret::{GlobalId, ErrorHandled};
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
use ty::error::ExpectedFound;
use rustc_data_structures::obligation_forest::{Error, ForestObligation, ObligationForest};
use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
use std::marker::PhantomData;
use hir::def_id::DefId;
use mir::interpret::ConstEvalErr;
use mir::interpret::EvalErrorKind;
use super::CodeAmbiguity;
use super::CodeProjectionError;
@ -495,13 +493,9 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
CodeSelectionError(ConstEvalFailure(err)))
}
} else {
ProcessResult::Error(
CodeSelectionError(ConstEvalFailure(ConstEvalErr {
span: obligation.cause.span,
error: EvalErrorKind::TooGeneric.into(),
stacktrace: vec![],
}.into()))
)
ProcessResult::Error(CodeSelectionError(
ConstEvalFailure(ErrorHandled::TooGeneric)
))
}
},
None => {

View file

@ -23,7 +23,7 @@ use hir::def_id::DefId;
use infer::SuppressRegionErrors;
use infer::outlives::env::OutlivesEnvironment;
use middle::region;
use mir::interpret::ConstEvalErr;
use mir::interpret::ErrorHandled;
use ty::subst::Substs;
use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
use ty::error::{ExpectedFound, TypeError};
@ -438,7 +438,7 @@ pub enum SelectionError<'tcx> {
ty::PolyTraitRef<'tcx>,
ty::error::TypeError<'tcx>),
TraitNotObjectSafe(DefId),
ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
ConstEvalFailure(ErrorHandled),
Overflow,
}

View file

@ -172,9 +172,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
)
}
super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
err.into(),
)),
super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)),
super::Overflow => Some(super::Overflow),
}
}

View file

@ -27,7 +27,7 @@ use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangIte
use middle::privacy::AccessLevels;
use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir;
use mir::interpret::GlobalId;
use mir::interpret::{GlobalId, ErrorHandled};
use mir::GeneratorLayout;
use session::CrateDisambiguator;
use traits::{self, Reveal};
@ -2191,11 +2191,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
None
}
}
Err(err) => {
err.report_as_error(
tcx.at(tcx.def_span(expr_did)),
"could not evaluate enum discriminant",
);
Err(ErrorHandled::Reported) => {
if !expr_did.is_local() {
span_bug!(tcx.def_span(expr_did),
"variant discriminant evaluation succeeded \
@ -2203,6 +2199,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
}
None
}
Err(ErrorHandled::TooGeneric) => span_bug!(
tcx.def_span(expr_did),
"enum discriminant depends on generic arguments",
),
}
}

View file

@ -296,6 +296,30 @@ impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
}
impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
fn describe(
tcx: TyCtxt<'_, '_, '_>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> Cow<'static, str> {
format!(
"const-evaluating + checking `{}`",
tcx.item_path_str(key.value.instance.def.def_id()),
).into()
}
#[inline]
fn cache_on_disk(_key: Self::Key) -> bool {
true
}
#[inline]
fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
id: SerializedDepNodeIndex)
-> Option<Self::Value> {
tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok)
}
}
impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> Cow<'static, str>
{

View file

@ -301,6 +301,14 @@ define_queries! { <'tcx>
},
Other {
/// Evaluate a constant without running sanity checks
///
/// DO NOT USE THIS outside const eval. Const eval uses this to break query cycles during
/// validation. Please add a comment to every use site explaining why using `const_eval`
/// isn't sufficient
[] fn const_eval_raw: const_eval_raw_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> ConstEvalResult<'tcx>,
/// Results of evaluating const items or constants embedded in
/// other items (such as enum variant explicit discriminants).
[] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
@ -776,6 +784,10 @@ fn const_eval_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> DepConstructor<'tcx> {
DepConstructor::ConstEval { param_env }
}
fn const_eval_raw_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> DepConstructor<'tcx> {
DepConstructor::ConstEvalRaw { param_env }
}
fn mir_keys<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::MirKeys

View file

@ -1063,6 +1063,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::NeedsDrop |
DepKind::Layout |
DepKind::ConstEval |
DepKind::ConstEvalRaw |
DepKind::InstanceSymbolName |
DepKind::MirShim |
DepKind::BorrowCheckKrate |

View file

@ -13,7 +13,7 @@
//! hand, though we've recently added some macros (e.g.,
//! `BraceStructLiftImpl!`) to help with the tedium.
use mir::interpret::{ConstValue, ConstEvalErr};
use mir::interpret::ConstValue;
use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@ -460,164 +460,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
}
}
impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> {
type Lifted = ConstEvalErr<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
tcx.lift(&self.error).map(|error| {
ConstEvalErr {
span: self.span,
stacktrace: self.stacktrace.clone(),
error,
}
})
}
}
impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
type Lifted = interpret::EvalError<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
Some(interpret::EvalError {
kind: tcx.lift(&self.kind)?,
})
}
}
impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
type Lifted = interpret::EvalErrorKind<'tcx, <O as Lift<'tcx>>::Lifted>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
use ::mir::interpret::EvalErrorKind::*;
Some(match *self {
MachineError(ref err) => MachineError(err.clone()),
FunctionAbiMismatch(a, b) => FunctionAbiMismatch(a, b),
FunctionArgMismatch(a, b) => FunctionArgMismatch(
tcx.lift(&a)?,
tcx.lift(&b)?,
),
FunctionRetMismatch(a, b) => FunctionRetMismatch(
tcx.lift(&a)?,
tcx.lift(&b)?,
),
FunctionArgCountMismatch => FunctionArgCountMismatch,
NoMirFor(ref s) => NoMirFor(s.clone()),
UnterminatedCString(ptr) => UnterminatedCString(ptr),
DanglingPointerDeref => DanglingPointerDeref,
DoubleFree => DoubleFree,
InvalidMemoryAccess => InvalidMemoryAccess,
InvalidFunctionPointer => InvalidFunctionPointer,
InvalidBool => InvalidBool,
InvalidDiscriminant(val) => InvalidDiscriminant(val),
PointerOutOfBounds {
ptr,
access,
allocation_size,
} => PointerOutOfBounds { ptr, access, allocation_size },
InvalidNullPointerUsage => InvalidNullPointerUsage,
ReadPointerAsBytes => ReadPointerAsBytes,
ReadBytesAsPointer => ReadBytesAsPointer,
ReadForeignStatic => ReadForeignStatic,
InvalidPointerMath => InvalidPointerMath,
ReadUndefBytes(offset) => ReadUndefBytes(offset),
DeadLocal => DeadLocal,
InvalidBoolOp(bop) => InvalidBoolOp(bop),
Unimplemented(ref s) => Unimplemented(s.clone()),
DerefFunctionPointer => DerefFunctionPointer,
ExecuteMemory => ExecuteMemory,
BoundsCheck { ref len, ref index } => BoundsCheck {
len: tcx.lift(len)?,
index: tcx.lift(index)?,
},
Intrinsic(ref s) => Intrinsic(s.clone()),
InvalidChar(c) => InvalidChar(c),
StackFrameLimitReached => StackFrameLimitReached,
OutOfTls => OutOfTls,
TlsOutOfBounds => TlsOutOfBounds,
AbiViolation(ref s) => AbiViolation(s.clone()),
AlignmentCheckFailed {
required,
has,
} => AlignmentCheckFailed { required, has },
MemoryLockViolation {
ptr,
len,
frame,
access,
ref lock,
} => MemoryLockViolation { ptr, len, frame, access, lock: lock.clone() },
MemoryAcquireConflict {
ptr,
len,
kind,
ref lock,
} => MemoryAcquireConflict { ptr, len, kind, lock: lock.clone() },
InvalidMemoryLockRelease {
ptr,
len,
frame,
ref lock,
} => InvalidMemoryLockRelease { ptr, len, frame, lock: lock.clone() },
DeallocatedLockedMemory {
ptr,
ref lock,
} => DeallocatedLockedMemory { ptr, lock: lock.clone() },
ValidationFailure(ref s) => ValidationFailure(s.clone()),
CalledClosureAsFunction => CalledClosureAsFunction,
VtableForArgumentlessMethod => VtableForArgumentlessMethod,
ModifiedConstantMemory => ModifiedConstantMemory,
AssumptionNotHeld => AssumptionNotHeld,
InlineAsm => InlineAsm,
TypeNotPrimitive(ty) => TypeNotPrimitive(tcx.lift(&ty)?),
ReallocatedWrongMemoryKind(ref a, ref b) => {
ReallocatedWrongMemoryKind(a.clone(), b.clone())
},
DeallocatedWrongMemoryKind(ref a, ref b) => {
DeallocatedWrongMemoryKind(a.clone(), b.clone())
},
ReallocateNonBasePtr => ReallocateNonBasePtr,
DeallocateNonBasePtr => DeallocateNonBasePtr,
IncorrectAllocationInformation(a, b, c, d) => {
IncorrectAllocationInformation(a, b, c, d)
},
Layout(lay) => Layout(tcx.lift(&lay)?),
HeapAllocZeroBytes => HeapAllocZeroBytes,
HeapAllocNonPowerOfTwoAlignment(n) => HeapAllocNonPowerOfTwoAlignment(n),
Unreachable => Unreachable,
Panic { ref msg, ref file, line, col } => Panic {
msg: msg.clone(),
file: file.clone(),
line, col,
},
ReadFromReturnPointer => ReadFromReturnPointer,
PathNotFound(ref v) => PathNotFound(v.clone()),
UnimplementedTraitSelection => UnimplementedTraitSelection,
TypeckError => TypeckError,
TooGeneric => TooGeneric,
CheckMatchError => CheckMatchError,
ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(&**err)?.into()),
OverflowNeg => OverflowNeg,
Overflow(op) => Overflow(op),
DivisionByZero => DivisionByZero,
RemainderByZero => RemainderByZero,
GeneratorResumedAfterReturn => GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic => GeneratorResumedAfterPanic,
InfiniteLoop => InfiniteLoop,
})
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::layout::LayoutError<'a> {
type Lifted = ty::layout::LayoutError<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
match *self {
ty::layout::LayoutError::Unknown(ref ty) => {
tcx.lift(ty).map(ty::layout::LayoutError::Unknown)
}
ty::layout::LayoutError::SizeOverflow(ref ty) => {
tcx.lift(ty).map(ty::layout::LayoutError::SizeOverflow)
}
}
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
type Lifted = ty::InstanceDef<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {

View file

@ -9,12 +9,11 @@
// except according to those terms.
use llvm;
use rustc::mir::interpret::{ConstEvalErr, read_target_uint};
use rustc::mir::interpret::{ErrorHandled, read_target_uint};
use rustc_mir::const_eval::const_field;
use rustc::hir::def_id::DefId;
use rustc::mir;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::sync::Lrc;
use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size};
@ -124,7 +123,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
pub fn codegen_static_initializer(
cx: &CodegenCx<'ll, 'tcx>,
def_id: DefId,
) -> Result<(&'ll Value, &'tcx Allocation), Lrc<ConstEvalErr<'tcx>>> {
) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> {
let instance = ty::Instance::mono(cx.tcx, def_id);
let cid = GlobalId {
instance,
@ -145,7 +144,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
&mut self,
bx: &Builder<'a, 'll, 'tcx>,
constant: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
match constant.val {
ConstValue::Unevaluated(def_id, ref substs) => {
let tcx = bx.tcx();
@ -165,7 +164,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
&mut self,
bx: &Builder<'a, 'll, 'tcx>,
constant: &mir::Constant<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
let c = self.monomorphize(&constant.literal);
self.fully_evaluate(bx, c)
}
@ -176,7 +175,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
bx: &Builder<'a, 'll, 'tcx>,
span: Span,
ty: Ty<'tcx>,
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
constant: Result<&'tcx ty::Const<'tcx>, ErrorHandled>,
) -> (&'ll Value, Ty<'tcx>) {
constant
.and_then(|c| {
@ -185,7 +184,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
ref other => bug!("invalid simd shuffle type: {}", other),
};
let values: Result<Vec<_>, Lrc<_>> = (0..fields).map(|field| {
let values: Result<Vec<_>, ErrorHandled> = (0..fields).map(|field| {
let field = const_field(
bx.tcx(),
ty::ParamEnv::reveal_all(),
@ -211,9 +210,9 @@ impl FunctionCx<'a, 'll, 'tcx> {
let llval = C_struct(bx.cx, &values?, false);
Ok((llval, c.ty))
})
.unwrap_or_else(|e| {
e.report_as_error(
bx.tcx().at(span),
.unwrap_or_else(|_| {
bx.tcx().sess.span_err(
span,
"could not evaluate shuffle_indices at compile time",
);
// We've errored, so we don't have to produce working code.

View file

@ -8,11 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::mir::interpret::{ConstValue, ConstEvalErr};
use rustc::mir::interpret::{ConstValue, ErrorHandled};
use rustc::mir;
use rustc::ty;
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
use rustc_data_structures::sync::Lrc;
use base;
use common::{CodegenCx, C_undef, C_usize};
@ -79,7 +78,7 @@ impl OperandRef<'ll, 'tcx> {
pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
val: &'tcx ty::Const<'tcx>)
-> Result<OperandRef<'ll, 'tcx>, Lrc<ConstEvalErr<'tcx>>> {
-> Result<OperandRef<'ll, 'tcx>, ErrorHandled> {
let layout = bx.cx.layout_of(val.ty);
if layout.is_zst() {
@ -424,10 +423,13 @@ impl FunctionCx<'a, 'll, 'tcx> {
self.eval_mir_constant(bx, constant)
.and_then(|c| OperandRef::from_const(bx, c))
.unwrap_or_else(|err| {
err.report_as_error(
bx.tcx().at(constant.span),
"could not evaluate constant operand",
);
match err {
// errored or at least linted
ErrorHandled::Reported => {},
ErrorHandled::TooGeneric => {
bug!("codgen encountered polymorphic constant")
},
}
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
// the above error (or silence it under some conditions) will not cause UB
let fnname = bx.cx.get_intrinsic(&("llvm.trap"));

View file

@ -1271,50 +1271,7 @@ impl LintPass for UnusedBrokenConst {
lint_array!()
}
}
fn validate_const<'a, 'tcx>(
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
constant: &ty::Const<'tcx>,
param_env: ty::ParamEnv<'tcx>,
gid: ::rustc::mir::interpret::GlobalId<'tcx>,
what: &str,
) {
let ecx = ::rustc_mir::const_eval::mk_eval_cx(tcx, gid.instance, param_env).unwrap();
let result = (|| {
let op = ecx.const_to_op(constant)?;
let mut ref_tracking = ::rustc_mir::interpret::RefTracking::new(op);
while let Some((op, mut path)) = ref_tracking.todo.pop() {
ecx.validate_operand(
op,
&mut path,
Some(&mut ref_tracking),
/* const_mode */ true,
)?;
}
Ok(())
})();
if let Err(err) = result {
let (trace, span) = ecx.generate_stacktrace(None);
let err = ::rustc::mir::interpret::ConstEvalErr {
error: err,
stacktrace: trace,
span,
};
let err = err.struct_error(
tcx.at(span),
&format!("this {} likely exhibits undefined behavior", what),
);
if let Some(mut err) = err {
err.note("The rules on what exactly is undefined behavior aren't clear, \
so this check might be overzealous. Please open an issue on the rust compiler \
repository if you believe it should not be considered undefined behavior",
);
err.emit();
}
}
}
fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) {
fn check_const(cx: &LateContext, body_id: hir::BodyId) {
let def_id = cx.tcx.hir.body_owner_def_id(body_id);
let is_static = cx.tcx.is_static(def_id).is_some();
let param_env = if is_static {
@ -1327,46 +1284,19 @@ fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) {
instance: ty::Instance::mono(cx.tcx, def_id),
promoted: None
};
match cx.tcx.const_eval(param_env.and(cid)) {
Ok(val) => validate_const(cx.tcx, val, param_env, cid, what),
Err(err) => {
// errors for statics are already reported directly in the query, avoid duplicates
if !is_static {
let span = cx.tcx.def_span(def_id);
err.report_as_lint(
cx.tcx.at(span),
&format!("this {} cannot be used", what),
cx.current_lint_root(),
);
}
},
}
}
struct UnusedBrokenConstVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);
impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for UnusedBrokenConstVisitor<'a, 'tcx> {
fn visit_nested_body(&mut self, id: hir::BodyId) {
check_const(self.0, id, "array length");
}
fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
hir::intravisit::NestedVisitorMap::None
}
// trigger the query once for all constants since that will already report the errors
let _ = cx.tcx.const_eval(param_env.and(cid));
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
match it.node {
hir::ItemKind::Const(_, body_id) => {
check_const(cx, body_id, "constant");
check_const(cx, body_id);
},
hir::ItemKind::Static(_, _, body_id) => {
check_const(cx, body_id, "static");
check_const(cx, body_id);
},
hir::ItemKind::Ty(ref ty, _) => hir::intravisit::walk_ty(
&mut UnusedBrokenConstVisitor(cx),
ty
),
_ => {},
}
}

View file

@ -17,13 +17,16 @@ use std::hash::Hash;
use std::collections::hash_map::Entry;
use rustc::hir::{self, def_id::DefId};
use rustc::mir::interpret::ConstEvalErr;
use rustc::hir::def::Def;
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
use rustc::mir;
use rustc::ty::{self, Ty, TyCtxt, Instance, query::TyCtxtAt};
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout};
use rustc::ty::subst::Subst;
use rustc::traits::Reveal;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::fx::FxHashMap;
use rustc::util::common::ErrorReported;
use syntax::ast::Mutability;
use syntax::source_map::{Span, DUMMY_SP};
@ -32,7 +35,7 @@ use interpret::{self,
PlaceTy, MemPlace, OpTy, Operand, Value, Pointer, Scalar, ConstValue,
EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup,
Allocation, AllocId, MemoryKind,
snapshot,
snapshot, RefTracking,
};
/// Number of steps until the detector even starts doing anything.
@ -509,13 +512,11 @@ pub fn const_field<'a, 'tcx>(
// this is not called for statics.
op_to_const(&ecx, field, true)
})();
result.map_err(|err| {
let (trace, span) = ecx.generate_stacktrace(None);
ConstEvalErr {
error: err,
stacktrace: trace,
span,
}.into()
result.map_err(|error| {
let stacktrace = ecx.generate_stacktrace(None);
let err = ::rustc::mir::interpret::ConstEvalErr { error, stacktrace, span: ecx.tcx.span };
err.report_as_error(ecx.tcx, "could not access field of constant");
ErrorHandled::Reported
})
}
@ -531,41 +532,97 @@ pub fn const_variant_index<'a, 'tcx>(
Ok(ecx.read_discriminant(op)?.1)
}
pub fn const_to_allocation_provider<'a, 'tcx>(
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
val: &'tcx ty::Const<'tcx>,
) -> &'tcx Allocation {
// FIXME: This really does not need to be a query. Instead, we should have a query for statics
// that returns an allocation directly (or an `AllocId`?), after doing a sanity check of the
// value and centralizing error reporting.
match val.val {
ConstValue::ByRef(_, alloc, offset) => {
assert_eq!(offset.bytes(), 0);
return alloc;
},
_ => bug!("const_to_allocation called on non-static"),
}
fn validate_const<'a, 'tcx>(
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
constant: &'tcx ty::Const<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
let cid = key.value;
let ecx = mk_eval_cx(tcx, cid.instance, key.param_env).unwrap();
let val = (|| {
let op = ecx.const_to_op(constant)?;
let mut ref_tracking = RefTracking::new(op);
while let Some((op, mut path)) = ref_tracking.todo.pop() {
ecx.validate_operand(
op,
&mut path,
Some(&mut ref_tracking),
/* const_mode */ true,
)?;
}
Ok(constant)
})();
val.map_err(|error| {
let stacktrace = ecx.generate_stacktrace(None);
let err = ::rustc::mir::interpret::ConstEvalErr { error, stacktrace, span: ecx.tcx.span };
match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") {
Ok(mut diag) => {
diag.note("The rules on what exactly is undefined behavior aren't clear, \
so this check might be overzealous. Please open an issue on the rust compiler \
repository if you believe it should not be considered undefined behavior",
);
diag.emit();
ErrorHandled::Reported
}
Err(err) => err,
}
})
}
pub fn const_eval_provider<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
// see comment in const_eval_provider for what we're doing here
if key.param_env.reveal == Reveal::All {
let mut key = key.clone();
key.param_env.reveal = Reveal::UserFacing;
match tcx.const_eval(key) {
// try again with reveal all as requested
Err(ErrorHandled::TooGeneric) => {},
// dedupliate calls
other => return other,
}
}
tcx.const_eval_raw(key).and_then(|val| {
validate_const(tcx, val, key)
})
}
pub fn const_eval_raw_provider<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
// Because the constant is computed twice (once per value of `Reveal`), we are at risk of
// reporting the same error twice here. To resolve this, we check whether we can evaluate the
// constant in the more restrictive `Reveal::UserFacing`, which most likely already was
// computed. For a large percentage of constants that will already have succeeded. Only
// associated constants of generic functions will fail due to not enough monomorphization
// information being available.
// In case we fail in the `UserFacing` variant, we just do the real computation.
if key.param_env.reveal == Reveal::All {
let mut key = key.clone();
key.param_env.reveal = Reveal::UserFacing;
match tcx.const_eval_raw(key) {
// try again with reveal all as requested
Err(ErrorHandled::TooGeneric) => {},
// dedupliate calls
other => return other,
}
}
trace!("const eval: {:?}", key);
let cid = key.value;
let def_id = cid.instance.def.def_id();
if let Some(id) = tcx.hir.as_local_node_id(def_id) {
let tables = tcx.typeck_tables_of(def_id);
let span = tcx.def_span(def_id);
// Do match-check before building MIR
if tcx.check_match(def_id).is_err() {
return Err(ConstEvalErr {
error: EvalErrorKind::CheckMatchError.into(),
stacktrace: vec![],
span,
}.into());
if let Err(ErrorReported) = tcx.check_match(def_id) {
return Err(ErrorHandled::Reported)
}
if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) {
@ -574,11 +631,7 @@ pub fn const_eval_provider<'a, 'tcx>(
// Do not continue into miri if typeck errors occurred; it will fail horribly
if tables.tainted_by_errors {
return Err(ConstEvalErr {
error: EvalErrorKind::CheckMatchError.into(),
stacktrace: vec![],
span,
}.into());
return Err(ErrorHandled::Reported)
}
};
@ -593,19 +646,62 @@ pub fn const_eval_provider<'a, 'tcx>(
}
}
op_to_const(&ecx, op, normalize)
}).map_err(|err| {
let (trace, span) = ecx.generate_stacktrace(None);
let err = ConstEvalErr {
error: err,
stacktrace: trace,
span,
};
}).map_err(|error| {
let stacktrace = ecx.generate_stacktrace(None);
let err = ConstEvalErr { error, stacktrace, span: ecx.tcx.span };
// errors in statics are always emitted as fatal errors
if tcx.is_static(def_id).is_some() {
err.report_as_error(ecx.tcx, "could not evaluate static initializer");
let err = err.report_as_error(ecx.tcx, "could not evaluate static initializer");
// check that a static never produces `TooGeneric`
if tcx.sess.err_count() == 0 {
span_bug!(span, "static eval failure didn't emit an error: {:#?}", err);
span_bug!(ecx.tcx.span, "static eval failure didn't emit an error: {:#?}", err);
}
err
} else if def_id.is_local() {
// constant defined in this crate, we can figure out a lint level!
match tcx.describe_def(def_id) {
// constants never produce a hard error at the definition site. Anything else is
// a backwards compatibility hazard (and will break old versions of winapi for sure)
//
// note that validation may still cause a hard error on this very same constant,
// because any code that existed before validation could not have failed validation
// thus preventing such a hard error from being a backwards compatibility hazard
Some(Def::Const(_)) | Some(Def::AssociatedConst(_)) => {
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
err.report_as_lint(
tcx.at(tcx.def_span(def_id)),
"any use of this value will cause an error",
node_id,
)
},
// promoting runtime code is only allowed to error if it references broken constants
// any other kind of error will be reported to the user as a deny-by-default lint
_ => if let Some(p) = cid.promoted {
let span = tcx.optimized_mir(def_id).promoted[p].span;
if let EvalErrorKind::ReferencedConstant = err.error.kind {
err.report_as_error(
tcx.at(span),
"evaluation of constant expression failed",
)
} else {
err.report_as_lint(
tcx.at(span),
"reaching this expression at runtime will panic or abort",
tcx.hir.as_local_node_id(def_id).unwrap(),
)
}
// anything else (array lengths, enum initializers, constant patterns) are reported
// as hard errors
} else {
err.report_as_error(
ecx.tcx,
"evaluation of constant value failed",
)
},
}
} else {
// use of broken constant from other crate
err.report_as_error(ecx.tcx, "could not evaluate constant")
}
err.into()
})
}

View file

@ -15,7 +15,7 @@ use hair::cx::block;
use hair::cx::to_ref::ToRef;
use hair::util::UserAnnotatedTyHelpers;
use rustc::hir::def::{Def, CtorKind};
use rustc::mir::interpret::GlobalId;
use rustc::mir::interpret::{GlobalId, ErrorHandled};
use rustc::ty::{self, AdtKind, Ty};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
use rustc::ty::cast::CastKind as TyCastKind;
@ -571,8 +571,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let span = cx.tcx.def_span(def_id);
let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
Ok(cv) => cv.unwrap_usize(cx.tcx),
Err(e) => {
e.report_as_error(cx.tcx.at(span), "could not evaluate array length");
Err(ErrorHandled::Reported) => 0,
Err(ErrorHandled::TooGeneric) => {
cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");
0
},
};

View file

@ -732,13 +732,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
Ok(value) => {
return self.const_to_pat(instance, value, id, span)
},
Err(err) => {
err.report_as_error(
self.tcx.at(span),
Err(_) => {
self.tcx.sess.span_err(
span,
"could not evaluate constant pattern",
);
PatternKind::Wild
},
}
}
},
None => {

View file

@ -24,6 +24,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::query::TyCtxtAt;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::mir::interpret::{
ErrorHandled,
GlobalId, Scalar, FrameInfo, AllocId,
EvalResult, EvalErrorKind,
truncate, sign_extend,
@ -611,8 +612,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
} else {
self.param_env
};
self.tcx.const_eval(param_env.and(gid))
.map_err(|err| EvalErrorKind::ReferencedConstant(err).into())
self.tcx.const_eval(param_env.and(gid)).map_err(|err| {
match err {
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
}
})
}
pub fn dump_place(&self, place: Place<M::PointerTag>) {
@ -679,7 +684,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
}
}
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> (Vec<FrameInfo>, Span) {
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo> {
let mut last_span = None;
let mut frames = Vec::new();
// skip 1 because the last frame is just the environment of the constant
@ -716,7 +721,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
frames.push(FrameInfo { span, location, lint_root });
}
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
(frames, self.tcx.span)
frames
}
#[inline(always)]

View file

@ -30,7 +30,7 @@ use syntax::ast::Mutability;
use super::{
Pointer, AllocId, Allocation, ConstValue, GlobalId,
EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic,
Machine, MemoryAccess, AllocMap, MayLeak, ScalarMaybeUndef,
Machine, MemoryAccess, AllocMap, MayLeak, ScalarMaybeUndef, ErrorHandled,
};
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
@ -368,10 +368,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
instance,
promoted: None,
};
tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
// use the raw query here to break validation cycles. Later uses of the static will call the
// full query anyway
tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
// no need to report anything, the const_eval call takes care of that for statics
assert!(tcx.is_static(def_id).is_some());
EvalErrorKind::ReferencedConstant(err).into()
match err {
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
}
}).map(|const_val| {
if let ConstValue::ByRef(_, allocation, _) = const_val.val {
// We got tcx memory. Let the machine figure out whether and how to

View file

@ -125,6 +125,12 @@ impl<Tag> MemPlace<Tag> {
}
}
/// Produces a Place that will error if attempted to be read from or written to
#[inline(always)]
pub fn null(cx: impl HasDataLayout) -> Self {
Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1, 1).unwrap())
}
#[inline(always)]
pub fn from_ptr(ptr: Pointer<Tag>, align: Align) -> Self {
Self::from_scalar_ptr(ptr.into(), align)
@ -209,17 +215,17 @@ impl<'tcx, Tag: ::std::fmt::Debug> OpTy<'tcx, Tag> {
impl<'tcx, Tag: ::std::fmt::Debug> Place<Tag> {
/// Produces a Place that will error if attempted to be read from or written to
#[inline]
#[inline(always)]
pub fn null(cx: impl HasDataLayout) -> Self {
Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1, 1).unwrap())
Place::Ptr(MemPlace::null(cx))
}
#[inline]
#[inline(always)]
pub fn from_scalar_ptr(ptr: Scalar<Tag>, align: Align) -> Self {
Place::Ptr(MemPlace::from_scalar_ptr(ptr, align))
}
#[inline]
#[inline(always)]
pub fn from_ptr(ptr: Pointer<Tag>, align: Align) -> Self {
Place::Ptr(MemPlace::from_ptr(ptr, align))
}
@ -880,9 +886,14 @@ where
layout: TyLayout<'tcx>,
kind: MemoryKind<M::MemoryKinds>,
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
assert!(!layout.is_unsized(), "cannot alloc memory for unsized type");
let ptr = self.memory.allocate(layout.size, layout.align, kind)?;
Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
if layout.is_unsized() {
assert!(self.tcx.features().unsized_locals, "cannot alloc memory for unsized type");
// FIXME: What should we do here?
Ok(MPlaceTy::dangling(layout, &self))
} else {
let ptr = self.memory.allocate(layout.size, layout.align, kind)?;
Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
}
}
pub fn write_discriminant_index(

View file

@ -95,6 +95,7 @@ pub fn provide(providers: &mut Providers) {
shim::provide(providers);
transform::provide(providers);
providers.const_eval = const_eval::const_eval_provider;
providers.const_eval_raw = const_eval::const_eval_raw_provider;
providers.check_match = hair::pattern::check_match;
}

View file

@ -202,7 +202,7 @@ use rustc::session::config;
use rustc::mir::{self, Location, Promoted};
use rustc::mir::visit::Visitor as MirVisitor;
use rustc::mir::mono::MonoItem;
use rustc::mir::interpret::{Scalar, GlobalId, AllocType};
use rustc::mir::interpret::{Scalar, GlobalId, AllocType, ErrorHandled};
use monomorphize::{self, Instance};
use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
@ -988,6 +988,20 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
hir::ItemKind::Const(..) => {
// const items only generate mono items if they are
// actually used somewhere. Just declaring them is insufficient.
// but even just declaring them must collect the items they refer to
let def_id = self.tcx.hir.local_def_id(item.id);
let instance = Instance::mono(self.tcx, def_id);
let cid = GlobalId {
instance,
promoted: None,
};
let param_env = ty::ParamEnv::reveal_all();
if let Ok(val) = self.tcx.const_eval(param_env.and(cid)) {
collect_const(self.tcx, val, instance.substs, &mut self.output);
}
}
hir::ItemKind::Fn(..) => {
let def_id = self.tcx.hir.local_def_id(item.id);
@ -1198,15 +1212,10 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
};
match tcx.const_eval(param_env.and(cid)) {
Ok(val) => collect_const(tcx, val, instance.substs, output),
Err(err) => {
use rustc::mir::interpret::EvalErrorKind;
if let EvalErrorKind::ReferencedConstant(_) = err.error.kind {
err.report_as_error(
tcx.at(mir.promoted[i].span),
"erroneous constant used",
);
}
},
Err(ErrorHandled::Reported) => {},
Err(ErrorHandled::TooGeneric) => span_bug!(
mir.promoted[i].span, "collection encountered polymorphic constant",
),
}
}
}
@ -1247,14 +1256,10 @@ fn collect_const<'a, 'tcx>(
};
match tcx.const_eval(param_env.and(cid)) {
Ok(val) => val.val,
Err(err) => {
let span = tcx.def_span(def_id);
err.report_as_error(
tcx.at(span),
"constant evaluation error",
);
return;
}
Err(ErrorHandled::Reported) => return,
Err(ErrorHandled::TooGeneric) => span_bug!(
tcx.def_span(def_id), "collection encountered polymorphic constant",
),
}
},
_ => constant.val,

View file

@ -18,7 +18,7 @@ use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind};
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
use rustc::mir::visit::{Visitor, PlaceContext};
use rustc::mir::interpret::{
ConstEvalErr, EvalErrorKind, Scalar, GlobalId, EvalResult
ConstEvalErr, EvalErrorKind, Scalar, GlobalId, EvalResult,
};
use rustc::ty::{TyCtxt, self, Instance};
use interpret::{self, EvalContext, Value, OpTy, MemoryKind, ScalarMaybeUndef};
@ -44,14 +44,24 @@ impl MirPass for ConstProp {
if source.promoted.is_some() {
return;
}
match tcx.describe_def(source.def_id) {
// skip statics/consts because they'll be evaluated by miri anyway
Some(Def::Const(..)) |
Some(Def::Static(..)) => return,
// we still run on associated constants, because they might not get evaluated
// within the current crate
_ => {},
use rustc::hir::map::blocks::FnLikeNode;
let node_id = tcx.hir.as_local_node_id(source.def_id)
.expect("Non-local call to local provider is_const_fn");
let is_fn_like = FnLikeNode::from_node(tcx.hir.get(node_id)).is_some();
let is_assoc_const = match tcx.describe_def(source.def_id) {
Some(Def::AssociatedConst(_)) => true,
_ => false,
};
// Only run const prop on functions, methods, closures and associated constants
if !is_fn_like && !is_assoc_const {
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
trace!("ConstProp skipped for {:?}", source.def_id);
return
}
trace!("ConstProp starting for {:?}", source.def_id);
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
@ -144,8 +154,8 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
let r = match f(self) {
Ok(val) => Some(val),
Err(error) => {
let (stacktrace, span) = self.ecx.generate_stacktrace(None);
let diagnostic = ConstEvalErr { span, error, stacktrace };
let stacktrace = self.ecx.generate_stacktrace(None);
let diagnostic = ConstEvalErr { span: source_info.span, error, stacktrace };
use rustc::mir::interpret::EvalErrorKind::*;
match diagnostic.error.kind {
// don't report these, they make no sense in a const prop context
@ -208,7 +218,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
| ReadFromReturnPointer
| GeneratorResumedAfterReturn
| GeneratorResumedAfterPanic
| ReferencedConstant(_)
| ReferencedConstant
| InfiniteLoop
=> {
// FIXME: report UB here
@ -223,7 +233,6 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
| UnimplementedTraitSelection
| TypeckError
| TooGeneric
| CheckMatchError
// these are just noise
=> {},
@ -264,16 +273,11 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
Some((op, c.span))
},
Err(error) => {
let (stacktrace, span) = self.ecx.generate_stacktrace(None);
let err = ConstEvalErr {
span,
error,
stacktrace,
let stacktrace = self.ecx.generate_stacktrace(None);
let err = ::rustc::mir::interpret::ConstEvalErr {
error, stacktrace, span: source_info.span,
};
err.report_as_error(
self.tcx.at(source_info.span),
"could not evaluate constant",
);
err.report_as_error(self.ecx.tcx, "erroneous constant used");
None
},
}

View file

@ -4238,13 +4238,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
let count = tcx.const_eval(param_env.and(global_id));
if let Err(ref err) = count {
err.report_as_error(
tcx.at(tcx.def_span(count_def_id)),
"could not evaluate repeat length",
);
}
let uty = match expected {
ExpectHasType(uty) => {
match uty.sty {

View file

@ -38,6 +38,7 @@ mod mod1 {
fn do_something_else(&self, x: T) -> T { x }
}
//~ MONO_ITEM fn vtable_through_const::mod1[0]::id[0]<i64> @@ vtable_through_const-mod1.volatile[Internal]
fn id<T>(x: T) -> T { x }
// These are referenced, so they produce mono-items (see start())
@ -52,6 +53,8 @@ mod mod1 {
fn do_something_else(&self) {}
}
//~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait2[0]::do_something[0]<u32> @@ vtable_through_const-mod1.volatile[Internal]
//~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait2[0]::do_something_else[0]<u32> @@ vtable_through_const-mod1.volatile[Internal]
impl Trait2 for u32 {}
pub trait Trait2Gen<T> {
@ -89,6 +92,8 @@ fn start(_: isize, _: *const *const u8) -> isize {
// Same as above
//~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[1]::do_something[0]<u8> @@ vtable_through_const-mod1.volatile[External]
//~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[1]::do_something_else[0]<u8> @@ vtable_through_const-mod1.volatile[External]
//~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[3]::do_something[0]<u8> @@ vtable_through_const-mod1.volatile[Internal]
//~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[3]::do_something_else[0]<u8> @@ vtable_through_const-mod1.volatile[Internal]
mod1::TRAIT1_GEN_REF.do_something(0u8);
//~ MONO_ITEM fn vtable_through_const::mod1[0]::id[0]<char> @@ vtable_through_const-mod1.volatile[External]

View file

@ -26,5 +26,5 @@ const fn f(x: usize) -> usize {
#[allow(unused_variables)]
fn main() {
let a : [i32; f(X)]; //~ ERROR E0080
let a : [i32; f(X)];
}

View file

@ -14,5 +14,4 @@ fn main() {
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
//~^ ERROR constant contains unimplemented expression type
//~| ERROR could not evaluate repeat length
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Just check if we don't get an ICE for the _S type.
// Just check we don't get an ICE for `N`.
use std::cell::Cell;
use std::mem;
@ -17,4 +17,4 @@ pub struct S {
s: Cell<usize>
}
pub type _S = [usize; 0 - (mem::size_of::<S>() != 4) as usize];
pub const N: usize = 0 - (mem::size_of::<S>() != 4) as usize;

View file

@ -11,7 +11,7 @@
const A: &'static [i32] = &[];
const B: i32 = (&A)[1];
//~^ index out of bounds: the len is 0 but the index is 1
//~| ERROR this constant cannot be used
//~| ERROR any use of this value will cause an error
fn main() {
let _ = B;

View file

@ -1,4 +1,4 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/array_const_index-0.rs:12:1
|
LL | const B: i32 = (&A)[1];

View file

@ -11,7 +11,7 @@
const A: [i32; 0] = [];
const B: i32 = A[1];
//~^ index out of bounds: the len is 0 but the index is 1
//~| ERROR this constant cannot be used
//~| ERROR any use of this value will cause an error
fn main() {
let _ = B;

View file

@ -1,4 +1,4 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/array_const_index-1.rs:12:1
|
LL | const B: i32 = A[1];

View file

@ -16,7 +16,7 @@ const FOO: [usize; 3] = [1, 2, 3];
const BAR: usize = FOO[5]; // no error, because the error below occurs before regular const eval
const BLUB: [u32; FOO[4]] = [5, 6];
//~^ ERROR could not evaluate constant expression [E0080]
//~^ ERROR evaluation of constant value failed [E0080]
//~| index out of bounds: the len is 3 but the index is 4
fn main() {

View file

@ -1,19 +1,9 @@
error: index out of bounds: the len is 3 but the index is 4
error[E0080]: evaluation of constant value failed
--> $DIR/const-array-oob.rs:18:19
|
LL | const BLUB: [u32; FOO[4]] = [5, 6];
| ^^^^^^
|
= note: #[deny(const_err)] on by default
| ^^^^^^ index out of bounds: the len is 3 but the index is 4
error[E0080]: could not evaluate constant expression
--> $DIR/const-array-oob.rs:18:13
|
LL | const BLUB: [u32; FOO[4]] = [5, 6];
| ^^^^^^------^
| |
| index out of bounds: the len is 3 but the index is 4
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -1,4 +1,4 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-early.rs:13:1
|
LL | pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
@ -12,7 +12,7 @@ note: lint level defined here
LL | #![deny(const_err)]
| ^^^^^^^^^
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-early.rs:14:1
|
LL | pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
@ -20,7 +20,7 @@ LL | pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
| |
| attempt to add with overflow
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-early.rs:15:1
|
LL | pub const C: u8 = 200u8 * 4; //~ ERROR const_err
@ -28,7 +28,7 @@ LL | pub const C: u8 = 200u8 * 4; //~ ERROR const_err
| |
| attempt to multiply with overflow
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-early.rs:16:1
|
LL | pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
@ -36,7 +36,7 @@ LL | pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
| |
| attempt to subtract with overflow
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-early.rs:17:1
|
LL | pub const E: u8 = [5u8][1]; //~ ERROR const_err

View file

@ -11,16 +11,13 @@
#![deny(const_err)]
pub const A: i8 = -std::i8::MIN;
//~^ ERROR this constant cannot be used
//~^ ERROR const_err
pub const B: i8 = A;
//~^ ERROR const_err
//~| ERROR const_err
pub const C: u8 = A as u8;
//~^ ERROR const_err
//~| ERROR const_err
pub const D: i8 = 50 - A;
//~^ ERROR const_err
//~| ERROR const_err
fn main() {
let _ = (A, B, C, D);

View file

@ -1,4 +1,4 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-multi.rs:13:1
|
LL | pub const A: i8 = -std::i8::MIN;
@ -12,16 +12,7 @@ note: lint level defined here
LL | #![deny(const_err)]
| ^^^^^^^^^
error: referenced constant has errors
--> $DIR/const-err-multi.rs:15:1
|
LL | pub const A: i8 = -std::i8::MIN;
| ------------- attempt to negate with overflow
LL | //~^ ERROR this constant cannot be used
LL | pub const B: i8 = A;
| ^^^^^^^^^^^^^^^^^^^^
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-err-multi.rs:15:1
|
LL | pub const B: i8 = A;
@ -29,39 +20,21 @@ LL | pub const B: i8 = A;
| |
| referenced constant has errors
error: referenced constant has errors
--> $DIR/const-err-multi.rs:18:1
|
LL | pub const A: i8 = -std::i8::MIN;
| ------------- attempt to negate with overflow
...
LL | pub const C: u8 = A as u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this constant cannot be used
--> $DIR/const-err-multi.rs:18:1
error: any use of this value will cause an error
--> $DIR/const-err-multi.rs:17:1
|
LL | pub const C: u8 = A as u8;
| ^^^^^^^^^^^^^^^^^^-------^
| |
| referenced constant has errors
error: referenced constant has errors
--> $DIR/const-err-multi.rs:21:1
|
LL | pub const A: i8 = -std::i8::MIN;
| ------------- attempt to negate with overflow
...
LL | pub const D: i8 = 50 - A;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: this constant cannot be used
--> $DIR/const-err-multi.rs:21:1
error: any use of this value will cause an error
--> $DIR/const-err-multi.rs:19:1
|
LL | pub const D: i8 = 50 - A;
| ^^^^^^^^^^^^^^^^^^------^
| |
| referenced constant has errors
error: aborting due to 7 previous errors
error: aborting due to 4 previous errors

View file

@ -10,23 +10,17 @@
// compile-flags: -Zforce-overflow-checks=on
// these errors are not actually "const_err", they occur in codegen/consts
// and are unconditional warnings that can't be denied or allowed
#![allow(exceeding_bitshifts)]
#![allow(const_err)]
#![warn(const_err)]
fn black_box<T>(_: T) {
unimplemented!()
}
// Make sure that the two uses get two errors.
const FOO: u8 = [5u8][1];
//~^ ERROR constant evaluation error
//~| index out of bounds: the len is 1 but the index is 1
//~^ WARN any use of this value will cause an error
fn main() {
black_box((FOO, FOO));
//~^ ERROR referenced constant has errors
//~| ERROR could not evaluate constant
//~^ ERROR erroneous constant used
}

View file

@ -1,26 +1,23 @@
error[E0080]: referenced constant has errors
--> $DIR/const-err.rs:29:15
|
LL | const FOO: u8 = [5u8][1];
| -------- index out of bounds: the len is 1 but the index is 1
...
LL | black_box((FOO, FOO));
| ^^^^^^^^^^
error[E0080]: could not evaluate constant
--> $DIR/const-err.rs:29:15
|
LL | black_box((FOO, FOO));
| ^^^^^^^^^^ referenced constant has errors
error[E0080]: constant evaluation error
--> $DIR/const-err.rs:24:1
warning: any use of this value will cause an error
--> $DIR/const-err.rs:20:1
|
LL | const FOO: u8 = [5u8][1];
| ^^^^^^^^^^^^^^^^--------^
| |
| index out of bounds: the len is 1 but the index is 1
|
note: lint level defined here
--> $DIR/const-err.rs:14:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
error: aborting due to 3 previous errors
error[E0080]: erroneous constant used
--> $DIR/const-err.rs:24:15
|
LL | black_box((FOO, FOO));
| ^^^^^^^^^^ referenced constant has errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -16,7 +16,7 @@ union Foo {
enum Bar {
Boo = [unsafe { Foo { b: () }.a }; 4][3],
//~^ ERROR could not evaluate enum discriminant
//~^ ERROR evaluation of constant value failed
}
fn main() {

View file

@ -1,4 +1,4 @@
error[E0080]: could not evaluate enum discriminant
error[E0080]: evaluation of constant value failed
--> $DIR/const-err4.rs:18:11
|
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],

View file

@ -13,10 +13,9 @@
const X: u32 = 5;
const Y: u32 = 6;
const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
//~^ WARN this constant cannot be used
//~^ WARN any use of this value will cause an error
fn main() {
println!("{}", FOO);
//~^ ERROR
//~| ERROR
}

View file

@ -1,4 +1,4 @@
warning: this constant cannot be used
warning: any use of this value will cause an error
--> $DIR/conditional_array_execution.rs:15:1
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
@ -12,21 +12,12 @@ note: lint level defined here
LL | #![warn(const_err)]
| ^^^^^^^^^
error[E0080]: referenced constant has errors
--> $DIR/conditional_array_execution.rs:19:20
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ----- attempt to subtract with overflow
...
LL | println!("{}", FOO);
| ^^^
error[E0080]: erroneous constant used
error[E0080]: evaluation of constant expression failed
--> $DIR/conditional_array_execution.rs:19:20
|
LL | println!("{}", FOO);
| ^^^ referenced constant has errors
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -1,12 +1,8 @@
error[E0080]: could not evaluate constant pattern
error: could not evaluate constant pattern
--> $DIR/const-eval-overflow-2.rs:25:9
|
LL | const NEG_NEG_128: i8 = -NEG_128;
| -------- attempt to negate with overflow
...
LL | NEG_NEG_128 => println!("A"),
| ^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -1,19 +1,9 @@
error: attempt to add with overflow
error[E0080]: evaluation of constant value failed
--> $DIR/const-eval-overflow-3.rs:30:11
|
LL | = [0; (i8::MAX + 1) as usize];
| ^^^^^^^^^^^^^
|
= note: #[deny(const_err)] on by default
| ^^^^^^^^^^^^^ attempt to add with overflow
error[E0080]: could not evaluate repeat length
--> $DIR/const-eval-overflow-3.rs:30:11
|
LL | = [0; (i8::MAX + 1) as usize];
| -------------^^^^^^^^^
| |
| attempt to add with overflow
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -21,8 +21,7 @@ use std::{u8, u16, u32, u64, usize};
const A_I8_T
: [u32; (i8::MAX as i8 + 1i8) as usize]
//~^ ERROR attempt to add with overflow
//~| ERROR could not evaluate constant expression
//~^ ERROR evaluation of constant value failed
= [0; (i8::MAX as usize) + 1];
fn main() {

View file

@ -1,19 +1,9 @@
error: attempt to add with overflow
error[E0080]: evaluation of constant value failed
--> $DIR/const-eval-overflow-4.rs:23:13
|
LL | : [u32; (i8::MAX as i8 + 1i8) as usize]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(const_err)] on by default
| ^^^^^^^^^^^^^^^^^^^^^ attempt to add with overflow
error[E0080]: could not evaluate constant expression
--> $DIR/const-eval-overflow-4.rs:23:7
|
LL | : [u32; (i8::MAX as i8 + 1i8) as usize]
| ^^^^^^---------------------^^^^^^^^^^
| |
| attempt to add with overflow
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -21,48 +21,40 @@ use std::fmt;
use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};
const VALS_I8: (i8,) =
//~^ ERROR this constant cannot be used
const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
(
i8::MIN - 1,
);
const VALS_I16: (i16,) =
//~^ ERROR this constant cannot be used
const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
(
i16::MIN - 1,
);
const VALS_I32: (i32,) =
//~^ ERROR this constant cannot be used
const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
(
i32::MIN - 1,
);
const VALS_I64: (i64,) =
//~^ ERROR this constant cannot be used
const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
(
i64::MIN - 1,
);
const VALS_U8: (u8,) =
//~^ ERROR this constant cannot be used
const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
(
u8::MIN - 1,
);
const VALS_U16: (u16,) = (
//~^ ERROR this constant cannot be used
const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
u16::MIN - 1,
);
const VALS_U32: (u32,) = (
//~^ ERROR this constant cannot be used
const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
u32::MIN - 1,
);
const VALS_U64: (u64,) =
//~^ ERROR this constant cannot be used
const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
(
u64::MIN - 1,
);

View file

@ -1,8 +1,7 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:24:1
|
LL | / const VALS_I8: (i8,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i8::MIN - 1,
| | ----------- attempt to subtract with overflow
@ -15,75 +14,68 @@ note: lint level defined here
LL | #![deny(const_err)]
| ^^^^^^^^^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:30:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:29:1
|
LL | / const VALS_I16: (i16,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i16::MIN - 1,
| | ------------ attempt to subtract with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:36:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:34:1
|
LL | / const VALS_I32: (i32,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i32::MIN - 1,
| | ------------ attempt to subtract with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:42:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:39:1
|
LL | / const VALS_I64: (i64,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i64::MIN - 1,
| | ------------ attempt to subtract with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:48:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:44:1
|
LL | / const VALS_U8: (u8,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | u8::MIN - 1,
| | ----------- attempt to subtract with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:54:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:49:1
|
LL | / const VALS_U16: (u16,) = (
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
LL | | u16::MIN - 1,
| | ------------ attempt to subtract with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:59:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:53:1
|
LL | / const VALS_U32: (u32,) = (
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
LL | | u32::MIN - 1,
| | ------------ attempt to subtract with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2.rs:64:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2.rs:57:1
|
LL | / const VALS_U64: (u64,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | u64::MIN - 1,
| | ------------ attempt to subtract with overflow

View file

@ -21,48 +21,40 @@ use std::fmt;
use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};
const VALS_I8: (i8,) =
//~^ ERROR this constant cannot be used
const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
(
i8::MAX + 1,
);
const VALS_I16: (i16,) =
//~^ ERROR this constant cannot be used
const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
(
i16::MAX + 1,
);
const VALS_I32: (i32,) =
//~^ ERROR this constant cannot be used
const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
(
i32::MAX + 1,
);
const VALS_I64: (i64,) =
//~^ ERROR this constant cannot be used
const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
(
i64::MAX + 1,
);
const VALS_U8: (u8,) =
//~^ ERROR this constant cannot be used
const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
(
u8::MAX + 1,
);
const VALS_U16: (u16,) = (
//~^ ERROR this constant cannot be used
const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
u16::MAX + 1,
);
const VALS_U32: (u32,) = (
//~^ ERROR this constant cannot be used
const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
u32::MAX + 1,
);
const VALS_U64: (u64,) =
//~^ ERROR this constant cannot be used
const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
(
u64::MAX + 1,
);

View file

@ -1,8 +1,7 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:24:1
|
LL | / const VALS_I8: (i8,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i8::MAX + 1,
| | ----------- attempt to add with overflow
@ -15,75 +14,68 @@ note: lint level defined here
LL | #![deny(const_err)]
| ^^^^^^^^^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:30:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:29:1
|
LL | / const VALS_I16: (i16,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i16::MAX + 1,
| | ------------ attempt to add with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:36:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:34:1
|
LL | / const VALS_I32: (i32,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i32::MAX + 1,
| | ------------ attempt to add with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:42:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:39:1
|
LL | / const VALS_I64: (i64,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i64::MAX + 1,
| | ------------ attempt to add with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:48:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:44:1
|
LL | / const VALS_U8: (u8,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | u8::MAX + 1,
| | ----------- attempt to add with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:54:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:49:1
|
LL | / const VALS_U16: (u16,) = (
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
LL | | u16::MAX + 1,
| | ------------ attempt to add with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:59:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:53:1
|
LL | / const VALS_U32: (u32,) = (
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
LL | | u32::MAX + 1,
| | ------------ attempt to add with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2b.rs:64:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2b.rs:57:1
|
LL | / const VALS_U64: (u64,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | u64::MAX + 1,
| | ------------ attempt to add with overflow

View file

@ -21,48 +21,40 @@ use std::fmt;
use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};
const VALS_I8: (i8,) =
//~^ ERROR this constant cannot be used
const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
(
i8::MIN * 2,
);
const VALS_I16: (i16,) =
//~^ ERROR this constant cannot be used
const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
(
i16::MIN * 2,
);
const VALS_I32: (i32,) =
//~^ ERROR this constant cannot be used
const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
(
i32::MIN * 2,
);
const VALS_I64: (i64,) =
//~^ ERROR this constant cannot be used
const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
(
i64::MIN * 2,
);
const VALS_U8: (u8,) =
//~^ ERROR this constant cannot be used
const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
(
u8::MAX * 2,
);
const VALS_U16: (u16,) = (
//~^ ERROR this constant cannot be used
const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
u16::MAX * 2,
);
const VALS_U32: (u32,) = (
//~^ ERROR this constant cannot be used
const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
u32::MAX * 2,
);
const VALS_U64: (u64,) =
//~^ ERROR this constant cannot be used
const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
(
u64::MAX * 2,
);

View file

@ -1,8 +1,7 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:24:1
|
LL | / const VALS_I8: (i8,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i8::MIN * 2,
| | ----------- attempt to multiply with overflow
@ -15,75 +14,68 @@ note: lint level defined here
LL | #![deny(const_err)]
| ^^^^^^^^^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:30:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:29:1
|
LL | / const VALS_I16: (i16,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i16::MIN * 2,
| | ------------ attempt to multiply with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:36:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:34:1
|
LL | / const VALS_I32: (i32,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i32::MIN * 2,
| | ------------ attempt to multiply with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:42:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:39:1
|
LL | / const VALS_I64: (i64,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | i64::MIN * 2,
| | ------------ attempt to multiply with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:48:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:44:1
|
LL | / const VALS_U8: (u8,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | u8::MAX * 2,
| | ----------- attempt to multiply with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:54:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:49:1
|
LL | / const VALS_U16: (u16,) = (
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
LL | | u16::MAX * 2,
| | ------------ attempt to multiply with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:59:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:53:1
|
LL | / const VALS_U32: (u32,) = (
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
LL | | u32::MAX * 2,
| | ------------ attempt to multiply with overflow
LL | | );
| |_______^
error: this constant cannot be used
--> $DIR/const-eval-overflow2c.rs:64:1
error: any use of this value will cause an error
--> $DIR/const-eval-overflow2c.rs:57:1
|
LL | / const VALS_U64: (u64,) =
LL | | //~^ ERROR this constant cannot be used
LL | / const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
LL | | (
LL | | u64::MAX * 2,
| | ------------ attempt to multiply with overflow

View file

@ -22,89 +22,89 @@ union Nonsense {
fn main() {
const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
}

View file

@ -1,4 +1,4 @@
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:24:5
|
LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
@ -6,7 +6,7 @@ LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:27:5
|
LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
@ -16,7 +16,7 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_
|
= note: #[deny(const_err)] on by default
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:30:5
|
LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
@ -24,7 +24,7 @@ LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:33:5
|
LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
@ -32,7 +32,7 @@ LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:36:5
|
LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
@ -40,13 +40,13 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:39:5
|
LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:42:5
|
LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
@ -54,7 +54,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:45:5
|
LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
@ -62,7 +62,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:48:5
|
LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
@ -70,7 +70,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:51:5
|
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
@ -78,13 +78,13 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:54:5
|
LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:57:5
|
LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
@ -92,7 +92,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:60:5
|
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
@ -100,7 +100,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:63:5
|
LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
@ -108,7 +108,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:66:5
|
LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
@ -116,7 +116,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:69:5
|
LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
@ -124,7 +124,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:72:5
|
LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
@ -132,7 +132,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:75:5
|
LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
@ -140,7 +140,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:78:5
|
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
@ -148,7 +148,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:81:5
|
LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
@ -156,7 +156,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:84:5
|
LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
@ -164,7 +164,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:87:5
|
LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
@ -172,7 +172,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:90:5
|
LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
@ -180,7 +180,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:93:5
|
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
@ -188,7 +188,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:96:5
|
LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
@ -196,7 +196,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:99:5
|
LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
@ -204,7 +204,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:102:5
|
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
@ -212,7 +212,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:105:5
|
LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
@ -220,7 +220,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
| |
| a raw memory access tried to access part of a pointer value as raw bytes
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:108:5
|
LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };

View file

@ -9,14 +9,13 @@
// except according to those terms.
#![feature(const_panic)]
#![crate_type = "lib"]
fn main() {}
pub const Z: () = panic!("cheese");
//~^ ERROR any use of this value will cause an error
const Z: () = panic!("cheese");
//~^ ERROR this constant cannot be used
pub const Y: () = unreachable!();
//~^ ERROR any use of this value will cause an error
const Y: () = unreachable!();
//~^ ERROR this constant cannot be used
const X: () = unimplemented!();
//~^ ERROR this constant cannot be used
pub const X: () = unimplemented!();
//~^ ERROR any use of this value will cause an error

View file

@ -1,31 +1,31 @@
error: this constant cannot be used
--> $DIR/const_panic.rs:15:1
error: any use of this value will cause an error
--> $DIR/const_panic.rs:14:1
|
LL | const Z: () = panic!("cheese");
| ^^^^^^^^^^^^^^----------------^
| |
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:15:15
LL | pub const Z: () = panic!("cheese");
| ^^^^^^^^^^^^^^^^^^----------------^
| |
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:14:19
|
= note: #[deny(const_err)] on by default
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: this constant cannot be used
--> $DIR/const_panic.rs:18:1
error: any use of this value will cause an error
--> $DIR/const_panic.rs:17:1
|
LL | const Y: () = unreachable!();
| ^^^^^^^^^^^^^^--------------^
| |
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:18:15
LL | pub const Y: () = unreachable!();
| ^^^^^^^^^^^^^^^^^^--------------^
| |
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:17:19
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: this constant cannot be used
--> $DIR/const_panic.rs:21:1
error: any use of this value will cause an error
--> $DIR/const_panic.rs:20:1
|
LL | const X: () = unimplemented!();
| ^^^^^^^^^^^^^^----------------^
| |
| the evaluated program panicked at 'not yet implemented', $DIR/const_panic.rs:21:15
LL | pub const X: () = unimplemented!();
| ^^^^^^^^^^^^^^^^^^----------------^
| |
| the evaluated program panicked at 'not yet implemented', $DIR/const_panic.rs:20:19
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

View file

@ -13,10 +13,10 @@
#![feature(const_panic)]
const Z: () = panic!("cheese");
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const Y: () = unreachable!();
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const X: () = unimplemented!();
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error

View file

@ -1,4 +1,4 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_panic_libcore.rs:15:1
|
LL | const Z: () = panic!("cheese");
@ -9,7 +9,7 @@ LL | const Z: () = panic!("cheese");
= note: #[deny(const_err)] on by default
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_panic_libcore.rs:18:1
|
LL | const Y: () = unreachable!();
@ -19,7 +19,7 @@ LL | const Y: () = unreachable!();
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_panic_libcore.rs:21:1
|
LL | const X: () = unimplemented!();

View file

@ -17,13 +17,13 @@
use core::panic::PanicInfo;
const Z: () = panic!("cheese");
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const Y: () = unreachable!();
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
const X: () = unimplemented!();
//~^ ERROR this constant cannot be used
//~^ ERROR any use of this value will cause an error
#[lang = "eh_personality"]
fn eh() {}

View file

@ -1,4 +1,4 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_panic_libcore_main.rs:19:1
|
LL | const Z: () = panic!("cheese");
@ -9,7 +9,7 @@ LL | const Z: () = panic!("cheese");
= note: #[deny(const_err)] on by default
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_panic_libcore_main.rs:22:1
|
LL | const Y: () = unreachable!();
@ -19,7 +19,7 @@ LL | const Y: () = unreachable!();
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_panic_libcore_main.rs:25:1
|
LL | const X: () = unimplemented!();

View file

@ -13,15 +13,15 @@
fn main() {}
// unconst and bad, will thus error in miri
const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR cannot be used
const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause
// unconst and fine
const X2: bool = 42 as *const i32 == 43 as *const i32;
// unconst and fine
const Y: usize = 42usize as *const i32 as usize + 1;
// unconst and bad, will thus error in miri
const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR cannot be used
const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause
// unconst and fine
const Z: i32 = unsafe { *(&1 as *const i32) };
// unconst and bad, will thus error in miri
const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR cannot be used
const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR cannot be used
const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR any use of this value will cause
const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR any use of this value will cause

View file

@ -1,33 +1,33 @@
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_raw_ptr_ops.rs:16:1
|
LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR cannot be used
LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause
| ^^^^^^^^^^^^^^^^------------------------------------^
| |
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
= note: #[deny(const_err)] on by default
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_raw_ptr_ops.rs:22:1
|
LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR cannot be used
LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause
| ^^^^^^^^^^^^^^^^^^-----------------------------^
| |
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_raw_ptr_ops.rs:26:1
|
LL | const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR cannot be used
LL | const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR any use of this value will cause
| ^^^^^^^^^^^^^^^^^^^^^^^^^-------------------^^^
| |
| a memory access tried to interpret some bytes as a pointer
error: this constant cannot be used
error: any use of this value will cause an error
--> $DIR/const_raw_ptr_ops.rs:27:1
|
LL | const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR cannot be used
LL | const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR any use of this value will cause
| ^^^^^^^^^^^^^^^^^^^^^^^^^-------------------^^^
| |
| a memory access tried to interpret some bytes as a pointer

View file

@ -1,4 +1,4 @@
error[E0080]: this static likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/double_check2.rs:25:1
|
LL | / static FOO: (&Foo, &Bar) = unsafe {( //~ undefined behavior

View file

@ -15,10 +15,10 @@ fn main() {
// The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
let _ = [(); {
//~^ WARNING Constant evaluating a complex constant, this might take some time
//~| ERROR could not evaluate repeat length
let mut n = 113383; // #20 in https://oeis.org/A006884
while n != 0 { //~ ERROR constant contains unimplemented expression type
n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
//~^ ERROR evaluation of constant value failed
}
n
}];

View file

@ -1,8 +1,9 @@
error[E0019]: constant contains unimplemented expression type
--> $DIR/infinite_loop.rs:20:9
--> $DIR/infinite_loop.rs:19:9
|
LL | / while n != 0 { //~ ERROR constant contains unimplemented expression type
LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
LL | | //~^ ERROR evaluation of constant value failed
LL | | }
| |_________^
@ -12,28 +13,18 @@ warning: Constant evaluating a complex constant, this might take some time
LL | let _ = [(); {
| __________________^
LL | | //~^ WARNING Constant evaluating a complex constant, this might take some time
LL | | //~| ERROR could not evaluate repeat length
LL | | let mut n = 113383; // #20 in https://oeis.org/A006884
LL | | while n != 0 { //~ ERROR constant contains unimplemented expression type
... |
LL | | n
LL | | }];
| |_____^
error[E0080]: could not evaluate repeat length
--> $DIR/infinite_loop.rs:16:18
error[E0080]: evaluation of constant value failed
--> $DIR/infinite_loop.rs:20:20
|
LL | let _ = [(); {
| __________________^
LL | | //~^ WARNING Constant evaluating a complex constant, this might take some time
LL | | //~| ERROR could not evaluate repeat length
LL | | let mut n = 113383; // #20 in https://oeis.org/A006884
LL | | while n != 0 { //~ ERROR constant contains unimplemented expression type
LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
| | ---------- duplicate interpreter state observed here, const evaluation will never terminate
LL | | }
LL | | n
LL | | }];
| |_____^
LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
| ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
error: aborting due to 2 previous errors

View file

@ -16,12 +16,10 @@ const fn foo(x: u32) -> u32 {
fn main() {
const X: u32 = 0-1;
//~^ WARN this constant cannot be used
//~^ WARN any use of this value will cause
const Y: u32 = foo(0-1);
//~^ WARN this constant cannot be used
//~^ WARN any use of this value will cause
println!("{} {}", X, Y);
//~^ ERROR erroneous constant used
//~| ERROR erroneous constant used
//~| ERROR E0080
//~| ERROR E0080
//~^ ERROR evaluation of constant expression failed
//~| ERROR evaluation of constant expression failed
}

View file

@ -1,4 +1,4 @@
warning: this constant cannot be used
warning: any use of this value will cause an error
--> $DIR/issue-43197.rs:18:5
|
LL | const X: u32 = 0-1;
@ -12,7 +12,7 @@ note: lint level defined here
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: this constant cannot be used
warning: any use of this value will cause an error
--> $DIR/issue-43197.rs:20:5
|
LL | const Y: u32 = foo(0-1);
@ -20,36 +20,18 @@ LL | const Y: u32 = foo(0-1);
| |
| attempt to subtract with overflow
error[E0080]: referenced constant has errors
--> $DIR/issue-43197.rs:22:26
|
LL | const Y: u32 = foo(0-1);
| --- attempt to subtract with overflow
LL | //~^ WARN this constant cannot be used
LL | println!("{} {}", X, Y);
| ^
error[E0080]: erroneous constant used
error[E0080]: evaluation of constant expression failed
--> $DIR/issue-43197.rs:22:26
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
error[E0080]: referenced constant has errors
--> $DIR/issue-43197.rs:22:23
|
LL | const X: u32 = 0-1;
| --- attempt to subtract with overflow
...
LL | println!("{} {}", X, Y);
| ^
error[E0080]: erroneous constant used
error[E0080]: evaluation of constant expression failed
--> $DIR/issue-43197.rs:22:23
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.

View file

@ -33,6 +33,5 @@ impl Foo for u16 {
fn main() {
println!("{}", <Bar<u16, u8> as Foo>::AMT);
//~^ ERROR erroneous constant used
//~| ERROR E0080
//~^ ERROR E0080
}

View file

@ -1,18 +1,9 @@
error[E0080]: referenced constant has errors
--> $DIR/issue-44578.rs:35:20
|
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
| ------------------------------------ index out of bounds: the len is 1 but the index is 1
...
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: erroneous constant used
error[E0080]: evaluation of constant expression failed
--> $DIR/issue-44578.rs:35:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View file

@ -19,12 +19,11 @@ trait Foo<T> {
struct A<T>(T);
impl<T: C> Foo<T> for A<T> {
const BAR: usize = [5, 6, 7][T::BOO];
const BAR: usize = [5, 6, 7][T::BOO]; //~ ERROR any use of this value will cause an error
}
fn foo<T: C>() -> &'static usize {
&<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
//~| ERROR E0080
&<A<T> as Foo<T>>::BAR //~ ERROR E0080
}
impl C for () {

View file

@ -1,16 +1,17 @@
error[E0080]: referenced constant has errors
--> $DIR/issue-50814-2.rs:26:5
error: any use of this value will cause an error
--> $DIR/issue-50814-2.rs:22:5
|
LL | const BAR: usize = [5, 6, 7][T::BOO];
| ----------------- index out of bounds: the len is 3 but the index is 42
...
LL | &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
| ^^^^^^^^^^^^^^^^^^^^^^
LL | const BAR: usize = [5, 6, 7][T::BOO]; //~ ERROR any use of this value will cause an error
| ^^^^^^^^^^^^^^^^^^^-----------------^
| |
| index out of bounds: the len is 3 but the index is 42
|
= note: #[deny(const_err)] on by default
error[E0080]: erroneous constant used
error[E0080]: evaluation of constant expression failed
--> $DIR/issue-50814-2.rs:26:5
|
LL | &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
LL | &<A<T> as Foo<T>>::BAR //~ ERROR E0080
| ^---------------------
| |
| referenced constant has errors

View file

@ -20,12 +20,11 @@ impl Unsigned for U8 {
struct Sum<A,B>(A,B);
impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A,B> {
const MAX: u8 = A::MAX + B::MAX;
const MAX: u8 = A::MAX + B::MAX; //~ ERROR any use of this value will cause an error
}
fn foo<T>(_: T) -> &'static u8 {
&Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
//~| ERROR E0080
&Sum::<U8,U8>::MAX //~ ERROR E0080
}
fn main() {

View file

@ -1,16 +1,17 @@
error[E0080]: referenced constant has errors
--> $DIR/issue-50814.rs:27:5
error: any use of this value will cause an error
--> $DIR/issue-50814.rs:23:5
|
LL | const MAX: u8 = A::MAX + B::MAX;
| --------------- attempt to add with overflow
...
LL | &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
| ^^^^^^^^^^^^^^^^^^
LL | const MAX: u8 = A::MAX + B::MAX; //~ ERROR any use of this value will cause an error
| ^^^^^^^^^^^^^^^^---------------^
| |
| attempt to add with overflow
|
= note: #[deny(const_err)] on by default
error[E0080]: erroneous constant used
error[E0080]: evaluation of constant expression failed
--> $DIR/issue-50814.rs:27:5
|
LL | &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
LL | &Sum::<U8,U8>::MAX //~ ERROR E0080
| ^-----------------
| |
| referenced constant has errors

View file

@ -10,4 +10,5 @@
fn main() {
[(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
//~^ ERROR it is undefined behavior to use this value
}

View file

@ -4,6 +4,15 @@ error[E0019]: constant contains unimplemented expression type
LL | [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
| ^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0080]: it is undefined behavior to use this value
--> $DIR/issue-52442.rs:12:11
|
LL | [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
For more information about this error, try `rustc --explain E0019`.
error: aborting due to 2 previous errors
Some errors occurred: E0019, E0080.
For more information about an error, try `rustc --explain E0019`.

View file

@ -13,11 +13,10 @@
fn main() {
let _ = [(); {
//~^ WARNING Constant evaluating a complex constant, this might take some time
//~| ERROR could not evaluate repeat length
let mut x = &0;
let mut n = 0;
while n < 5 { //~ ERROR constant contains unimplemented expression type
n = (n + 1) % 5;
n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
x = &0; // Materialize a new AllocId
}
0

View file

@ -1,8 +1,8 @@
error[E0019]: constant contains unimplemented expression type
--> $DIR/issue-52475.rs:19:9
--> $DIR/issue-52475.rs:18:9
|
LL | / while n < 5 { //~ ERROR constant contains unimplemented expression type
LL | | n = (n + 1) % 5;
LL | | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
LL | | x = &0; // Materialize a new AllocId
LL | | }
| |_________^
@ -13,28 +13,18 @@ warning: Constant evaluating a complex constant, this might take some time
LL | let _ = [(); {
| __________________^
LL | | //~^ WARNING Constant evaluating a complex constant, this might take some time
LL | | //~| ERROR could not evaluate repeat length
LL | | let mut x = &0;
LL | | let mut n = 0;
... |
LL | | 0
LL | | }];
| |_____^
error[E0080]: could not evaluate repeat length
--> $DIR/issue-52475.rs:14:18
error[E0080]: evaluation of constant value failed
--> $DIR/issue-52475.rs:19:17
|
LL | let _ = [(); {
| __________________^
LL | | //~^ WARNING Constant evaluating a complex constant, this might take some time
LL | | //~| ERROR could not evaluate repeat length
LL | | let mut x = &0;
... |
LL | | n = (n + 1) % 5;
| | ----------- duplicate interpreter state observed here, const evaluation will never terminate
... |
LL | | 0
LL | | }];
| |_____^
LL | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
| ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
error: aborting due to 2 previous errors

View file

@ -12,10 +12,11 @@ fn main() {
// Make sure match uses the usual pointer comparison code path -- i.e., it should complain
// that pointer comparison is disallowed, not that parts of a pointer are accessed as raw
// bytes.
let _: [u8; 0] = [4; { //~ ERROR could not evaluate repeat length
let _: [u8; 0] = [4; {
match &1 as *const i32 as usize { //~ ERROR casting pointers to integers in constants
0 => 42, //~ ERROR constant contains unimplemented expression type
//~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed
//~| ERROR evaluation of constant value failed
n => n,
}
}];

View file

@ -12,19 +12,11 @@ error[E0019]: constant contains unimplemented expression type
LL | 0 => 42, //~ ERROR constant contains unimplemented expression type
| ^
error[E0080]: could not evaluate repeat length
--> $DIR/match-test-ptr-null.rs:15:26
error[E0080]: evaluation of constant value failed
--> $DIR/match-test-ptr-null.rs:17:13
|
LL | let _: [u8; 0] = [4; { //~ ERROR could not evaluate repeat length
| __________________________^
LL | | match &1 as *const i32 as usize { //~ ERROR casting pointers to integers in constants
LL | | 0 => 42, //~ ERROR constant contains unimplemented expression type
| | - "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
LL | | //~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed
LL | | n => n,
LL | | }
LL | | }];
| |_____^
LL | 0 => 42, //~ ERROR constant contains unimplemented expression type
| ^ "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
error: aborting due to 3 previous errors

View file

@ -10,7 +10,7 @@
#![feature(const_fn, const_fn_union)]
#![deny(const_err)]
#![allow(const_err)]
union Bar {
a: &'static u8,

View file

@ -0,0 +1,14 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:31:27
|
LL | let x: &'static u8 = &(bar() + 1);
| ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error: aborting due to previous error
For more information about this error, try `rustc --explain E0716`.

View file

@ -0,0 +1,34 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(const_fn, const_fn_union)]
#![deny(const_err)]
union Bar {
a: &'static u8,
b: usize,
}
const fn bar() -> u8 {
unsafe {
// This will error as long as this test is run on a system whose
// pointers need more than 8 bits.
Bar { a: &42 }.b as u8
}
}
fn main() {
// This will compile, but then hard-abort at runtime.
// FIXME(oli-obk): this should instead panic (not hard-abort) at runtime.
let x: &'static u8 = &(bar() + 1);
let y = *x;
unreachable!();
}

View file

@ -0,0 +1,14 @@
error[E0597]: borrowed value does not live long enough
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:31:27
|
LL | let x: &'static u8 = &(bar() + 1);
| ^^^^^^^^^^^ temporary value does not live long enough
...
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.

View file

@ -46,3 +46,15 @@ warning: this expression will panic at runtime
LL | let _x = 1/(false as u32);
| ^^^^^^^^^^^^^^^^ attempt to divide by zero
warning: reaching this expression at runtime will panic or abort
--> $DIR/promoted_errors.rs:24:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^ attempt to divide by zero
warning: reaching this expression at runtime will panic or abort
--> $DIR/promoted_errors.rs:19:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^ attempt to divide by zero

View file

@ -14,8 +14,6 @@
#![crate_type = "lib"]
pub const Z: u32 = 0 - 1;
//~^ WARN this constant cannot be used
//~^ WARN any use of this value will cause an error
pub type Foo = [i32; 0 - 1];
//~^ WARN attempt to subtract with overflow
//~| WARN this array length cannot be used

View file

@ -1,4 +1,4 @@
warning: this constant cannot be used
warning: any use of this value will cause an error
--> $DIR/pub_const_err.rs:16:1
|
LL | pub const Z: u32 = 0 - 1;
@ -12,15 +12,3 @@ note: lint level defined here
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: attempt to subtract with overflow
--> $DIR/pub_const_err.rs:19:22
|
LL | pub type Foo = [i32; 0 - 1];
| ^^^^^
warning: this array length cannot be used
--> $DIR/pub_const_err.rs:19:22
|
LL | pub type Foo = [i32; 0 - 1];
| ^^^^^ attempt to subtract with overflow

View file

@ -12,10 +12,8 @@
#![warn(const_err)]
pub const Z: u32 = 0 - 1;
//~^ WARN this constant cannot be used
//~^ WARN any use of this value will cause an error
pub type Foo = [i32; 0 - 1];
//~^ WARN attempt to subtract with overflow
//~| WARN this array length cannot be used
fn main() {}

View file

@ -1,4 +1,4 @@
warning: this constant cannot be used
warning: any use of this value will cause an error
--> $DIR/pub_const_err_bin.rs:14:1
|
LL | pub const Z: u32 = 0 - 1;
@ -12,15 +12,3 @@ note: lint level defined here
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: attempt to subtract with overflow
--> $DIR/pub_const_err_bin.rs:17:22
|
LL | pub type Foo = [i32; 0 - 1];
| ^^^^^
warning: this array length cannot be used
--> $DIR/pub_const_err_bin.rs:17:22
|
LL | pub type Foo = [i32; 0 - 1];
| ^^^^^ attempt to subtract with overflow

View file

@ -14,7 +14,7 @@ fn main() {
let n: Int = 40;
match n {
0..=10 => {},
10..=BAR => {}, //~ ERROR lower range bound must be less than or equal to upper
10..=BAR => {}, //~ ERROR could not evaluate constant pattern
_ => {},
}
}
@ -30,4 +30,4 @@ type Int = u64;
#[cfg(target_pointer_width="32")]
type Int = u32;
const BAR: Int = unsafe { Foo { r: &42 }.f };
const BAR: Int = unsafe { Foo { r: &42 }.f }; //~ ERROR it is undefined behavior to use this value

View file

@ -1,9 +1,17 @@
error[E0030]: lower range bound must be less than or equal to upper
--> $DIR/ref_to_int_match.rs:17:9
error[E0080]: it is undefined behavior to use this value
--> $DIR/ref_to_int_match.rs:33:1
|
LL | 10..=BAR => {}, //~ ERROR lower range bound must be less than or equal to upper
| ^^ lower bound larger than upper bound
LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; //~ ERROR it is undefined behavior to use this value
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error: aborting due to previous error
error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:17:14
|
LL | 10..=BAR => {}, //~ ERROR could not evaluate constant pattern
| ^^^
For more information about this error, try `rustc --explain E0030`.
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.

View file

@ -1,4 +1,4 @@
error[E0080]: could not evaluate enum discriminant
error[E0080]: evaluation of constant value failed
--> $DIR/shift_overflow.rs:13:9
|
LL | X = 1 << ((u32::max_value() as u64) + 1), //~ ERROR E0080

View file

@ -13,6 +13,6 @@
use std::mem;
static FOO: bool = unsafe { mem::transmute(3u8) };
//~^ ERROR this static likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
fn main() {}

View file

@ -1,4 +1,4 @@
error[E0080]: this static likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/transmute-const.rs:15:1
|
LL | static FOO: bool = unsafe { mem::transmute(3u8) };

View file

@ -20,7 +20,7 @@ union TransmuteEnum {
// A pointer is guaranteed non-null
const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR is undefined behavior
// Invalid enum discriminant
#[repr(usize)]
@ -33,7 +33,7 @@ union TransmuteEnum2 {
b: Enum2,
}
const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR is undefined behavior
// Invalid enum field content (mostly to test printing of apths for enum tuple
// variants and tuples).
@ -43,7 +43,7 @@ union TransmuteChar {
}
// Need to create something which does not clash with enum layout optimizations.
const BAD_ENUM_CHAR : Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR is undefined behavior
fn main() {
}

View file

@ -1,4 +1,4 @@
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:22:1
|
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
@ -6,7 +6,7 @@ LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:35:1
|
LL | const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
@ -14,7 +14,7 @@ LL | const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: this constant likely exhibits undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:45:1
|
LL | const BAD_ENUM_CHAR : Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));

View file

@ -15,11 +15,11 @@ use std::ptr::NonNull;
use std::num::{NonZeroU8, NonZeroUsize};
const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
//~^ ERROR this constant likely exhibits undefined behavior
//~^ ERROR it is undefined behavior to use this value
fn main() {}

Some files were not shown because too many files have changed in this diff Show more