Report const eval error inside the query
This commit is contained in:
parent
3476ac0bee
commit
7fdf06cdde
135 changed files with 1472 additions and 1090 deletions
|
@ -530,6 +530,7 @@ define_dep_nodes!( <'tcx>
|
||||||
[] UsedTraitImports(DefId),
|
[] UsedTraitImports(DefId),
|
||||||
[] HasTypeckTables(DefId),
|
[] HasTypeckTables(DefId),
|
||||||
[] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
|
[] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
|
||||||
|
[] ConstEvalRaw { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
|
||||||
[] CheckMatch(DefId),
|
[] CheckMatch(DefId),
|
||||||
[] SymbolName(DefId),
|
[] SymbolName(DefId),
|
||||||
[] InstanceSymbolName { instance: Instance<'tcx> },
|
[] InstanceSymbolName { instance: Instance<'tcx> },
|
||||||
|
|
|
@ -74,6 +74,7 @@ pub enum Def {
|
||||||
SelfCtor(DefId /* impl */), // DefId refers to the impl
|
SelfCtor(DefId /* impl */), // DefId refers to the impl
|
||||||
Method(DefId),
|
Method(DefId),
|
||||||
AssociatedConst(DefId),
|
AssociatedConst(DefId),
|
||||||
|
Closure(hir::BodyId),
|
||||||
|
|
||||||
Local(ast::NodeId),
|
Local(ast::NodeId),
|
||||||
Upvar(ast::NodeId, // node id of closed over local
|
Upvar(ast::NodeId, // node id of closed over local
|
||||||
|
@ -281,6 +282,7 @@ impl Def {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Def::Closure(_) |
|
||||||
Def::Local(..) |
|
Def::Local(..) |
|
||||||
Def::Upvar(..) |
|
Def::Upvar(..) |
|
||||||
Def::Label(..) |
|
Def::Label(..) |
|
||||||
|
@ -319,6 +321,7 @@ impl Def {
|
||||||
Def::Trait(..) => "trait",
|
Def::Trait(..) => "trait",
|
||||||
Def::ForeignTy(..) => "foreign type",
|
Def::ForeignTy(..) => "foreign type",
|
||||||
Def::Method(..) => "method",
|
Def::Method(..) => "method",
|
||||||
|
Def::Closure(_) => "closure",
|
||||||
Def::Const(..) => "constant",
|
Def::Const(..) => "constant",
|
||||||
Def::AssociatedConst(..) => "associated constant",
|
Def::AssociatedConst(..) => "associated constant",
|
||||||
Def::TyParam(..) => "type parameter",
|
Def::TyParam(..) => "type parameter",
|
||||||
|
|
|
@ -340,9 +340,14 @@ impl<'hir> Map<'hir> {
|
||||||
let def_id = self.local_def_id(variant.node.data.id());
|
let def_id = self.local_def_id(variant.node.data.id());
|
||||||
Some(Def::Variant(def_id))
|
Some(Def::Variant(def_id))
|
||||||
}
|
}
|
||||||
|
Node::Expr(expr) => {
|
||||||
|
match expr.node {
|
||||||
|
ExprKind::Closure(_, _, body_id, _, _) => Some(Def::Closure(body_id)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
Node::Field(_) |
|
Node::Field(_) |
|
||||||
Node::AnonConst(_) |
|
Node::AnonConst(_) |
|
||||||
Node::Expr(_) |
|
|
||||||
Node::Stmt(_) |
|
Node::Stmt(_) |
|
||||||
Node::Ty(_) |
|
Node::Ty(_) |
|
||||||
Node::TraitRef(_) |
|
Node::TraitRef(_) |
|
||||||
|
|
|
@ -1044,6 +1044,7 @@ impl_stable_hash_for!(enum hir::def::Def {
|
||||||
SelfCtor(impl_def_id),
|
SelfCtor(impl_def_id),
|
||||||
VariantCtor(def_id, ctor_kind),
|
VariantCtor(def_id, ctor_kind),
|
||||||
Method(def_id),
|
Method(def_id),
|
||||||
|
Closure(body_id),
|
||||||
AssociatedConst(def_id),
|
AssociatedConst(def_id),
|
||||||
Local(def_id),
|
Local(def_id),
|
||||||
Upvar(def_id, index, expr_id),
|
Upvar(def_id, index, expr_id),
|
||||||
|
|
|
@ -483,10 +483,9 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
|
||||||
val
|
val
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ::mir::interpret::ConstEvalErr<'tcx> {
|
impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
|
||||||
span,
|
Reported,
|
||||||
stacktrace,
|
TooGeneric
|
||||||
error
|
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
|
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
|
||||||
|
@ -503,8 +502,6 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
|
||||||
predicates
|
predicates
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ::mir::interpret::EvalError<'tcx> { kind });
|
|
||||||
|
|
||||||
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
|
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
|
||||||
for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
fn hash_stable<W: StableHasherResult>(&self,
|
||||||
|
@ -543,7 +540,6 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||||
UnimplementedTraitSelection |
|
UnimplementedTraitSelection |
|
||||||
TypeckError |
|
TypeckError |
|
||||||
TooGeneric |
|
TooGeneric |
|
||||||
CheckMatchError |
|
|
||||||
DerefFunctionPointer |
|
DerefFunctionPointer |
|
||||||
ExecuteMemory |
|
ExecuteMemory |
|
||||||
OverflowNeg |
|
OverflowNeg |
|
||||||
|
@ -551,6 +547,7 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||||
DivisionByZero |
|
DivisionByZero |
|
||||||
GeneratorResumedAfterReturn |
|
GeneratorResumedAfterReturn |
|
||||||
GeneratorResumedAfterPanic |
|
GeneratorResumedAfterPanic |
|
||||||
|
ReferencedConstant |
|
||||||
InfiniteLoop => {}
|
InfiniteLoop => {}
|
||||||
ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
|
ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
|
||||||
InvalidDiscriminant(val) => val.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);
|
line.hash_stable(hcx, hasher);
|
||||||
col.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),
|
MachineError(ref err) => err.hash_stable(hcx, hasher),
|
||||||
FunctionAbiMismatch(a, b) => {
|
FunctionAbiMismatch(a, b) => {
|
||||||
a.hash_stable(hcx, hasher);
|
a.hash_stable(hcx, hasher);
|
||||||
|
|
|
@ -13,7 +13,6 @@ use std::{fmt, env};
|
||||||
use mir;
|
use mir;
|
||||||
use ty::{Ty, layout};
|
use ty::{Ty, layout};
|
||||||
use ty::layout::{Size, Align};
|
use ty::layout::{Size, Align};
|
||||||
use rustc_data_structures::sync::Lrc;
|
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -30,7 +29,26 @@ use syntax_pos::Span;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>;
|
#[derive(Debug, 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)]
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct ConstEvalErr<'tcx> {
|
pub struct ConstEvalErr<'tcx> {
|
||||||
|
@ -50,7 +68,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||||
pub fn struct_error(&self,
|
pub fn struct_error(&self,
|
||||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||||
message: &str)
|
message: &str)
|
||||||
-> Option<DiagnosticBuilder<'tcx>>
|
-> Result<DiagnosticBuilder<'tcx>, ErrorHandled>
|
||||||
{
|
{
|
||||||
self.struct_generic(tcx, message, None)
|
self.struct_generic(tcx, message, None)
|
||||||
}
|
}
|
||||||
|
@ -58,10 +76,14 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||||
pub fn report_as_error(&self,
|
pub fn report_as_error(&self,
|
||||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||||
message: &str
|
message: &str
|
||||||
) {
|
) -> ErrorHandled {
|
||||||
let err = self.struct_error(tcx, message);
|
let err = self.struct_error(tcx, message);
|
||||||
if let Some(mut err) = err {
|
match err {
|
||||||
err.emit();
|
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>,
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||||
message: &str,
|
message: &str,
|
||||||
lint_root: ast::NodeId,
|
lint_root: ast::NodeId,
|
||||||
) {
|
) -> ErrorHandled {
|
||||||
let lint = self.struct_generic(
|
let lint = self.struct_generic(
|
||||||
tcx,
|
tcx,
|
||||||
message,
|
message,
|
||||||
Some(lint_root),
|
Some(lint_root),
|
||||||
);
|
);
|
||||||
if let Some(mut lint) = lint {
|
match lint {
|
||||||
lint.emit();
|
Ok(mut lint) => {
|
||||||
|
lint.emit();
|
||||||
|
ErrorHandled::Reported
|
||||||
|
},
|
||||||
|
Err(err) => err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,15 +111,11 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||||
message: &str,
|
message: &str,
|
||||||
lint_root: Option<ast::NodeId>,
|
lint_root: Option<ast::NodeId>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
|
||||||
match self.error.kind {
|
match self.error.kind {
|
||||||
::mir::interpret::EvalErrorKind::TypeckError |
|
EvalErrorKind::TooGeneric => return Err(ErrorHandled::TooGeneric),
|
||||||
::mir::interpret::EvalErrorKind::TooGeneric |
|
EvalErrorKind::TypeckError |
|
||||||
::mir::interpret::EvalErrorKind::CheckMatchError |
|
EvalErrorKind::Layout(_) => return Err(ErrorHandled::Reported),
|
||||||
::mir::interpret::EvalErrorKind::Layout(_) => return None,
|
|
||||||
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
|
|
||||||
inner.struct_generic(tcx, "referenced constant has errors", lint_root)?.emit();
|
|
||||||
},
|
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
trace!("reporting const eval failure at {:?}", self.span);
|
trace!("reporting const eval failure at {:?}", self.span);
|
||||||
|
@ -117,7 +139,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||||
for FrameInfo { span, location, .. } in &self.stacktrace {
|
for FrameInfo { span, location, .. } in &self.stacktrace {
|
||||||
err.span_label(*span, format!("inside call to `{}`", location));
|
err.span_label(*span, format!("inside call to `{}`", location));
|
||||||
}
|
}
|
||||||
Some(err)
|
Ok(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,10 +301,9 @@ pub enum EvalErrorKind<'tcx, O> {
|
||||||
TypeckError,
|
TypeckError,
|
||||||
/// Resolution can fail if we are in a too generic context
|
/// Resolution can fail if we are in a too generic context
|
||||||
TooGeneric,
|
TooGeneric,
|
||||||
CheckMatchError,
|
|
||||||
/// Cannot compute this constant because it depends on another one
|
/// Cannot compute this constant because it depends on another one
|
||||||
/// which already produced an error
|
/// which already produced an error
|
||||||
ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
|
ReferencedConstant,
|
||||||
GeneratorResumedAfterReturn,
|
GeneratorResumedAfterReturn,
|
||||||
GeneratorResumedAfterPanic,
|
GeneratorResumedAfterPanic,
|
||||||
InfiniteLoop,
|
InfiniteLoop,
|
||||||
|
@ -407,9 +428,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
|
||||||
"encountered constants with type errors, stopping evaluation",
|
"encountered constants with type errors, stopping evaluation",
|
||||||
TooGeneric =>
|
TooGeneric =>
|
||||||
"encountered overly generic constant",
|
"encountered overly generic constant",
|
||||||
CheckMatchError =>
|
ReferencedConstant =>
|
||||||
"match checking failed",
|
|
||||||
ReferencedConstant(_) =>
|
|
||||||
"referenced constant has errors",
|
"referenced constant has errors",
|
||||||
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
|
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
|
||||||
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
|
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
|
||||||
|
|
|
@ -20,7 +20,7 @@ mod value;
|
||||||
|
|
||||||
pub use self::error::{
|
pub use self::error::{
|
||||||
EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
|
EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
|
||||||
FrameInfo, ConstEvalResult,
|
FrameInfo, ConstEvalResult, ErrorHandled,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::value::{Scalar, ConstValue};
|
pub use self::value::{Scalar, ConstValue};
|
||||||
|
|
|
@ -880,18 +880,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.tcx.report_object_safety_error(span, did, violations)
|
self.tcx.report_object_safety_error(span, did, violations)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstEvalFailure(ref err) => {
|
// already reported in the query
|
||||||
match err.struct_error(
|
ConstEvalFailure => {
|
||||||
self.tcx.at(span),
|
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
|
||||||
"could not evaluate constant expression",
|
return;
|
||||||
) {
|
|
||||||
Some(err) => err,
|
|
||||||
None => {
|
|
||||||
self.tcx.sess.delay_span_bug(span,
|
|
||||||
&format!("constant in type had an ignored error: {:?}", err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Overflow => {
|
Overflow => {
|
||||||
|
|
|
@ -16,8 +16,6 @@ use rustc_data_structures::obligation_forest::{Error, ForestObligation, Obligati
|
||||||
use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
|
use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use mir::interpret::ConstEvalErr;
|
|
||||||
use mir::interpret::EvalErrorKind;
|
|
||||||
|
|
||||||
use super::CodeAmbiguity;
|
use super::CodeAmbiguity;
|
||||||
use super::CodeProjectionError;
|
use super::CodeProjectionError;
|
||||||
|
@ -491,17 +489,11 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
||||||
match self.selcx.tcx().at(obligation.cause.span)
|
match self.selcx.tcx().at(obligation.cause.span)
|
||||||
.const_eval(param_env.and(cid)) {
|
.const_eval(param_env.and(cid)) {
|
||||||
Ok(_) => ProcessResult::Changed(vec![]),
|
Ok(_) => ProcessResult::Changed(vec![]),
|
||||||
Err(err) => ProcessResult::Error(
|
Err(_) => ProcessResult::Error(
|
||||||
CodeSelectionError(ConstEvalFailure(err)))
|
CodeSelectionError(ConstEvalFailure))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ProcessResult::Error(
|
ProcessResult::Error(CodeSelectionError(ConstEvalFailure))
|
||||||
CodeSelectionError(ConstEvalFailure(ConstEvalErr {
|
|
||||||
span: obligation.cause.span,
|
|
||||||
error: EvalErrorKind::TooGeneric.into(),
|
|
||||||
stacktrace: vec![],
|
|
||||||
}.into()))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -23,7 +23,6 @@ use hir::def_id::DefId;
|
||||||
use infer::SuppressRegionErrors;
|
use infer::SuppressRegionErrors;
|
||||||
use infer::outlives::env::OutlivesEnvironment;
|
use infer::outlives::env::OutlivesEnvironment;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use mir::interpret::ConstEvalErr;
|
|
||||||
use ty::subst::Substs;
|
use ty::subst::Substs;
|
||||||
use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
|
use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
|
||||||
use ty::error::{ExpectedFound, TypeError};
|
use ty::error::{ExpectedFound, TypeError};
|
||||||
|
@ -438,7 +437,7 @@ pub enum SelectionError<'tcx> {
|
||||||
ty::PolyTraitRef<'tcx>,
|
ty::PolyTraitRef<'tcx>,
|
||||||
ty::error::TypeError<'tcx>),
|
ty::error::TypeError<'tcx>),
|
||||||
TraitNotObjectSafe(DefId),
|
TraitNotObjectSafe(DefId),
|
||||||
ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
|
ConstEvalFailure,
|
||||||
Overflow,
|
Overflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,9 +172,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
|
super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
|
||||||
super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
|
super::ConstEvalFailure(ref err) => Some(super::ConstEvalFailure),
|
||||||
err.into(),
|
|
||||||
)),
|
|
||||||
super::Overflow => Some(super::Overflow),
|
super::Overflow => Some(super::Overflow),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangIte
|
||||||
use middle::privacy::AccessLevels;
|
use middle::privacy::AccessLevels;
|
||||||
use middle::resolve_lifetime::ObjectLifetimeDefault;
|
use middle::resolve_lifetime::ObjectLifetimeDefault;
|
||||||
use mir::Mir;
|
use mir::Mir;
|
||||||
use mir::interpret::GlobalId;
|
use mir::interpret::{GlobalId, ErrorHandled};
|
||||||
use mir::GeneratorLayout;
|
use mir::GeneratorLayout;
|
||||||
use session::CrateDisambiguator;
|
use session::CrateDisambiguator;
|
||||||
use traits::{self, Reveal};
|
use traits::{self, Reveal};
|
||||||
|
@ -2191,11 +2191,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(ErrorHandled::Reported) => {
|
||||||
err.report_as_error(
|
|
||||||
tcx.at(tcx.def_span(expr_did)),
|
|
||||||
"could not evaluate enum discriminant",
|
|
||||||
);
|
|
||||||
if !expr_did.is_local() {
|
if !expr_did.is_local() {
|
||||||
span_bug!(tcx.def_span(expr_did),
|
span_bug!(tcx.def_span(expr_did),
|
||||||
"variant discriminant evaluation succeeded \
|
"variant discriminant evaluation succeeded \
|
||||||
|
@ -2203,6 +2199,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||||
|
tcx.def_span(expr_did),
|
||||||
|
"enum discriminant depends on generic arguments",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,6 +296,30 @@ impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'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>>)
|
fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
|
||||||
-> Cow<'static, str>
|
-> Cow<'static, str>
|
||||||
{
|
{
|
||||||
|
|
|
@ -301,6 +301,14 @@ define_queries! { <'tcx>
|
||||||
},
|
},
|
||||||
|
|
||||||
Other {
|
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
|
/// Results of evaluating const items or constants embedded in
|
||||||
/// other items (such as enum variant explicit discriminants).
|
/// other items (such as enum variant explicit discriminants).
|
||||||
[] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
|
[] 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<'tcx> {
|
||||||
DepConstructor::ConstEval { param_env }
|
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> {
|
fn mir_keys<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
||||||
DepConstructor::MirKeys
|
DepConstructor::MirKeys
|
||||||
|
|
|
@ -1063,6 +1063,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
|
||||||
DepKind::NeedsDrop |
|
DepKind::NeedsDrop |
|
||||||
DepKind::Layout |
|
DepKind::Layout |
|
||||||
DepKind::ConstEval |
|
DepKind::ConstEval |
|
||||||
|
DepKind::ConstEvalRaw |
|
||||||
DepKind::InstanceSymbolName |
|
DepKind::InstanceSymbolName |
|
||||||
DepKind::MirShim |
|
DepKind::MirShim |
|
||||||
DepKind::BorrowCheckKrate |
|
DepKind::BorrowCheckKrate |
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//! hand, though we've recently added some macros (e.g.,
|
//! hand, though we've recently added some macros (e.g.,
|
||||||
//! `BraceStructLiftImpl!`) to help with the tedium.
|
//! `BraceStructLiftImpl!`) to help with the tedium.
|
||||||
|
|
||||||
use mir::interpret::{ConstValue, ConstEvalErr};
|
use mir::interpret::ConstValue;
|
||||||
use ty::{self, Lift, Ty, TyCtxt};
|
use ty::{self, Lift, Ty, TyCtxt};
|
||||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
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> {
|
impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
|
||||||
type Lifted = ty::InstanceDef<'tcx>;
|
type Lifted = ty::InstanceDef<'tcx>;
|
||||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use llvm;
|
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_mir::const_eval::const_field;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
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::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size};
|
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(
|
pub fn codegen_static_initializer(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
def_id: DefId,
|
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 instance = ty::Instance::mono(cx.tcx, def_id);
|
||||||
let cid = GlobalId {
|
let cid = GlobalId {
|
||||||
instance,
|
instance,
|
||||||
|
@ -145,7 +144,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'a, 'll, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
constant: &'tcx ty::Const<'tcx>,
|
constant: &'tcx ty::Const<'tcx>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
|
||||||
match constant.val {
|
match constant.val {
|
||||||
ConstValue::Unevaluated(def_id, ref substs) => {
|
ConstValue::Unevaluated(def_id, ref substs) => {
|
||||||
let tcx = bx.tcx();
|
let tcx = bx.tcx();
|
||||||
|
@ -165,7 +164,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'a, 'll, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
constant: &mir::Constant<'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);
|
let c = self.monomorphize(&constant.literal);
|
||||||
self.fully_evaluate(bx, c)
|
self.fully_evaluate(bx, c)
|
||||||
}
|
}
|
||||||
|
@ -176,7 +175,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
bx: &Builder<'a, 'll, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
|
constant: Result<&'tcx ty::Const<'tcx>, ErrorHandled>,
|
||||||
) -> (&'ll Value, Ty<'tcx>) {
|
) -> (&'ll Value, Ty<'tcx>) {
|
||||||
constant
|
constant
|
||||||
.and_then(|c| {
|
.and_then(|c| {
|
||||||
|
@ -185,7 +184,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
|
ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
|
||||||
ref other => bug!("invalid simd shuffle type: {}", other),
|
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(
|
let field = const_field(
|
||||||
bx.tcx(),
|
bx.tcx(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
|
@ -211,9 +210,9 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
let llval = C_struct(bx.cx, &values?, false);
|
let llval = C_struct(bx.cx, &values?, false);
|
||||||
Ok((llval, c.ty))
|
Ok((llval, c.ty))
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|_| {
|
||||||
e.report_as_error(
|
bx.tcx().sess.span_err(
|
||||||
bx.tcx().at(span),
|
span,
|
||||||
"could not evaluate shuffle_indices at compile time",
|
"could not evaluate shuffle_indices at compile time",
|
||||||
);
|
);
|
||||||
// We've errored, so we don't have to produce working code.
|
// We've errored, so we don't have to produce working code.
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use rustc::mir::interpret::{ConstValue, ConstEvalErr};
|
use rustc::mir::interpret::{ConstValue, ErrorHandled};
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
|
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
|
||||||
use base;
|
use base;
|
||||||
use common::{CodegenCx, C_undef, C_usize};
|
use common::{CodegenCx, C_undef, C_usize};
|
||||||
|
@ -79,7 +80,7 @@ impl OperandRef<'ll, 'tcx> {
|
||||||
|
|
||||||
pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
|
pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
|
||||||
val: &'tcx ty::Const<'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);
|
let layout = bx.cx.layout_of(val.ty);
|
||||||
|
|
||||||
if layout.is_zst() {
|
if layout.is_zst() {
|
||||||
|
@ -424,10 +425,13 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
self.eval_mir_constant(bx, constant)
|
self.eval_mir_constant(bx, constant)
|
||||||
.and_then(|c| OperandRef::from_const(bx, c))
|
.and_then(|c| OperandRef::from_const(bx, c))
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
err.report_as_error(
|
match err {
|
||||||
bx.tcx().at(constant.span),
|
// errored or at least linted
|
||||||
"could not evaluate constant operand",
|
ErrorHandled::Reported => {},
|
||||||
);
|
ErrorHandled::TooGeneric => {
|
||||||
|
bug!("codgen encountered polymorphic constant")
|
||||||
|
},
|
||||||
|
}
|
||||||
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
|
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
|
||||||
// the above error (or silence it under some conditions) will not cause UB
|
// the above error (or silence it under some conditions) will not cause UB
|
||||||
let fnname = bx.cx.get_intrinsic(&("llvm.trap"));
|
let fnname = bx.cx.get_intrinsic(&("llvm.trap"));
|
||||||
|
|
|
@ -1590,7 +1590,7 @@ fn validate_const<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 def_id = cx.tcx.hir.body_owner_def_id(body_id);
|
||||||
let is_static = cx.tcx.is_static(def_id).is_some();
|
let is_static = cx.tcx.is_static(def_id).is_some();
|
||||||
let param_env = if is_static {
|
let param_env = if is_static {
|
||||||
|
@ -1603,27 +1603,15 @@ fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) {
|
||||||
instance: ty::Instance::mono(cx.tcx, def_id),
|
instance: ty::Instance::mono(cx.tcx, def_id),
|
||||||
promoted: None
|
promoted: None
|
||||||
};
|
};
|
||||||
match cx.tcx.const_eval(param_env.and(cid)) {
|
// trigger the query once for all constants since that will already report the errors
|
||||||
Ok(val) => validate_const(cx.tcx, val, param_env, cid, what),
|
let _ = cx.tcx.const_eval(param_env.and(cid));
|
||||||
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>);
|
struct UnusedBrokenConstVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);
|
||||||
|
|
||||||
impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for UnusedBrokenConstVisitor<'a, 'tcx> {
|
impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for UnusedBrokenConstVisitor<'a, 'tcx> {
|
||||||
fn visit_nested_body(&mut self, id: hir::BodyId) {
|
fn visit_nested_body(&mut self, id: hir::BodyId) {
|
||||||
check_const(self.0, id, "array length");
|
check_const(self.0, id);
|
||||||
}
|
}
|
||||||
fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
|
fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
|
||||||
hir::intravisit::NestedVisitorMap::None
|
hir::intravisit::NestedVisitorMap::None
|
||||||
|
@ -1634,10 +1622,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
|
||||||
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
||||||
match it.node {
|
match it.node {
|
||||||
hir::ItemKind::Const(_, body_id) => {
|
hir::ItemKind::Const(_, body_id) => {
|
||||||
check_const(cx, body_id, "constant");
|
check_const(cx, body_id);
|
||||||
},
|
},
|
||||||
hir::ItemKind::Static(_, _, 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(
|
hir::ItemKind::Ty(ref ty, _) => hir::intravisit::walk_ty(
|
||||||
&mut UnusedBrokenConstVisitor(cx),
|
&mut UnusedBrokenConstVisitor(cx),
|
||||||
|
|
|
@ -152,7 +152,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
UnreachablePub: UnreachablePub,
|
UnreachablePub: UnreachablePub,
|
||||||
UnnameableTestItems: UnnameableTestItems::new(),
|
UnnameableTestItems: UnnameableTestItems::new(),
|
||||||
TypeAliasBounds: TypeAliasBounds,
|
TypeAliasBounds: TypeAliasBounds,
|
||||||
UnusedBrokenConst: UnusedBrokenConst,
|
|
||||||
TrivialConstraints: TrivialConstraints,
|
TrivialConstraints: TrivialConstraints,
|
||||||
TypeLimits: TypeLimits::new(),
|
TypeLimits: TypeLimits::new(),
|
||||||
MissingDoc: MissingDoc::new(),
|
MissingDoc: MissingDoc::new(),
|
||||||
|
|
|
@ -17,13 +17,16 @@ use std::hash::Hash;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use rustc::hir::{self, def_id::DefId};
|
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::mir;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, Instance, query::TyCtxtAt};
|
use rustc::ty::{self, Ty, TyCtxt, Instance, query::TyCtxtAt};
|
||||||
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout};
|
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout};
|
||||||
use rustc::ty::subst::Subst;
|
use rustc::ty::subst::Subst;
|
||||||
|
use rustc::util::nodemap::FxHashSet;
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc::util::common::ErrorReported;
|
||||||
|
|
||||||
use syntax::ast::Mutability;
|
use syntax::ast::Mutability;
|
||||||
use syntax::source_map::{Span, DUMMY_SP};
|
use syntax::source_map::{Span, DUMMY_SP};
|
||||||
|
@ -509,13 +512,11 @@ pub fn const_field<'a, 'tcx>(
|
||||||
// this is not called for statics.
|
// this is not called for statics.
|
||||||
op_to_const(&ecx, field, true)
|
op_to_const(&ecx, field, true)
|
||||||
})();
|
})();
|
||||||
result.map_err(|err| {
|
result.map_err(|error| {
|
||||||
let (trace, span) = ecx.generate_stacktrace(None);
|
let stacktrace = ecx.generate_stacktrace(None);
|
||||||
ConstEvalErr {
|
let err = ::rustc::mir::interpret::ConstEvalErr { error, stacktrace, span: ecx.tcx.span };
|
||||||
error: err,
|
err.report_as_error(ecx.tcx, "could not access field of constant");
|
||||||
stacktrace: trace,
|
ErrorHandled::Reported
|
||||||
span,
|
|
||||||
}.into()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,25 +532,58 @@ pub fn const_variant_index<'a, 'tcx>(
|
||||||
Ok(ecx.read_discriminant(op)?.1)
|
Ok(ecx.read_discriminant(op)?.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_to_allocation_provider<'a, 'tcx>(
|
fn validate_const<'a, 'tcx>(
|
||||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
val: &'tcx ty::Const<'tcx>,
|
constant: &'tcx ty::Const<'tcx>,
|
||||||
) -> &'tcx Allocation {
|
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||||
// FIXME: This really does not need to be a query. Instead, we should have a query for statics
|
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||||
// that returns an allocation directly (or an `AllocId`?), after doing a sanity check of the
|
let cid = key.value;
|
||||||
// value and centralizing error reporting.
|
let ecx = mk_eval_cx(tcx, cid.instance, key.param_env).unwrap();
|
||||||
match val.val {
|
let val = (|| {
|
||||||
ConstValue::ByRef(_, alloc, offset) => {
|
let op = ecx.const_to_op(constant)?;
|
||||||
assert_eq!(offset.bytes(), 0);
|
let mut todo = vec![(op, Vec::new())];
|
||||||
return alloc;
|
let mut seen = FxHashSet();
|
||||||
},
|
seen.insert(op);
|
||||||
_ => bug!("const_to_allocation called on non-static"),
|
while let Some((op, mut path)) = todo.pop() {
|
||||||
}
|
ecx.validate_operand(
|
||||||
|
op,
|
||||||
|
&mut path,
|
||||||
|
&mut seen,
|
||||||
|
&mut todo,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
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>(
|
pub fn const_eval_provider<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||||
|
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||||
|
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> {
|
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||||
trace!("const eval: {:?}", key);
|
trace!("const eval: {:?}", key);
|
||||||
let cid = key.value;
|
let cid = key.value;
|
||||||
|
@ -557,15 +591,10 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||||
|
|
||||||
if let Some(id) = tcx.hir.as_local_node_id(def_id) {
|
if let Some(id) = tcx.hir.as_local_node_id(def_id) {
|
||||||
let tables = tcx.typeck_tables_of(def_id);
|
let tables = tcx.typeck_tables_of(def_id);
|
||||||
let span = tcx.def_span(def_id);
|
|
||||||
|
|
||||||
// Do match-check before building MIR
|
// Do match-check before building MIR
|
||||||
if tcx.check_match(def_id).is_err() {
|
if let Err(ErrorReported) = tcx.check_match(def_id) {
|
||||||
return Err(ConstEvalErr {
|
return Err(ErrorHandled::Reported)
|
||||||
error: EvalErrorKind::CheckMatchError.into(),
|
|
||||||
stacktrace: vec![],
|
|
||||||
span,
|
|
||||||
}.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) {
|
if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) {
|
||||||
|
@ -574,11 +603,7 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||||
|
|
||||||
// Do not continue into miri if typeck errors occurred; it will fail horribly
|
// Do not continue into miri if typeck errors occurred; it will fail horribly
|
||||||
if tables.tainted_by_errors {
|
if tables.tainted_by_errors {
|
||||||
return Err(ConstEvalErr {
|
return Err(ErrorHandled::Reported)
|
||||||
error: EvalErrorKind::CheckMatchError.into(),
|
|
||||||
stacktrace: vec![],
|
|
||||||
span,
|
|
||||||
}.into());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -593,19 +618,50 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
op_to_const(&ecx, op, normalize)
|
op_to_const(&ecx, op, normalize)
|
||||||
}).map_err(|err| {
|
}).map_err(|error| {
|
||||||
let (trace, span) = ecx.generate_stacktrace(None);
|
let stacktrace = ecx.generate_stacktrace(None);
|
||||||
let err = ConstEvalErr {
|
let err = ConstEvalErr { error, stacktrace, span: ecx.tcx.span };
|
||||||
error: err,
|
|
||||||
stacktrace: trace,
|
|
||||||
span,
|
|
||||||
};
|
|
||||||
if tcx.is_static(def_id).is_some() {
|
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");
|
||||||
if tcx.sess.err_count() == 0 {
|
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) {
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_ => 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(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err.report_as_error(
|
||||||
|
ecx.tcx,
|
||||||
|
"evaluation of constant value failed",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// use of constant from other crate
|
||||||
|
err.report_as_error(ecx.tcx, "could not evaluate constant")
|
||||||
}
|
}
|
||||||
err.into()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use hair::cx::block;
|
||||||
use hair::cx::to_ref::ToRef;
|
use hair::cx::to_ref::ToRef;
|
||||||
use hair::util::UserAnnotatedTyHelpers;
|
use hair::util::UserAnnotatedTyHelpers;
|
||||||
use rustc::hir::def::{Def, CtorKind};
|
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::{self, AdtKind, Ty};
|
||||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
|
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
|
||||||
use rustc::ty::cast::CastKind as TyCastKind;
|
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 span = cx.tcx.def_span(def_id);
|
||||||
let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
|
let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
|
||||||
Ok(cv) => cv.unwrap_usize(cx.tcx),
|
Ok(cv) => cv.unwrap_usize(cx.tcx),
|
||||||
Err(e) => {
|
Err(ErrorHandled::Reported) => 0,
|
||||||
e.report_as_error(cx.tcx.at(span), "could not evaluate array length");
|
Err(ErrorHandled::TooGeneric) => {
|
||||||
|
cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -732,13 +732,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
return self.const_to_pat(instance, value, id, span)
|
return self.const_to_pat(instance, value, id, span)
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(_) => {
|
||||||
err.report_as_error(
|
self.tcx.sess.span_err(
|
||||||
self.tcx.at(span),
|
span,
|
||||||
"could not evaluate constant pattern",
|
"could not evaluate constant pattern",
|
||||||
);
|
);
|
||||||
PatternKind::Wild
|
PatternKind::Wild
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -611,8 +611,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||||
} else {
|
} else {
|
||||||
self.param_env
|
self.param_env
|
||||||
};
|
};
|
||||||
self.tcx.const_eval(param_env.and(gid))
|
self.tcx.const_eval(param_env.and(gid)).map_err(|_| {
|
||||||
.map_err(|err| EvalErrorKind::ReferencedConstant(err).into())
|
EvalErrorKind::ReferencedConstant.into()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_place(&self, place: Place<M::PointerTag>) {
|
pub fn dump_place(&self, place: Place<M::PointerTag>) {
|
||||||
|
@ -679,7 +680,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 last_span = None;
|
||||||
let mut frames = Vec::new();
|
let mut frames = Vec::new();
|
||||||
// skip 1 because the last frame is just the environment of the constant
|
// skip 1 because the last frame is just the environment of the constant
|
||||||
|
@ -716,7 +717,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||||
frames.push(FrameInfo { span, location, lint_root });
|
frames.push(FrameInfo { span, location, lint_root });
|
||||||
}
|
}
|
||||||
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
|
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
|
||||||
(frames, self.tcx.span)
|
frames
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -368,10 +368,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||||
instance,
|
instance,
|
||||||
promoted: None,
|
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(|_| {
|
||||||
// no need to report anything, the const_eval call takes care of that for statics
|
// no need to report anything, the const_eval call takes care of that for statics
|
||||||
assert!(tcx.is_static(def_id).is_some());
|
assert!(tcx.is_static(def_id).is_some());
|
||||||
EvalErrorKind::ReferencedConstant(err).into()
|
EvalErrorKind::ReferencedConstant.into()
|
||||||
}).map(|const_val| {
|
}).map(|const_val| {
|
||||||
if let ConstValue::ByRef(_, allocation, _) = const_val.val {
|
if let ConstValue::ByRef(_, allocation, _) = const_val.val {
|
||||||
// We got tcx memory. Let the machine figure out whether and how to
|
// We got tcx memory. Let the machine figure out whether and how to
|
||||||
|
|
|
@ -94,6 +94,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
shim::provide(providers);
|
shim::provide(providers);
|
||||||
transform::provide(providers);
|
transform::provide(providers);
|
||||||
providers.const_eval = const_eval::const_eval_provider;
|
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;
|
providers.check_match = hair::pattern::check_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,7 @@ use rustc::session::config;
|
||||||
use rustc::mir::{self, Location, Promoted};
|
use rustc::mir::{self, Location, Promoted};
|
||||||
use rustc::mir::visit::Visitor as MirVisitor;
|
use rustc::mir::visit::Visitor as MirVisitor;
|
||||||
use rustc::mir::mono::MonoItem;
|
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 monomorphize::{self, Instance};
|
||||||
use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
|
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(..) => {
|
hir::ItemKind::Const(..) => {
|
||||||
// const items only generate mono items if they are
|
// const items only generate mono items if they are
|
||||||
// actually used somewhere. Just declaring them is insufficient.
|
// 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(..) => {
|
hir::ItemKind::Fn(..) => {
|
||||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
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)) {
|
match tcx.const_eval(param_env.and(cid)) {
|
||||||
Ok(val) => collect_const(tcx, val, instance.substs, output),
|
Ok(val) => collect_const(tcx, val, instance.substs, output),
|
||||||
Err(err) => {
|
Err(ErrorHandled::Reported) => {},
|
||||||
use rustc::mir::interpret::EvalErrorKind;
|
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||||
if let EvalErrorKind::ReferencedConstant(_) = err.error.kind {
|
mir.promoted[i].span, "collection encountered polymorphic constant",
|
||||||
err.report_as_error(
|
),
|
||||||
tcx.at(mir.promoted[i].span),
|
|
||||||
"erroneous constant used",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1247,14 +1256,10 @@ fn collect_const<'a, 'tcx>(
|
||||||
};
|
};
|
||||||
match tcx.const_eval(param_env.and(cid)) {
|
match tcx.const_eval(param_env.and(cid)) {
|
||||||
Ok(val) => val.val,
|
Ok(val) => val.val,
|
||||||
Err(err) => {
|
Err(ErrorHandled::Reported) => return,
|
||||||
let span = tcx.def_span(def_id);
|
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||||
err.report_as_error(
|
tcx.def_span(def_id), "collection encountered polymorphic constant",
|
||||||
tcx.at(span),
|
),
|
||||||
"constant evaluation error",
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => constant.val,
|
_ => constant.val,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind};
|
||||||
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
|
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
|
||||||
use rustc::mir::visit::{Visitor, PlaceContext};
|
use rustc::mir::visit::{Visitor, PlaceContext};
|
||||||
use rustc::mir::interpret::{
|
use rustc::mir::interpret::{
|
||||||
ConstEvalErr, EvalErrorKind, Scalar, GlobalId, EvalResult
|
ConstEvalErr, EvalErrorKind, Scalar, GlobalId, EvalResult,
|
||||||
};
|
};
|
||||||
use rustc::ty::{TyCtxt, self, Instance};
|
use rustc::ty::{TyCtxt, self, Instance};
|
||||||
use interpret::{self, EvalContext, Value, OpTy, MemoryKind, ScalarMaybeUndef};
|
use interpret::{self, EvalContext, Value, OpTy, MemoryKind, ScalarMaybeUndef};
|
||||||
|
@ -45,12 +45,17 @@ impl MirPass for ConstProp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match tcx.describe_def(source.def_id) {
|
match tcx.describe_def(source.def_id) {
|
||||||
// skip statics/consts because they'll be evaluated by miri anyway
|
// Only run const prop on functions, methods, closures and associated constants
|
||||||
Some(Def::Const(..)) |
|
| Some(Def::Fn(_))
|
||||||
Some(Def::Static(..)) => return,
|
| Some(Def::Method(_))
|
||||||
// we still run on associated constants, because they might not get evaluated
|
| Some(Def::AssociatedConst(_))
|
||||||
// within the current crate
|
| Some(Def::Closure(_))
|
||||||
_ => {},
|
=> {}
|
||||||
|
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
|
||||||
|
def => {
|
||||||
|
trace!("ConstProp skipped for {:?} ({:?})", source.def_id, def);
|
||||||
|
return
|
||||||
|
},
|
||||||
}
|
}
|
||||||
trace!("ConstProp starting for {:?}", source.def_id);
|
trace!("ConstProp starting for {:?}", source.def_id);
|
||||||
|
|
||||||
|
@ -144,8 +149,8 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
let r = match f(self) {
|
let r = match f(self) {
|
||||||
Ok(val) => Some(val),
|
Ok(val) => Some(val),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let (stacktrace, span) = self.ecx.generate_stacktrace(None);
|
let stacktrace = self.ecx.generate_stacktrace(None);
|
||||||
let diagnostic = ConstEvalErr { span, error, stacktrace };
|
let diagnostic = ConstEvalErr { span: source_info.span, error, stacktrace };
|
||||||
use rustc::mir::interpret::EvalErrorKind::*;
|
use rustc::mir::interpret::EvalErrorKind::*;
|
||||||
match diagnostic.error.kind {
|
match diagnostic.error.kind {
|
||||||
// don't report these, they make no sense in a const prop context
|
// don't report these, they make no sense in a const prop context
|
||||||
|
@ -208,7 +213,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
| ReadFromReturnPointer
|
| ReadFromReturnPointer
|
||||||
| GeneratorResumedAfterReturn
|
| GeneratorResumedAfterReturn
|
||||||
| GeneratorResumedAfterPanic
|
| GeneratorResumedAfterPanic
|
||||||
| ReferencedConstant(_)
|
| ReferencedConstant
|
||||||
| InfiniteLoop
|
| InfiniteLoop
|
||||||
=> {
|
=> {
|
||||||
// FIXME: report UB here
|
// FIXME: report UB here
|
||||||
|
@ -223,7 +228,6 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
| UnimplementedTraitSelection
|
| UnimplementedTraitSelection
|
||||||
| TypeckError
|
| TypeckError
|
||||||
| TooGeneric
|
| TooGeneric
|
||||||
| CheckMatchError
|
|
||||||
// these are just noise
|
// these are just noise
|
||||||
=> {},
|
=> {},
|
||||||
|
|
||||||
|
@ -264,16 +268,11 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
Some((op, c.span))
|
Some((op, c.span))
|
||||||
},
|
},
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let (stacktrace, span) = self.ecx.generate_stacktrace(None);
|
let stacktrace = self.ecx.generate_stacktrace(None);
|
||||||
let err = ConstEvalErr {
|
let err = ::rustc::mir::interpret::ConstEvalErr {
|
||||||
span,
|
error, stacktrace, span: source_info.span,
|
||||||
error,
|
|
||||||
stacktrace,
|
|
||||||
};
|
};
|
||||||
err.report_as_error(
|
err.report_as_error(self.ecx.tcx, "erroneous constant used");
|
||||||
self.tcx.at(source_info.span),
|
|
||||||
"could not evaluate constant",
|
|
||||||
);
|
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -827,6 +827,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
ref_id: id_from_def_id(def_id),
|
ref_id: id_from_def_id(def_id),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
HirDef::Closure(_) |
|
||||||
HirDef::PrimTy(..) |
|
HirDef::PrimTy(..) |
|
||||||
HirDef::SelfTy(..) |
|
HirDef::SelfTy(..) |
|
||||||
HirDef::Label(..) |
|
HirDef::Label(..) |
|
||||||
|
|
|
@ -4238,13 +4238,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
let count = tcx.const_eval(param_env.and(global_id));
|
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 {
|
let uty = match expected {
|
||||||
ExpectHasType(uty) => {
|
ExpectHasType(uty) => {
|
||||||
match uty.sty {
|
match uty.sty {
|
||||||
|
|
|
@ -16,7 +16,7 @@ const fn f(x: usize) -> usize {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
//~^ let bindings in constant functions are unstable
|
//~^ let bindings in constant functions are unstable
|
||||||
//~| statements in constant functions are unstable
|
//~| statements in constant functions are unstable
|
||||||
for i in 0..x {
|
for i in 0..x { //~ ERROR E0080
|
||||||
//~^ ERROR E0015
|
//~^ ERROR E0015
|
||||||
//~| ERROR E0019
|
//~| ERROR E0019
|
||||||
sum += i;
|
sum += i;
|
||||||
|
@ -26,5 +26,5 @@ const fn f(x: usize) -> usize {
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn main() {
|
fn main() {
|
||||||
let a : [i32; f(X)]; //~ ERROR E0080
|
let a : [i32; f(X)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,5 +14,5 @@ fn main() {
|
||||||
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
|
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
|
||||||
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
||||||
//~^ ERROR constant contains unimplemented expression type
|
//~^ ERROR constant contains unimplemented expression type
|
||||||
//~| ERROR could not evaluate repeat length
|
//~| ERROR evaluation of constant value failed
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,9 @@
|
||||||
const A: &'static [i32] = &[];
|
const A: &'static [i32] = &[];
|
||||||
const B: i32 = (&A)[1];
|
const B: i32 = (&A)[1];
|
||||||
//~^ index out of bounds: the len is 0 but the index is 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
|
||||||
|
//~| ERROR any use of this value will cause an error
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = B;
|
let _ = B; //~ ERROR erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/array_const_index-0.rs:12:1
|
||||||
|
|
|
|
||||||
LL | const B: i32 = (&A)[1];
|
LL | const B: i32 = (&A)[1];
|
||||||
|
@ -8,5 +8,20 @@ LL | const B: i32 = (&A)[1];
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= note: #[deny(const_err)] on by default
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/array_const_index-0.rs:12:1
|
||||||
|
|
|
||||||
|
LL | const B: i32 = (&A)[1];
|
||||||
|
| ^^^^^^^^^^^^^^^-------^
|
||||||
|
| |
|
||||||
|
| index out of bounds: the len is 0 but the index is 1
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/array_const_index-0.rs:18:13
|
||||||
|
|
|
||||||
|
LL | let _ = B; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -11,8 +11,9 @@
|
||||||
const A: [i32; 0] = [];
|
const A: [i32; 0] = [];
|
||||||
const B: i32 = A[1];
|
const B: i32 = A[1];
|
||||||
//~^ index out of bounds: the len is 0 but the index is 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
|
||||||
|
//~| ERROR any use of this value will cause an error
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = B;
|
let _ = B; //~ ERROR erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/array_const_index-1.rs:12:1
|
||||||
|
|
|
|
||||||
LL | const B: i32 = A[1];
|
LL | const B: i32 = A[1];
|
||||||
|
@ -8,5 +8,20 @@ LL | const B: i32 = A[1];
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= note: #[deny(const_err)] on by default
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/array_const_index-1.rs:12:1
|
||||||
|
|
|
||||||
|
LL | const B: i32 = A[1];
|
||||||
|
| ^^^^^^^^^^^^^^^----^
|
||||||
|
| |
|
||||||
|
| index out of bounds: the len is 0 but the index is 1
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/array_const_index-1.rs:18:13
|
||||||
|
|
|
||||||
|
LL | let _ = B; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -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 BAR: usize = FOO[5]; // no error, because the error below occurs before regular const eval
|
||||||
|
|
||||||
const BLUB: [u32; FOO[4]] = [5, 6];
|
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
|
//~| index out of bounds: the len is 3 but the index is 4
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -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
|
--> $DIR/const-array-oob.rs:18:19
|
||||||
|
|
|
|
||||||
LL | const BLUB: [u32; FOO[4]] = [5, 6];
|
LL | const BLUB: [u32; FOO[4]] = [5, 6];
|
||||||
| ^^^^^^
|
| ^^^^^^ index out of bounds: the len is 3 but the index is 4
|
||||||
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
|
||||||
|
|
||||||
error[E0080]: could not evaluate constant expression
|
error: aborting due to previous error
|
||||||
--> $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
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -4,6 +4,12 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct
|
||||||
LL | let _ = [0; f(2)];
|
LL | let _ = [0; f(2)];
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/const-call.rs:16:17
|
||||||
|
|
|
||||||
|
LL | let _ = [0; f(2)];
|
||||||
|
| ^^^^ calling non-const fn `f`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0015`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -11,16 +11,17 @@
|
||||||
#![deny(const_err)]
|
#![deny(const_err)]
|
||||||
|
|
||||||
pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
|
pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
|
||||||
|
//~^ ERROR const_err
|
||||||
pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
|
pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
|
||||||
pub const C: u8 = 200u8 * 4; //~ ERROR const_err
|
pub const C: u8 = 200u8 * 4; //~ ERROR const_err
|
||||||
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
|
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
|
||||||
pub const E: u8 = [5u8][1]; //~ ERROR const_err
|
pub const E: u8 = [5u8][1]; //~ ERROR const_err
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _a = A;
|
let _a = A; //~ ERROR erroneous constant used
|
||||||
let _b = B;
|
let _b = B; //~ ERROR erroneous constant used
|
||||||
let _c = C;
|
let _c = C; //~ ERROR erroneous constant used
|
||||||
let _d = D;
|
let _d = D; //~ ERROR erroneous constant used
|
||||||
let _e = E;
|
let _e = E; //~ ERROR erroneous constant used
|
||||||
let _e = [6u8][1];
|
let _e = [6u8][1]; //~ ERROR index out of bounds
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/const-err-early.rs:13:1
|
||||||
|
|
|
|
||||||
LL | pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
|
LL | pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
|
||||||
|
@ -12,37 +12,82 @@ note: lint level defined here
|
||||||
LL | #![deny(const_err)]
|
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
|
--> $DIR/const-err-early.rs:15:1
|
||||||
|
|
|
|
||||||
LL | pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
|
LL | pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
|
||||||
| ^^^^^^^^^^^^^^^^^^-------------^
|
| ^^^^^^^^^^^^^^^^^^-------------^
|
||||||
| |
|
| |
|
||||||
| attempt to add with overflow
|
| 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
|
--> $DIR/const-err-early.rs:16:1
|
||||||
|
|
|
|
||||||
LL | pub const C: u8 = 200u8 * 4; //~ ERROR const_err
|
LL | pub const C: u8 = 200u8 * 4; //~ ERROR const_err
|
||||||
| ^^^^^^^^^^^^^^^^^^---------^
|
| ^^^^^^^^^^^^^^^^^^---------^
|
||||||
| |
|
| |
|
||||||
| attempt to multiply with overflow
|
| 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
|
--> $DIR/const-err-early.rs:17:1
|
||||||
|
|
|
|
||||||
LL | pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
|
LL | pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
|
||||||
| ^^^^^^^^^^^^^^^^^^-----------------^
|
| ^^^^^^^^^^^^^^^^^^-----------------^
|
||||||
| |
|
| |
|
||||||
| attempt to subtract with overflow
|
| 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
|
--> $DIR/const-err-early.rs:18:1
|
||||||
|
|
|
|
||||||
LL | pub const E: u8 = [5u8][1]; //~ ERROR const_err
|
LL | pub const E: u8 = [5u8][1]; //~ ERROR const_err
|
||||||
| ^^^^^^^^^^^^^^^^^^--------^
|
| ^^^^^^^^^^^^^^^^^^--------^
|
||||||
| |
|
| |
|
||||||
| index out of bounds: the len is 1 but the index is 1
|
| index out of bounds: the len is 1 but the index is 1
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
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
|
||||||
|
| ^^^^^^^^^^^^^^^^^^-------------^
|
||||||
|
| |
|
||||||
|
| attempt to negate with overflow
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err-early.rs:21:14
|
||||||
|
|
|
||||||
|
LL | let _a = A; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err-early.rs:22:14
|
||||||
|
|
|
||||||
|
LL | let _b = B; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err-early.rs:23:14
|
||||||
|
|
|
||||||
|
LL | let _c = C; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err-early.rs:24:14
|
||||||
|
|
|
||||||
|
LL | let _d = D; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err-early.rs:25:14
|
||||||
|
|
|
||||||
|
LL | let _e = E; //~ ERROR erroneous constant used
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error: index out of bounds: the len is 1 but the index is 1
|
||||||
|
--> $DIR/const-err-early.rs:26:14
|
||||||
|
|
|
||||||
|
LL | let _e = [6u8][1]; //~ ERROR index out of bounds
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -11,17 +11,16 @@
|
||||||
#![deny(const_err)]
|
#![deny(const_err)]
|
||||||
|
|
||||||
pub const A: i8 = -std::i8::MIN;
|
pub const A: i8 = -std::i8::MIN;
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR const_err
|
||||||
|
//~| ERROR const_err
|
||||||
pub const B: i8 = A;
|
pub const B: i8 = A;
|
||||||
//~^ ERROR const_err
|
//~^ ERROR const_err
|
||||||
//~| ERROR const_err
|
|
||||||
pub const C: u8 = A as u8;
|
pub const C: u8 = A as u8;
|
||||||
//~^ ERROR const_err
|
//~^ ERROR const_err
|
||||||
//~| ERROR const_err
|
|
||||||
pub const D: i8 = 50 - A;
|
pub const D: i8 = 50 - A;
|
||||||
//~^ ERROR const_err
|
//~^ ERROR const_err
|
||||||
//~| ERROR const_err
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = (A, B, C, D);
|
let _ = (A, B, C, D);
|
||||||
|
//~^ ERROR erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/const-err-multi.rs:13:1
|
||||||
|
|
|
|
||||||
LL | pub const A: i8 = -std::i8::MIN;
|
LL | pub const A: i8 = -std::i8::MIN;
|
||||||
|
@ -12,33 +12,15 @@ note: lint level defined here
|
||||||
LL | #![deny(const_err)]
|
LL | #![deny(const_err)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: referenced constant has errors
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-err-multi.rs:15:1
|
--> $DIR/const-err-multi.rs:16: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
|
|
||||||
--> $DIR/const-err-multi.rs:15:1
|
|
||||||
|
|
|
|
||||||
LL | pub const B: i8 = A;
|
LL | pub const B: i8 = A;
|
||||||
| ^^^^^^^^^^^^^^^^^^-^
|
| ^^^^^^^^^^^^^^^^^^-^
|
||||||
| |
|
| |
|
||||||
| referenced constant has errors
|
| referenced constant has errors
|
||||||
|
|
||||||
error: referenced constant has errors
|
error: any use of this value will cause an error
|
||||||
--> $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
|
--> $DIR/const-err-multi.rs:18:1
|
||||||
|
|
|
|
||||||
LL | pub const C: u8 = A as u8;
|
LL | pub const C: u8 = A as u8;
|
||||||
|
@ -46,22 +28,28 @@ LL | pub const C: u8 = A as u8;
|
||||||
| |
|
| |
|
||||||
| referenced constant has errors
|
| referenced constant has errors
|
||||||
|
|
||||||
error: referenced constant has errors
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-err-multi.rs:21:1
|
--> $DIR/const-err-multi.rs:20: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
|
|
||||||
|
|
|
|
||||||
LL | pub const D: i8 = 50 - A;
|
LL | pub const D: i8 = 50 - A;
|
||||||
| ^^^^^^^^^^^^^^^^^^------^
|
| ^^^^^^^^^^^^^^^^^^------^
|
||||||
| |
|
| |
|
||||||
| referenced constant has errors
|
| referenced constant has errors
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
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;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^-------------^
|
||||||
|
| |
|
||||||
|
| attempt to negate with overflow
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err-multi.rs:24:13
|
||||||
|
|
|
||||||
|
LL | let _ = (A, B, C, D);
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -10,23 +10,18 @@
|
||||||
|
|
||||||
// compile-flags: -Zforce-overflow-checks=on
|
// 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(exceeding_bitshifts)]
|
||||||
#![allow(const_err)]
|
#![warn(const_err)]
|
||||||
|
|
||||||
fn black_box<T>(_: T) {
|
fn black_box<T>(_: T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the two uses get two errors.
|
|
||||||
const FOO: u8 = [5u8][1];
|
const FOO: u8 = [5u8][1];
|
||||||
//~^ ERROR constant evaluation error
|
//~^ WARN any use of this value will cause an 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() {
|
fn main() {
|
||||||
black_box((FOO, FOO));
|
black_box((FOO, FOO));
|
||||||
//~^ ERROR referenced constant has errors
|
//~^ ERROR erroneous constant used
|
||||||
//~| ERROR could not evaluate constant
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
error[E0080]: referenced constant has errors
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/const-err.rs:29:15
|
--> $DIR/const-err.rs:20:1
|
||||||
|
|
|
|
||||||
LL | const FOO: u8 = [5u8][1];
|
LL | const FOO: u8 = [5u8][1];
|
||||||
| -------- index out of bounds: the len is 1 but the index is 1
|
| ^^^^^^^^^^^^^^^^--------^
|
||||||
...
|
| |
|
||||||
LL | black_box((FOO, FOO));
|
| index out of bounds: the len is 1 but the index is 1
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0080]: could not evaluate constant
|
|
||||||
--> $DIR/const-err.rs:29:15
|
|
||||||
|
|
|
|
||||||
LL | black_box((FOO, FOO));
|
note: lint level defined here
|
||||||
| ^^^^^^^^^^ referenced constant has errors
|
--> $DIR/const-err.rs:14:9
|
||||||
|
|
|
||||||
|
LL | #![warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0080]: constant evaluation error
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/const-err.rs:24:1
|
--> $DIR/const-err.rs:20:1
|
||||||
|
|
|
|
||||||
LL | const FOO: u8 = [5u8][1];
|
LL | const FOO: u8 = [5u8][1];
|
||||||
| ^^^^^^^^^^^^^^^^--------^
|
| ^^^^^^^^^^^^^^^^--------^
|
||||||
| |
|
| |
|
||||||
| index out of bounds: the len is 1 but the index is 1
|
| index out of bounds: the len is 1 but the index is 1
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-err.rs:25: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`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -16,7 +16,7 @@ union Foo {
|
||||||
|
|
||||||
enum Bar {
|
enum Bar {
|
||||||
Boo = [unsafe { Foo { b: () }.a }; 4][3],
|
Boo = [unsafe { Foo { b: () }.a }; 4][3],
|
||||||
//~^ ERROR could not evaluate enum discriminant
|
//~^ ERROR evaluation of constant value failed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0080]: could not evaluate enum discriminant
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/const-err4.rs:18:11
|
--> $DIR/const-err4.rs:18:11
|
||||||
|
|
|
|
||||||
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
|
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
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];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| attempt to subtract with overflow
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/conditional_array_execution.rs:11:9
|
||||||
|
|
|
||||||
|
LL | #![warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/conditional_array_execution.rs:19:14
|
||||||
|
|
|
||||||
|
LL | println!("{}", FOO);
|
||||||
|
| ^^^^ --- referenced constant has errors
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
|
@ -13,10 +13,9 @@
|
||||||
const X: u32 = 5;
|
const X: u32 = 5;
|
||||||
const Y: u32 = 6;
|
const Y: u32 = 6;
|
||||||
const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
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() {
|
fn main() {
|
||||||
println!("{}", FOO);
|
println!("{}", FOO);
|
||||||
//~^ ERROR
|
//~^ ERROR
|
||||||
//~| ERROR
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/conditional_array_execution.rs:15:1
|
||||||
|
|
|
|
||||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
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)]
|
LL | #![warn(const_err)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0080]: referenced constant has errors
|
error[E0080]: evaluation of constant expression failed
|
||||||
--> $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
|
|
||||||
--> $DIR/conditional_array_execution.rs:19:20
|
--> $DIR/conditional_array_execution.rs:19:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", FOO);
|
LL | println!("{}", FOO);
|
||||||
| ^^^ referenced constant has errors
|
| ^^^ 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`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -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
|
--> $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"),
|
LL | NEG_NEG_128 => println!("A"),
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
|
||||||
|
|
|
@ -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
|
--> $DIR/const-eval-overflow-3.rs:30:11
|
||||||
|
|
|
|
||||||
LL | = [0; (i8::MAX + 1) as usize];
|
LL | = [0; (i8::MAX + 1) as usize];
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ attempt to add with overflow
|
||||||
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
|
||||||
|
|
||||||
error[E0080]: could not evaluate repeat length
|
error: aborting due to previous error
|
||||||
--> $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
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -21,8 +21,7 @@ use std::{u8, u16, u32, u64, usize};
|
||||||
|
|
||||||
const A_I8_T
|
const A_I8_T
|
||||||
: [u32; (i8::MAX as i8 + 1i8) as usize]
|
: [u32; (i8::MAX as i8 + 1i8) as usize]
|
||||||
//~^ ERROR attempt to add with overflow
|
//~^ ERROR evaluation of constant value failed
|
||||||
//~| ERROR could not evaluate constant expression
|
|
||||||
= [0; (i8::MAX as usize) + 1];
|
= [0; (i8::MAX as usize) + 1];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -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
|
--> $DIR/const-eval-overflow-4.rs:23:13
|
||||||
|
|
|
|
||||||
LL | : [u32; (i8::MAX as i8 + 1i8) as usize]
|
LL | : [u32; (i8::MAX as i8 + 1i8) as usize]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^ attempt to add with overflow
|
||||||
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
|
||||||
|
|
||||||
error[E0080]: could not evaluate constant expression
|
error: aborting due to previous error
|
||||||
--> $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
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -21,62 +21,55 @@ use std::fmt;
|
||||||
use std::{i8, i16, i32, i64, isize};
|
use std::{i8, i16, i32, i64, isize};
|
||||||
use std::{u8, u16, u32, u64, usize};
|
use std::{u8, u16, u32, u64, usize};
|
||||||
|
|
||||||
const VALS_I8: (i8,) =
|
const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ const_err
|
||||||
(
|
(
|
||||||
i8::MIN - 1,
|
i8::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I16: (i16,) =
|
const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i16::MIN - 1,
|
i16::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I32: (i32,) =
|
const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i32::MIN - 1,
|
i32::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I64: (i64,) =
|
const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i64::MIN - 1,
|
i64::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U8: (u8,) =
|
const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
u8::MIN - 1,
|
u8::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U16: (u16,) = (
|
const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
u16::MIN - 1,
|
u16::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U32: (u32,) = (
|
const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
u32::MIN - 1,
|
u32::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U64: (u64,) =
|
const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
u64::MIN - 1,
|
u64::MIN - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo(VALS_I8);
|
foo(VALS_I8); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I16);
|
foo(VALS_I16); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I32);
|
foo(VALS_I32); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I64);
|
foo(VALS_I64); //~ ERROR erroneous constant used
|
||||||
|
|
||||||
foo(VALS_U8);
|
foo(VALS_U8); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U16);
|
foo(VALS_U16); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U32);
|
foo(VALS_U32); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U64);
|
foo(VALS_U64); //~ ERROR erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T>(_: T) {
|
fn foo<T>(_: T) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:24:1
|
--> $DIR/const-eval-overflow2.rs:24:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I8: (i8,) =
|
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
LL | | //~^ const_err
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i8::MIN - 1,
|
LL | | i8::MIN - 1,
|
||||||
| | ----------- attempt to subtract with overflow
|
| | ----------- attempt to subtract with overflow
|
||||||
|
@ -15,80 +15,133 @@ note: lint level defined here
|
||||||
LL | #![deny(const_err)]
|
LL | #![deny(const_err)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:30:1
|
--> $DIR/const-eval-overflow2.rs:30:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I16: (i16,) =
|
LL | / const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i16::MIN - 1,
|
LL | | i16::MIN - 1,
|
||||||
| | ------------ attempt to subtract with overflow
|
| | ------------ attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:36:1
|
--> $DIR/const-eval-overflow2.rs:35:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I32: (i32,) =
|
LL | / const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i32::MIN - 1,
|
LL | | i32::MIN - 1,
|
||||||
| | ------------ attempt to subtract with overflow
|
| | ------------ attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:42:1
|
--> $DIR/const-eval-overflow2.rs:40:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I64: (i64,) =
|
LL | / const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i64::MIN - 1,
|
LL | | i64::MIN - 1,
|
||||||
| | ------------ attempt to subtract with overflow
|
| | ------------ attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:48:1
|
--> $DIR/const-eval-overflow2.rs:45:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U8: (u8,) =
|
LL | / const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | u8::MIN - 1,
|
LL | | u8::MIN - 1,
|
||||||
| | ----------- attempt to subtract with overflow
|
| | ----------- attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:54:1
|
--> $DIR/const-eval-overflow2.rs:50:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U16: (u16,) = (
|
LL | / const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | u16::MIN - 1,
|
LL | | u16::MIN - 1,
|
||||||
| | ------------ attempt to subtract with overflow
|
| | ------------ attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:59:1
|
--> $DIR/const-eval-overflow2.rs:54:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U32: (u32,) = (
|
LL | / const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | u32::MIN - 1,
|
LL | | u32::MIN - 1,
|
||||||
| | ------------ attempt to subtract with overflow
|
| | ------------ attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2.rs:64:1
|
--> $DIR/const-eval-overflow2.rs:58:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U64: (u64,) =
|
LL | / const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | u64::MIN - 1,
|
LL | | u64::MIN - 1,
|
||||||
| | ------------ attempt to subtract with overflow
|
| | ------------ attempt to subtract with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/const-eval-overflow2.rs:24:1
|
||||||
|
|
|
||||||
|
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
|
LL | | //~^ const_err
|
||||||
|
LL | | (
|
||||||
|
LL | | i8::MIN - 1,
|
||||||
|
| | ----------- attempt to subtract with overflow
|
||||||
|
LL | | );
|
||||||
|
| |_______^
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:64:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I8); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:65:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I16); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:66:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I32); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:67:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I64); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:69:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U8); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:70:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U16); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:71:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U32); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2.rs:72:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U64); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -21,62 +21,55 @@ use std::fmt;
|
||||||
use std::{i8, i16, i32, i64, isize};
|
use std::{i8, i16, i32, i64, isize};
|
||||||
use std::{u8, u16, u32, u64, usize};
|
use std::{u8, u16, u32, u64, usize};
|
||||||
|
|
||||||
const VALS_I8: (i8,) =
|
const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ const_err
|
||||||
(
|
(
|
||||||
i8::MAX + 1,
|
i8::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I16: (i16,) =
|
const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i16::MAX + 1,
|
i16::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I32: (i32,) =
|
const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i32::MAX + 1,
|
i32::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I64: (i64,) =
|
const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i64::MAX + 1,
|
i64::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U8: (u8,) =
|
const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
u8::MAX + 1,
|
u8::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U16: (u16,) = (
|
const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
u16::MAX + 1,
|
u16::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U32: (u32,) = (
|
const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
u32::MAX + 1,
|
u32::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U64: (u64,) =
|
const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
u64::MAX + 1,
|
u64::MAX + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo(VALS_I8);
|
foo(VALS_I8); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I16);
|
foo(VALS_I16); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I32);
|
foo(VALS_I32); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I64);
|
foo(VALS_I64); //~ ERROR erroneous constant used
|
||||||
|
|
||||||
foo(VALS_U8);
|
foo(VALS_U8); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U16);
|
foo(VALS_U16); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U32);
|
foo(VALS_U32); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U64);
|
foo(VALS_U64); //~ ERROR erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T>(_: T) {
|
fn foo<T>(_: T) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:24:1
|
--> $DIR/const-eval-overflow2b.rs:24:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I8: (i8,) =
|
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
LL | | //~^ const_err
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i8::MAX + 1,
|
LL | | i8::MAX + 1,
|
||||||
| | ----------- attempt to add with overflow
|
| | ----------- attempt to add with overflow
|
||||||
|
@ -15,80 +15,133 @@ note: lint level defined here
|
||||||
LL | #![deny(const_err)]
|
LL | #![deny(const_err)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:30:1
|
--> $DIR/const-eval-overflow2b.rs:30:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I16: (i16,) =
|
LL | / const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i16::MAX + 1,
|
LL | | i16::MAX + 1,
|
||||||
| | ------------ attempt to add with overflow
|
| | ------------ attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:36:1
|
--> $DIR/const-eval-overflow2b.rs:35:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I32: (i32,) =
|
LL | / const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i32::MAX + 1,
|
LL | | i32::MAX + 1,
|
||||||
| | ------------ attempt to add with overflow
|
| | ------------ attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:42:1
|
--> $DIR/const-eval-overflow2b.rs:40:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I64: (i64,) =
|
LL | / const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i64::MAX + 1,
|
LL | | i64::MAX + 1,
|
||||||
| | ------------ attempt to add with overflow
|
| | ------------ attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:48:1
|
--> $DIR/const-eval-overflow2b.rs:45:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U8: (u8,) =
|
LL | / const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | u8::MAX + 1,
|
LL | | u8::MAX + 1,
|
||||||
| | ----------- attempt to add with overflow
|
| | ----------- attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:54:1
|
--> $DIR/const-eval-overflow2b.rs:50:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U16: (u16,) = (
|
LL | / const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | u16::MAX + 1,
|
LL | | u16::MAX + 1,
|
||||||
| | ------------ attempt to add with overflow
|
| | ------------ attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:59:1
|
--> $DIR/const-eval-overflow2b.rs:54:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U32: (u32,) = (
|
LL | / const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | u32::MAX + 1,
|
LL | | u32::MAX + 1,
|
||||||
| | ------------ attempt to add with overflow
|
| | ------------ attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2b.rs:64:1
|
--> $DIR/const-eval-overflow2b.rs:58:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U64: (u64,) =
|
LL | / const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | u64::MAX + 1,
|
LL | | u64::MAX + 1,
|
||||||
| | ------------ attempt to add with overflow
|
| | ------------ attempt to add with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:24:1
|
||||||
|
|
|
||||||
|
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
|
LL | | //~^ const_err
|
||||||
|
LL | | (
|
||||||
|
LL | | i8::MAX + 1,
|
||||||
|
| | ----------- attempt to add with overflow
|
||||||
|
LL | | );
|
||||||
|
| |_______^
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:64:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I8); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:65:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I16); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:66:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I32); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:67:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I64); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:69:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U8); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:70:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U16); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:71:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U32); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2b.rs:72:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U64); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -21,62 +21,55 @@ use std::fmt;
|
||||||
use std::{i8, i16, i32, i64, isize};
|
use std::{i8, i16, i32, i64, isize};
|
||||||
use std::{u8, u16, u32, u64, usize};
|
use std::{u8, u16, u32, u64, usize};
|
||||||
|
|
||||||
const VALS_I8: (i8,) =
|
const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ const_err
|
||||||
(
|
(
|
||||||
i8::MIN * 2,
|
i8::MIN * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I16: (i16,) =
|
const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i16::MIN * 2,
|
i16::MIN * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I32: (i32,) =
|
const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i32::MIN * 2,
|
i32::MIN * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_I64: (i64,) =
|
const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
i64::MIN * 2,
|
i64::MIN * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U8: (u8,) =
|
const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
u8::MAX * 2,
|
u8::MAX * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U16: (u16,) = (
|
const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
u16::MAX * 2,
|
u16::MAX * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U32: (u32,) = (
|
const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
u32::MAX * 2,
|
u32::MAX * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const VALS_U64: (u64,) =
|
const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
|
||||||
//~^ ERROR this constant cannot be used
|
|
||||||
(
|
(
|
||||||
u64::MAX * 2,
|
u64::MAX * 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo(VALS_I8);
|
foo(VALS_I8); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I16);
|
foo(VALS_I16); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I32);
|
foo(VALS_I32); //~ ERROR erroneous constant used
|
||||||
foo(VALS_I64);
|
foo(VALS_I64); //~ ERROR erroneous constant used
|
||||||
|
|
||||||
foo(VALS_U8);
|
foo(VALS_U8); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U16);
|
foo(VALS_U16); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U32);
|
foo(VALS_U32); //~ ERROR erroneous constant used
|
||||||
foo(VALS_U64);
|
foo(VALS_U64); //~ ERROR erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T>(_: T) {
|
fn foo<T>(_: T) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:24:1
|
--> $DIR/const-eval-overflow2c.rs:24:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I8: (i8,) =
|
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
LL | | //~^ const_err
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i8::MIN * 2,
|
LL | | i8::MIN * 2,
|
||||||
| | ----------- attempt to multiply with overflow
|
| | ----------- attempt to multiply with overflow
|
||||||
|
@ -15,80 +15,133 @@ note: lint level defined here
|
||||||
LL | #![deny(const_err)]
|
LL | #![deny(const_err)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:30:1
|
--> $DIR/const-eval-overflow2c.rs:30:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I16: (i16,) =
|
LL | / const VALS_I16: (i16,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i16::MIN * 2,
|
LL | | i16::MIN * 2,
|
||||||
| | ------------ attempt to multiply with overflow
|
| | ------------ attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:36:1
|
--> $DIR/const-eval-overflow2c.rs:35:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I32: (i32,) =
|
LL | / const VALS_I32: (i32,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i32::MIN * 2,
|
LL | | i32::MIN * 2,
|
||||||
| | ------------ attempt to multiply with overflow
|
| | ------------ attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:42:1
|
--> $DIR/const-eval-overflow2c.rs:40:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_I64: (i64,) =
|
LL | / const VALS_I64: (i64,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | i64::MIN * 2,
|
LL | | i64::MIN * 2,
|
||||||
| | ------------ attempt to multiply with overflow
|
| | ------------ attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:48:1
|
--> $DIR/const-eval-overflow2c.rs:45:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U8: (u8,) =
|
LL | / const VALS_U8: (u8,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | u8::MAX * 2,
|
LL | | u8::MAX * 2,
|
||||||
| | ----------- attempt to multiply with overflow
|
| | ----------- attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:54:1
|
--> $DIR/const-eval-overflow2c.rs:50:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U16: (u16,) = (
|
LL | / const VALS_U16: (u16,) = ( //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | u16::MAX * 2,
|
LL | | u16::MAX * 2,
|
||||||
| | ------------ attempt to multiply with overflow
|
| | ------------ attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:59:1
|
--> $DIR/const-eval-overflow2c.rs:54:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U32: (u32,) = (
|
LL | / const VALS_U32: (u32,) = ( //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | u32::MAX * 2,
|
LL | | u32::MAX * 2,
|
||||||
| | ------------ attempt to multiply with overflow
|
| | ------------ attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const-eval-overflow2c.rs:64:1
|
--> $DIR/const-eval-overflow2c.rs:58:1
|
||||||
|
|
|
|
||||||
LL | / const VALS_U64: (u64,) =
|
LL | / const VALS_U64: (u64,) = //~ ERROR any use of this value will cause an error
|
||||||
LL | | //~^ ERROR this constant cannot be used
|
|
||||||
LL | | (
|
LL | | (
|
||||||
LL | | u64::MAX * 2,
|
LL | | u64::MAX * 2,
|
||||||
| | ------------ attempt to multiply with overflow
|
| | ------------ attempt to multiply with overflow
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_______^
|
| |_______^
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:24:1
|
||||||
|
|
|
||||||
|
LL | / const VALS_I8: (i8,) = //~ ERROR any use of this value will cause an error
|
||||||
|
LL | | //~^ const_err
|
||||||
|
LL | | (
|
||||||
|
LL | | i8::MIN * 2,
|
||||||
|
| | ----------- attempt to multiply with overflow
|
||||||
|
LL | | );
|
||||||
|
| |_______^
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:64:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I8); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:65:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I16); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:66:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I32); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:67:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_I64); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:69:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U8); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:70:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U16); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:71:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U32); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/const-eval-overflow2c.rs:72:5
|
||||||
|
|
|
||||||
|
LL | foo(VALS_U64); //~ ERROR erroneous constant used
|
||||||
|
| ^^^^^^^^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -25,86 +25,86 @@ fn main() {
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
|
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 };
|
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 };
|
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 };
|
const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
|
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 };
|
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 };
|
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 };
|
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 };
|
const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
|
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 };
|
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 };
|
const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
|
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 };
|
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 };
|
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 };
|
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 };
|
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 };
|
const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
|
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 };
|
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 };
|
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 };
|
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 };
|
const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
|
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 };
|
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 };
|
const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR this constant likely exhibits undefined behavior
|
||||||
|
|
||||||
const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
|
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 };
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,13 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(const_panic)]
|
#![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");
|
pub const Y: () = unreachable!();
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
||||||
const Y: () = unreachable!();
|
pub const X: () = unimplemented!();
|
||||||
//~^ 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
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const_panic.rs:15:1
|
--> $DIR/const_panic.rs:14:1
|
||||||
|
|
|
|
||||||
LL | const Z: () = panic!("cheese");
|
LL | pub const Z: () = panic!("cheese");
|
||||||
| ^^^^^^^^^^^^^^----------------^
|
| ^^^^^^^^^^^^^^^^^^----------------^
|
||||||
| |
|
| |
|
||||||
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:15:15
|
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:14:19
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= 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)
|
= 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.rs:18:1
|
--> $DIR/const_panic.rs:17:1
|
||||||
|
|
|
|
||||||
LL | const Y: () = unreachable!();
|
LL | pub const Y: () = unreachable!();
|
||||||
| ^^^^^^^^^^^^^^--------------^
|
| ^^^^^^^^^^^^^^^^^^--------------^
|
||||||
| |
|
| |
|
||||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:18:15
|
| 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)
|
= 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.rs:21:1
|
--> $DIR/const_panic.rs:20:1
|
||||||
|
|
|
|
||||||
LL | const X: () = unimplemented!();
|
LL | pub const X: () = unimplemented!();
|
||||||
| ^^^^^^^^^^^^^^----------------^
|
| ^^^^^^^^^^^^^^^^^^----------------^
|
||||||
| |
|
| |
|
||||||
| the evaluated program panicked at 'not yet implemented', $DIR/const_panic.rs:21:15
|
| 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)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
#![feature(const_panic)]
|
#![feature(const_panic)]
|
||||||
|
|
||||||
const Z: () = panic!("cheese");
|
const Z: () = panic!("cheese");
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
||||||
const Y: () = unreachable!();
|
const Y: () = unreachable!();
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
||||||
const X: () = unimplemented!();
|
const X: () = unimplemented!();
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
|
@ -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
|
--> $DIR/const_panic_libcore.rs:15:1
|
||||||
|
|
|
|
||||||
LL | const Z: () = panic!("cheese");
|
LL | const Z: () = panic!("cheese");
|
||||||
|
@ -9,7 +9,7 @@ LL | const Z: () = panic!("cheese");
|
||||||
= note: #[deny(const_err)] on by default
|
= 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)
|
= 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
|
--> $DIR/const_panic_libcore.rs:18:1
|
||||||
|
|
|
|
||||||
LL | const Y: () = unreachable!();
|
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)
|
= 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
|
--> $DIR/const_panic_libcore.rs:21:1
|
||||||
|
|
|
|
||||||
LL | const X: () = unimplemented!();
|
LL | const X: () = unimplemented!();
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
const Z: () = panic!("cheese");
|
const Z: () = panic!("cheese");
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
||||||
const Y: () = unreachable!();
|
const Y: () = unreachable!();
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
||||||
const X: () = unimplemented!();
|
const X: () = unimplemented!();
|
||||||
//~^ ERROR this constant cannot be used
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
fn eh() {}
|
fn eh() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const_panic_libcore_main.rs:19:1
|
--> $DIR/const_panic_libcore_main.rs:20:1
|
||||||
|
|
|
|
||||||
LL | const Z: () = panic!("cheese");
|
LL | const Z: () = panic!("cheese");
|
||||||
| ^^^^^^^^^^^^^^----------------^
|
| ^^^^^^^^^^^^^^----------------^
|
||||||
|
@ -9,8 +9,8 @@ LL | const Z: () = panic!("cheese");
|
||||||
= note: #[deny(const_err)] on by default
|
= 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)
|
= 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
|
--> $DIR/const_panic_libcore_main.rs:23:1
|
||||||
|
|
|
|
||||||
LL | const Y: () = unreachable!();
|
LL | const Y: () = unreachable!();
|
||||||
| ^^^^^^^^^^^^^^--------------^
|
| ^^^^^^^^^^^^^^--------------^
|
||||||
|
@ -19,8 +19,8 @@ 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)
|
= 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
|
--> $DIR/const_panic_libcore_main.rs:26:1
|
||||||
|
|
|
|
||||||
LL | const X: () = unimplemented!();
|
LL | const X: () = unimplemented!();
|
||||||
| ^^^^^^^^^^^^^^----------------^
|
| ^^^^^^^^^^^^^^----------------^
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
// unconst and bad, will thus error in miri
|
// 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
|
// unconst and fine
|
||||||
const X2: bool = 42 as *const i32 == 43 as *const i32;
|
const X2: bool = 42 as *const i32 == 43 as *const i32;
|
||||||
// unconst and fine
|
// unconst and fine
|
||||||
const Y: usize = 42usize as *const i32 as usize + 1;
|
const Y: usize = 42usize as *const i32 as usize + 1;
|
||||||
// unconst and bad, will thus error in miri
|
// 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
|
// unconst and fine
|
||||||
const Z: i32 = unsafe { *(&1 as *const i32) };
|
const Z: i32 = unsafe { *(&1 as *const i32) };
|
||||||
// unconst and bad, will thus error in miri
|
// unconst and bad, will thus error in miri
|
||||||
const Z2: i32 = unsafe { *(42 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 cannot be used
|
const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR any use of this value will cause
|
||||||
|
|
|
@ -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
|
--> $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
|
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= 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
|
--> $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
|
| "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
|
--> $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
|
| 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
|
--> $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
|
| a memory access tried to interpret some bytes as a pointer
|
||||||
|
|
|
@ -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
|
--> $DIR/double_check2.rs:25:1
|
||||||
|
|
|
|
||||||
LL | / static FOO: (&Foo, &Bar) = unsafe {( //~ undefined behavior
|
LL | / static FOO: (&Foo, &Bar) = unsafe {( //~ undefined behavior
|
||||||
|
|
|
@ -15,10 +15,10 @@ fn main() {
|
||||||
// The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
|
// The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
|
||||||
let _ = [(); {
|
let _ = [(); {
|
||||||
//~^ WARNING Constant evaluating a complex constant, this might take some time
|
//~^ 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
|
let mut n = 113383; // #20 in https://oeis.org/A006884
|
||||||
while n != 0 { //~ ERROR constant contains unimplemented expression type
|
while n != 0 { //~ ERROR constant contains unimplemented expression type
|
||||||
n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||||
|
//~^ ERROR evaluation of constant value failed
|
||||||
}
|
}
|
||||||
n
|
n
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
error[E0019]: constant contains unimplemented expression type
|
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 | / while n != 0 { //~ ERROR constant contains unimplemented expression type
|
||||||
LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||||
|
LL | | //~^ ERROR evaluation of constant value failed
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
|
@ -12,28 +13,18 @@ warning: Constant evaluating a complex constant, this might take some time
|
||||||
LL | let _ = [(); {
|
LL | let _ = [(); {
|
||||||
| __________________^
|
| __________________^
|
||||||
LL | | //~^ WARNING Constant evaluating a complex constant, this might take some time
|
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 | | let mut n = 113383; // #20 in https://oeis.org/A006884
|
||||||
|
LL | | while n != 0 { //~ ERROR constant contains unimplemented expression type
|
||||||
... |
|
... |
|
||||||
LL | | n
|
LL | | n
|
||||||
LL | | }];
|
LL | | }];
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
||||||
error[E0080]: could not evaluate repeat length
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/infinite_loop.rs:16:18
|
--> $DIR/infinite_loop.rs:20:20
|
||||||
|
|
|
|
||||||
LL | let _ = [(); {
|
LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||||
| __________________^
|
| ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
|
||||||
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 | | }];
|
|
||||||
| |_____^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
43
src/test/ui/consts/const-eval/issue-43197.nll.stderr
Normal file
43
src/test/ui/consts/const-eval/issue-43197.nll.stderr
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
warning: any use of this value will cause an error
|
||||||
|
--> $DIR/issue-43197.rs:20:5
|
||||||
|
|
|
||||||
|
LL | const X: u32 = 0-1;
|
||||||
|
| ^^^^^^^^^^^^^^^---^
|
||||||
|
| |
|
||||||
|
| attempt to subtract with overflow
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/issue-43197.rs:11:9
|
||||||
|
|
|
||||||
|
LL | #![warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
warning: any use of this value will cause an error
|
||||||
|
--> $DIR/issue-43197.rs:22:5
|
||||||
|
|
|
||||||
|
LL | const Y: u32 = foo(0-1);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^---^^
|
||||||
|
| |
|
||||||
|
| attempt to subtract with overflow
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/issue-43197.rs:24:14
|
||||||
|
|
|
||||||
|
LL | println!("{} {}", X, Y);
|
||||||
|
| ^^^^^^^ - referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/issue-43197.rs:24:26
|
||||||
|
|
|
||||||
|
LL | println!("{} {}", X, Y);
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/issue-43197.rs:24:23
|
||||||
|
|
|
||||||
|
LL | println!("{} {}", X, Y);
|
||||||
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
|
@ -16,12 +16,10 @@ const fn foo(x: u32) -> u32 {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const X: u32 = 0-1;
|
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);
|
const Y: u32 = foo(0-1);
|
||||||
//~^ WARN this constant cannot be used
|
//~^ WARN any use of this value will cause
|
||||||
println!("{} {}", X, Y);
|
println!("{} {}", X, Y);
|
||||||
//~^ ERROR erroneous constant used
|
//~^ ERROR evaluation of constant expression failed
|
||||||
//~| ERROR erroneous constant used
|
//~| ERROR evaluation of constant expression failed
|
||||||
//~| ERROR E0080
|
|
||||||
//~| ERROR E0080
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: this constant cannot be used
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/issue-43197.rs:18:5
|
--> $DIR/issue-43197.rs:20:5
|
||||||
|
|
|
|
||||||
LL | const X: u32 = 0-1;
|
LL | const X: u32 = 0-1;
|
||||||
| ^^^^^^^^^^^^^^^---^
|
| ^^^^^^^^^^^^^^^---^
|
||||||
|
@ -12,44 +12,26 @@ note: lint level defined here
|
||||||
LL | #![warn(const_err)]
|
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
|
--> $DIR/issue-43197.rs:22:5
|
||||||
|
|
|
|
||||||
LL | const Y: u32 = foo(0-1);
|
LL | const Y: u32 = foo(0-1);
|
||||||
| ^^^^^^^^^^^^^^^^^^^---^^
|
| ^^^^^^^^^^^^^^^^^^^---^^
|
||||||
| |
|
| |
|
||||||
| attempt to subtract with overflow
|
| attempt to subtract with overflow
|
||||||
|
|
||||||
error[E0080]: referenced constant has errors
|
error[E0080]: evaluation of constant expression failed
|
||||||
--> $DIR/issue-43197.rs:22:26
|
--> $DIR/issue-43197.rs:24: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
|
|
||||||
--> $DIR/issue-43197.rs:22:26
|
|
||||||
|
|
|
|
||||||
LL | println!("{} {}", X, Y);
|
LL | println!("{} {}", X, Y);
|
||||||
| ^ referenced constant has errors
|
| ^ referenced constant has errors
|
||||||
|
|
||||||
error[E0080]: referenced constant has errors
|
error[E0080]: evaluation of constant expression failed
|
||||||
--> $DIR/issue-43197.rs:22:23
|
--> $DIR/issue-43197.rs:24:23
|
||||||
|
|
|
||||||
LL | const X: u32 = 0-1;
|
|
||||||
| --- attempt to subtract with overflow
|
|
||||||
...
|
|
||||||
LL | println!("{} {}", X, Y);
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error[E0080]: erroneous constant used
|
|
||||||
--> $DIR/issue-43197.rs:22:23
|
|
||||||
|
|
|
|
||||||
LL | println!("{} {}", X, Y);
|
LL | println!("{} {}", X, Y);
|
||||||
| ^ referenced constant has errors
|
| ^ 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`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
15
src/test/ui/consts/const-eval/issue-44578.nll.stderr
Normal file
15
src/test/ui/consts/const-eval/issue-44578.nll.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/issue-44578.rs:35:14
|
||||||
|
|
|
||||||
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
|
||||||
|
| ^^^^ -------------------------- referenced constant has errors
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
|
@ -33,6 +33,5 @@ impl Foo for u16 {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{}", <Bar<u16, u8> as Foo>::AMT);
|
println!("{}", <Bar<u16, u8> as Foo>::AMT);
|
||||||
//~^ ERROR erroneous constant used
|
//~^ ERROR E0080
|
||||||
//~| ERROR E0080
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
error[E0080]: referenced constant has errors
|
error[E0080]: evaluation of constant expression failed
|
||||||
--> $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
|
|
||||||
--> $DIR/issue-44578.rs:35:20
|
--> $DIR/issue-44578.rs:35:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -19,12 +19,11 @@ trait Foo<T> {
|
||||||
struct A<T>(T);
|
struct A<T>(T);
|
||||||
|
|
||||||
impl<T: C> Foo<T> for A<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 {
|
fn foo<T: C>() -> &'static usize {
|
||||||
&<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
|
&<A<T> as Foo<T>>::BAR //~ ERROR E0080
|
||||||
//~| ERROR E0080
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl C for () {
|
impl C for () {
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
error[E0080]: referenced constant has errors
|
error: any use of this value will cause an error
|
||||||
--> $DIR/issue-50814-2.rs:26:5
|
--> $DIR/issue-50814-2.rs:22:5
|
||||||
|
|
|
|
||||||
LL | const BAR: usize = [5, 6, 7][T::BOO];
|
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
|
| ^^^^^^^^^^^^^^^^^^^-----------------^
|
||||||
...
|
| |
|
||||||
LL | &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
|
| 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
|
--> $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
|
| referenced constant has errors
|
||||||
|
|
|
@ -20,12 +20,11 @@ impl Unsigned for U8 {
|
||||||
struct Sum<A,B>(A,B);
|
struct Sum<A,B>(A,B);
|
||||||
|
|
||||||
impl<A: Unsigned, B: Unsigned> Unsigned for Sum<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 {
|
fn foo<T>(_: T) -> &'static u8 {
|
||||||
&Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
|
&Sum::<U8,U8>::MAX //~ ERROR E0080
|
||||||
//~| ERROR E0080
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
error[E0080]: referenced constant has errors
|
error: any use of this value will cause an error
|
||||||
--> $DIR/issue-50814.rs:27:5
|
--> $DIR/issue-50814.rs:23:5
|
||||||
|
|
|
|
||||||
LL | const MAX: u8 = A::MAX + B::MAX;
|
LL | const MAX: u8 = A::MAX + B::MAX; //~ ERROR any use of this value will cause an error
|
||||||
| --------------- attempt to add with overflow
|
| ^^^^^^^^^^^^^^^^---------------^
|
||||||
...
|
| |
|
||||||
LL | &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
|
| 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
|
--> $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
|
| referenced constant has errors
|
||||||
|
|
49
src/test/ui/consts/const-eval/issue-52443.stderr
Normal file
49
src/test/ui/consts/const-eval/issue-52443.stderr
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-52443.rs:12:10
|
||||||
|
|
|
||||||
|
LL | [(); & { loop { continue } } ]; //~ ERROR mismatched types
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected usize, found reference
|
||||||
|
| help: consider removing the borrow: `{ loop { continue } }`
|
||||||
|
|
|
||||||
|
= note: expected type `usize`
|
||||||
|
found type `&_`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-52443.rs:13:17
|
||||||
|
|
|
||||||
|
LL | [(); loop { break }]; //~ ERROR mismatched types
|
||||||
|
| ^^^^^ expected (), found usize
|
||||||
|
|
|
||||||
|
= note: expected type `()`
|
||||||
|
found type `usize`
|
||||||
|
|
||||||
|
error[E0019]: constant contains unimplemented expression type
|
||||||
|
--> $DIR/issue-52443.rs:14:11
|
||||||
|
|
|
||||||
|
LL | [(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
|
--> $DIR/issue-52443.rs:15:21
|
||||||
|
|
|
||||||
|
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error[E0019]: constant contains unimplemented expression type
|
||||||
|
--> $DIR/issue-52443.rs:15:21
|
||||||
|
|
|
||||||
|
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/issue-52443.rs:15:21
|
||||||
|
|
|
||||||
|
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
||||||
|
| ^^^^^^^^ calling non-const fn `<I as std::iter::IntoIterator><std::ops::RangeFrom<usize>>::into_iter`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
Some errors occurred: E0015, E0019, E0080, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0015`.
|
|
@ -12,10 +12,11 @@ fn main() {
|
||||||
// Make sure match uses the usual pointer comparison code path -- i.e., it should complain
|
// 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
|
// that pointer comparison is disallowed, not that parts of a pointer are accessed as raw
|
||||||
// bytes.
|
// 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
|
match &1 as *const i32 as usize { //~ ERROR casting pointers to integers in constants
|
||||||
0 => 42, //~ ERROR constant contains unimplemented expression type
|
0 => 42, //~ ERROR constant contains unimplemented expression type
|
||||||
//~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed
|
//~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed
|
||||||
|
//~| ERROR evaluation of constant value failed
|
||||||
n => n,
|
n => n,
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -12,19 +12,11 @@ error[E0019]: constant contains unimplemented expression type
|
||||||
LL | 0 => 42, //~ ERROR constant contains unimplemented expression type
|
LL | 0 => 42, //~ ERROR constant contains unimplemented expression type
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error[E0080]: could not evaluate repeat length
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/match-test-ptr-null.rs:15:26
|
--> $DIR/match-test-ptr-null.rs:17:13
|
||||||
|
|
|
|
||||||
LL | let _: [u8; 0] = [4; { //~ ERROR could not evaluate repeat length
|
LL | 0 => 42, //~ ERROR constant contains unimplemented expression type
|
||||||
| __________________________^
|
| ^ "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
||||||
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 | | }];
|
|
||||||
| |_____^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#![feature(const_fn, const_fn_union)]
|
#![feature(const_fn, const_fn_union)]
|
||||||
|
|
||||||
#![deny(const_err)]
|
#![allow(const_err)]
|
||||||
|
|
||||||
union Bar {
|
union Bar {
|
||||||
a: &'static u8,
|
a: &'static u8,
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
// 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() {
|
||||||
|
// FIXME(oli-obk): this should panic at runtime
|
||||||
|
// this will actually compile, but then
|
||||||
|
// abort at runtime (not panic, hard abort).
|
||||||
|
let x: &'static u8 = &(bar() + 1);
|
||||||
|
let y = *x;
|
||||||
|
unreachable!();
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
error: reaching this expression at runtime will panic or abort
|
||||||
|
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:33:26
|
||||||
|
|
|
||||||
|
LL | Bar { a: &42 }.b as u8
|
||||||
|
| ---------------------- a raw memory access tried to access part of a pointer value as raw bytes
|
||||||
|
...
|
||||||
|
LL | let x: &'static u8 = &(bar() + 1);
|
||||||
|
| ^^-----^^^^^
|
||||||
|
| |
|
||||||
|
| inside call to `bar`
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:13:9
|
||||||
|
|
|
||||||
|
LL | #![deny(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -46,3 +46,15 @@ warning: this expression will panic at runtime
|
||||||
LL | let _x = 1/(false as u32);
|
LL | let _x = 1/(false as u32);
|
||||||
| ^^^^^^^^^^^^^^^^ attempt to divide by zero
|
| ^^^^^^^^^^^^^^^^ 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
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
pub const Z: u32 = 0 - 1;
|
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];
|
pub type Foo = [i32; 0 - 1];
|
||||||
//~^ WARN attempt to subtract with overflow
|
//~^ WARN attempt to subtract with overflow
|
||||||
|
|
|
@ -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
|
--> $DIR/pub_const_err.rs:16:1
|
||||||
|
|
|
|
||||||
LL | pub const Z: u32 = 0 - 1;
|
LL | pub const Z: u32 = 0 - 1;
|
||||||
|
@ -12,15 +12,3 @@ note: lint level defined here
|
||||||
LL | #![warn(const_err)]
|
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
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#![warn(const_err)]
|
#![warn(const_err)]
|
||||||
|
|
||||||
pub const Z: u32 = 0 - 1;
|
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];
|
pub type Foo = [i32; 0 - 1];
|
||||||
//~^ WARN attempt to subtract with overflow
|
//~^ WARN attempt to subtract with overflow
|
||||||
|
|
|
@ -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
|
--> $DIR/pub_const_err_bin.rs:14:1
|
||||||
|
|
|
|
||||||
LL | pub const Z: u32 = 0 - 1;
|
LL | pub const Z: u32 = 0 - 1;
|
||||||
|
@ -12,15 +12,3 @@ note: lint level defined here
|
||||||
LL | #![warn(const_err)]
|
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
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0080]: could not evaluate enum discriminant
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/shift_overflow.rs:13:9
|
--> $DIR/shift_overflow.rs:13:9
|
||||||
|
|
|
|
||||||
LL | X = 1 << ((u32::max_value() as u64) + 1), //~ ERROR E0080
|
LL | X = 1 << ((u32::max_value() as u64) + 1), //~ ERROR E0080
|
||||||
|
|
|
@ -20,7 +20,7 @@ union TransmuteEnum {
|
||||||
|
|
||||||
// A pointer is guaranteed non-null
|
// A pointer is guaranteed non-null
|
||||||
const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
|
const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
|
||||||
//~^ ERROR this constant likely exhibits undefined behavior
|
//~^ ERROR is undefined behavior
|
||||||
|
|
||||||
// Invalid enum discriminant
|
// Invalid enum discriminant
|
||||||
#[repr(usize)]
|
#[repr(usize)]
|
||||||
|
@ -33,7 +33,7 @@ union TransmuteEnum2 {
|
||||||
b: Enum2,
|
b: Enum2,
|
||||||
}
|
}
|
||||||
const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
|
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
|
// Invalid enum field content (mostly to test printing of apths for enum tuple
|
||||||
// variants and tuples).
|
// variants and tuples).
|
||||||
|
@ -43,7 +43,7 @@ union TransmuteChar {
|
||||||
}
|
}
|
||||||
// Need to create something which does not clash with enum layout optimizations.
|
// 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 }));
|
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() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/ub-enum.rs:22:1
|
||||||
|
|
|
|
||||||
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
|
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
|
= 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
|
--> $DIR/ub-enum.rs:35:1
|
||||||
|
|
|
|
||||||
LL | const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
|
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
|
= 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
|
--> $DIR/ub-enum.rs:45:1
|
||||||
|
|
|
|
||||||
LL | const BAD_ENUM_CHAR : Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
|
LL | const BAD_ENUM_CHAR : Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
|
||||||
|
|
|
@ -34,12 +34,15 @@ const fn read_field2() -> Field2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn read_field3() -> Field3 {
|
const fn read_field3() -> Field3 {
|
||||||
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR cannot be used
|
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value
|
||||||
|
//~^ ERROR any use of this value
|
||||||
FIELD3
|
FIELD3
|
||||||
|
//~^ erroneous constant used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(read_field1(), FLOAT1_AS_I32);
|
assert_eq!(read_field1(), FLOAT1_AS_I32);
|
||||||
assert_eq!(read_field2(), 1.0);
|
assert_eq!(read_field2(), 1.0);
|
||||||
assert_eq!(read_field3(), unsafe { UNION.field3 });
|
assert_eq!(read_field3(), unsafe { UNION.field3 });
|
||||||
|
//~^ ERROR evaluation of constant expression failed
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,36 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/union-const-eval-field.rs:37:5
|
--> $DIR/union-const-eval-field.rs:37:5
|
||||||
|
|
|
|
||||||
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR cannot be used
|
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= note: #[deny(const_err)] on by default
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: any use of this value will cause an error
|
||||||
|
--> $DIR/union-const-eval-field.rs:37:5
|
||||||
|
|
|
||||||
|
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
|
||||||
|
|
||||||
|
error[E0080]: erroneous constant used
|
||||||
|
--> $DIR/union-const-eval-field.rs:39:5
|
||||||
|
|
|
||||||
|
LL | FIELD3
|
||||||
|
| ^^^^^^ referenced constant has errors
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant expression failed
|
||||||
|
--> $DIR/union-const-eval-field.rs:46:5
|
||||||
|
|
|
||||||
|
LL | FIELD3
|
||||||
|
| ------ referenced constant has errors
|
||||||
|
...
|
||||||
|
LL | assert_eq!(read_field3(), unsafe { UNION.field3 });
|
||||||
|
| ^^^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| inside call to `read_field3`
|
||||||
|
|
|
||||||
|
= 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: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -20,9 +20,9 @@ union DummyUnion {
|
||||||
|
|
||||||
const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
|
const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
|
||||||
|
|
||||||
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant cannot be used
|
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error
|
||||||
|
|
||||||
const FIELD_PATH: Struct = Struct { //~ ERROR this constant likely exhibits undefined behavior
|
const FIELD_PATH: Struct = Struct { //~ ERROR any use of this value will cause an error
|
||||||
a: 42,
|
a: 42,
|
||||||
b: unsafe { UNION.field3 },
|
b: unsafe { UNION.field3 },
|
||||||
};
|
};
|
||||||
|
@ -32,7 +32,7 @@ struct Struct {
|
||||||
b: Field3,
|
b: Field3,
|
||||||
}
|
}
|
||||||
|
|
||||||
const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR this constant likely exhibits undefined behavior
|
const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR it is undefined behavior to use this value
|
||||||
b: [
|
b: [
|
||||||
21,
|
21,
|
||||||
unsafe { UNION.field3 },
|
unsafe { UNION.field3 },
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
error: this constant cannot be used
|
error: any use of this value will cause an error
|
||||||
--> $DIR/union-ice.rs:23:1
|
--> $DIR/union-ice.rs:23:1
|
||||||
|
|
|
|
||||||
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant cannot be used
|
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= note: #[deny(const_err)] on by default
|
||||||
|
|
||||||
error[E0080]: this constant likely exhibits undefined behavior
|
error: any use of this value will cause an error
|
||||||
--> $DIR/union-ice.rs:25:1
|
--> $DIR/union-ice.rs:25:1
|
||||||
|
|
|
|
||||||
LL | / const FIELD_PATH: Struct = Struct { //~ ERROR this constant likely exhibits undefined behavior
|
LL | / const FIELD_PATH: Struct = Struct { //~ ERROR any use of this value will cause an error
|
||||||
LL | | a: 42,
|
LL | | a: 42,
|
||||||
LL | | b: unsafe { UNION.field3 },
|
LL | | b: unsafe { UNION.field3 },
|
||||||
LL | | };
|
LL | | };
|
||||||
|
@ -17,10 +17,10 @@ LL | | };
|
||||||
|
|
|
|
||||||
= 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
|
= 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/union-ice.rs:35:1
|
--> $DIR/union-ice.rs:35:1
|
||||||
|
|
|
|
||||||
LL | / const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR this constant likely exhibits undefined behavior
|
LL | / const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR it is undefined behavior to use this value
|
||||||
LL | | b: [
|
LL | | b: [
|
||||||
LL | | 21,
|
LL | | 21,
|
||||||
LL | | unsafe { UNION.field3 },
|
LL | | unsafe { UNION.field3 },
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue