Rollup merge of #51636 - oli-obk:const_diagnostics, r=eddyb
Refactor error reporting of constants cc @eddyb This PR should not change any behaviour. It solely simplifies the internal handling of the errors
This commit is contained in:
commit
57aceeecc0
60 changed files with 490 additions and 791 deletions
|
|
@ -60,7 +60,7 @@
|
|||
//! user of the `DepNode` API of having to know how to compute the expected
|
||||
//! fingerprint for a given set of node parameters.
|
||||
|
||||
use mir::interpret::{GlobalId, ConstValue};
|
||||
use mir::interpret::GlobalId;
|
||||
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use hir::map::DefPathHash;
|
||||
use hir::{HirId, ItemLocalId};
|
||||
|
|
@ -75,7 +75,7 @@ use traits::query::{
|
|||
CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
|
||||
};
|
||||
use ty::{TyCtxt, FnSig, Instance, InstanceDef,
|
||||
ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty};
|
||||
ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty, self};
|
||||
use ty::subst::Substs;
|
||||
|
||||
// erase!() just makes tokens go away. It's used to specify which macro argument
|
||||
|
|
@ -632,7 +632,7 @@ define_dep_nodes!( <'tcx>
|
|||
// queries). Making them anonymous avoids hashing the result, which
|
||||
// may save a bit of time.
|
||||
[anon] EraseRegionsTy { ty: Ty<'tcx> },
|
||||
[anon] ConstValueToAllocation { val: ConstValue<'tcx>, ty: Ty<'tcx> },
|
||||
[anon] ConstValueToAllocation { val: &'tcx ty::Const<'tcx> },
|
||||
|
||||
[input] Freevars(DefId),
|
||||
[input] MaybeUnusedTraitImport(DefId),
|
||||
|
|
|
|||
|
|
@ -363,27 +363,6 @@ impl_stable_hash_for!(struct ty::FieldDef {
|
|||
vis,
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
for ::middle::const_val::ConstVal<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
use middle::const_val::ConstVal::*;
|
||||
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
Unevaluated(def_id, substs) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
}
|
||||
Value(ref value) => {
|
||||
value.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
for ::mir::interpret::ConstValue<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
|
|
@ -394,6 +373,10 @@ for ::mir::interpret::ConstValue<'gcx> {
|
|||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
Unevaluated(def_id, substs) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
}
|
||||
Scalar(val) => {
|
||||
val.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
|
@ -497,40 +480,18 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
|
|||
val
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> {
|
||||
impl_stable_hash_for!(struct ::mir::interpret::ConstEvalErr<'tcx> {
|
||||
span,
|
||||
kind
|
||||
stacktrace,
|
||||
error
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::const_val::FrameInfo {
|
||||
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
|
||||
span,
|
||||
lint_root,
|
||||
location
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
for ::middle::const_val::ErrKind<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
use middle::const_val::ErrKind::*;
|
||||
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
TypeckError |
|
||||
CouldNotResolve |
|
||||
CheckMatchError => {
|
||||
// nothing to do
|
||||
}
|
||||
Miri(ref err, ref trace) => {
|
||||
err.hash_stable(hcx, hasher);
|
||||
trace.hash_stable(hcx, hasher);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
|
||||
impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
|
||||
|
||||
|
|
@ -579,6 +540,8 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
|||
ReadFromReturnPointer |
|
||||
UnimplementedTraitSelection |
|
||||
TypeckError |
|
||||
TooGeneric |
|
||||
CheckMatchError |
|
||||
DerefFunctionPointer |
|
||||
ExecuteMemory |
|
||||
OverflowNeg |
|
||||
|
|
|
|||
|
|
@ -132,7 +132,6 @@ pub mod middle {
|
|||
pub mod allocator;
|
||||
pub mod borrowck;
|
||||
pub mod expr_use_visitor;
|
||||
pub mod const_val;
|
||||
pub mod cstore;
|
||||
pub mod dataflow;
|
||||
pub mod dead;
|
||||
|
|
|
|||
|
|
@ -1,178 +0,0 @@
|
|||
// Copyright 2012-2016 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.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty;
|
||||
use ty::subst::Substs;
|
||||
use ty::query::TyCtxtAt;
|
||||
use mir::interpret::ConstValue;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
use graphviz::IntoCow;
|
||||
use syntax_pos::Span;
|
||||
use syntax::ast;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum ConstVal<'tcx> {
|
||||
Unevaluated(DefId, &'tcx Substs<'tcx>),
|
||||
Value(ConstValue<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct ConstEvalErr<'tcx> {
|
||||
pub span: Span,
|
||||
pub kind: Lrc<ErrKind<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum ErrKind<'tcx> {
|
||||
|
||||
CouldNotResolve,
|
||||
TypeckError,
|
||||
CheckMatchError,
|
||||
Miri(::mir::interpret::EvalError<'tcx>, Vec<FrameInfo>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct FrameInfo {
|
||||
pub span: Span,
|
||||
pub location: String,
|
||||
pub lint_root: Option<ast::NodeId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ConstEvalErrDescription<'a, 'tcx: 'a> {
|
||||
Simple(Cow<'a, str>),
|
||||
Backtrace(&'a ::mir::interpret::EvalError<'tcx>, &'a [FrameInfo]),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ConstEvalErrDescription<'a, 'tcx> {
|
||||
/// Return a one-line description of the error, for lints and such
|
||||
pub fn into_oneline(self) -> Cow<'a, str> {
|
||||
match self {
|
||||
ConstEvalErrDescription::Simple(simple) => simple,
|
||||
ConstEvalErrDescription::Backtrace(miri, _) => format!("{}", miri).into_cow(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
pub fn description(&'a self) -> ConstEvalErrDescription<'a, 'tcx> {
|
||||
use self::ErrKind::*;
|
||||
use self::ConstEvalErrDescription::*;
|
||||
|
||||
macro_rules! simple {
|
||||
($msg:expr) => ({ Simple($msg.into_cow()) });
|
||||
($fmt:expr, $($arg:tt)+) => ({
|
||||
Simple(format!($fmt, $($arg)+).into_cow())
|
||||
})
|
||||
}
|
||||
|
||||
match *self.kind {
|
||||
CouldNotResolve => simple!("could not resolve"),
|
||||
TypeckError => simple!("type-checking failed"),
|
||||
CheckMatchError => simple!("match-checking failed"),
|
||||
Miri(ref err, ref trace) => Backtrace(err, trace),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_error(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str)
|
||||
-> Option<DiagnosticBuilder<'tcx>>
|
||||
{
|
||||
self.struct_generic(tcx, message, None, true)
|
||||
}
|
||||
|
||||
pub fn report_as_error(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str
|
||||
) {
|
||||
let err = self.struct_generic(tcx, message, None, true);
|
||||
if let Some(mut err) = err {
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_as_lint(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str,
|
||||
lint_root: ast::NodeId,
|
||||
) {
|
||||
let lint = self.struct_generic(
|
||||
tcx,
|
||||
message,
|
||||
Some(lint_root),
|
||||
false,
|
||||
);
|
||||
if let Some(mut lint) = lint {
|
||||
lint.emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_generic(
|
||||
&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str,
|
||||
lint_root: Option<ast::NodeId>,
|
||||
as_err: bool,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
let (msg, frames): (_, &[_]) = match *self.kind {
|
||||
ErrKind::TypeckError | ErrKind::CheckMatchError => return None,
|
||||
ErrKind::Miri(ref miri, ref frames) => {
|
||||
match miri.kind {
|
||||
::mir::interpret::EvalErrorKind::TypeckError |
|
||||
::mir::interpret::EvalErrorKind::Layout(_) => return None,
|
||||
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
|
||||
inner.struct_generic(tcx, "referenced constant", lint_root, as_err)?.emit();
|
||||
(miri.to_string(), frames)
|
||||
},
|
||||
_ => (miri.to_string(), frames),
|
||||
}
|
||||
}
|
||||
_ => (self.description().into_oneline().to_string(), &[]),
|
||||
};
|
||||
trace!("reporting const eval failure at {:?}", self.span);
|
||||
let mut err = if as_err {
|
||||
struct_error(tcx, message)
|
||||
} else {
|
||||
let node_id = frames
|
||||
.iter()
|
||||
.rev()
|
||||
.filter_map(|frame| frame.lint_root)
|
||||
.next()
|
||||
.or(lint_root)
|
||||
.expect("some part of a failing const eval must be local");
|
||||
tcx.struct_span_lint_node(
|
||||
::rustc::lint::builtin::CONST_ERR,
|
||||
node_id,
|
||||
tcx.span,
|
||||
message,
|
||||
)
|
||||
};
|
||||
err.span_label(self.span, msg);
|
||||
for FrameInfo { span, location, .. } in frames {
|
||||
err.span_label(*span, format!("inside call to `{}`", location));
|
||||
}
|
||||
Some(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_error<'a, 'gcx, 'tcx>(
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
msg: &str,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
use std::{fmt, env};
|
||||
|
||||
use mir;
|
||||
use middle::const_val::ConstEvalErr;
|
||||
use ty::{FnSig, Ty, layout};
|
||||
use ty::layout::{Size, Align};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
use super::{
|
||||
Pointer, Lock, AccessKind
|
||||
|
|
@ -11,6 +11,111 @@ use super::{
|
|||
|
||||
use backtrace::Backtrace;
|
||||
|
||||
use ty;
|
||||
use ty::query::TyCtxtAt;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
use syntax_pos::Span;
|
||||
use syntax::ast;
|
||||
|
||||
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>;
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct ConstEvalErr<'tcx> {
|
||||
pub span: Span,
|
||||
pub error: ::mir::interpret::EvalError<'tcx>,
|
||||
pub stacktrace: Vec<FrameInfo>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct FrameInfo {
|
||||
pub span: Span,
|
||||
pub location: String,
|
||||
pub lint_root: Option<ast::NodeId>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
pub fn struct_error(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str)
|
||||
-> Option<DiagnosticBuilder<'tcx>>
|
||||
{
|
||||
self.struct_generic(tcx, message, None)
|
||||
}
|
||||
|
||||
pub fn report_as_error(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str
|
||||
) {
|
||||
let err = self.struct_generic(tcx, message, None);
|
||||
if let Some(mut err) = err {
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_as_lint(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str,
|
||||
lint_root: ast::NodeId,
|
||||
) {
|
||||
let lint = self.struct_generic(
|
||||
tcx,
|
||||
message,
|
||||
Some(lint_root),
|
||||
);
|
||||
if let Some(mut lint) = lint {
|
||||
lint.emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_generic(
|
||||
&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str,
|
||||
lint_root: Option<ast::NodeId>,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
match self.error.kind {
|
||||
::mir::interpret::EvalErrorKind::TypeckError |
|
||||
::mir::interpret::EvalErrorKind::TooGeneric |
|
||||
::mir::interpret::EvalErrorKind::CheckMatchError |
|
||||
::mir::interpret::EvalErrorKind::Layout(_) => return None,
|
||||
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
|
||||
inner.struct_generic(tcx, "referenced constant has errors", lint_root)?.emit();
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
trace!("reporting const eval failure at {:?}", self.span);
|
||||
let mut err = if let Some(lint_root) = lint_root {
|
||||
let node_id = self.stacktrace
|
||||
.iter()
|
||||
.rev()
|
||||
.filter_map(|frame| frame.lint_root)
|
||||
.next()
|
||||
.unwrap_or(lint_root);
|
||||
tcx.struct_span_lint_node(
|
||||
::rustc::lint::builtin::CONST_ERR,
|
||||
node_id,
|
||||
tcx.span,
|
||||
message,
|
||||
)
|
||||
} else {
|
||||
struct_error(tcx, message)
|
||||
};
|
||||
err.span_label(self.span, self.error.to_string());
|
||||
for FrameInfo { span, location, .. } in &self.stacktrace {
|
||||
err.span_label(*span, format!("inside call to `{}`", location));
|
||||
}
|
||||
Some(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_error<'a, 'gcx, 'tcx>(
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
msg: &str,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
|
||||
pub struct EvalError<'tcx> {
|
||||
pub kind: EvalErrorKind<'tcx, u64>,
|
||||
|
|
@ -150,9 +255,12 @@ pub enum EvalErrorKind<'tcx, O> {
|
|||
UnimplementedTraitSelection,
|
||||
/// Abort in case type errors are reached
|
||||
TypeckError,
|
||||
/// Resolution can fail if we are in a too generic context
|
||||
TooGeneric,
|
||||
CheckMatchError,
|
||||
/// Cannot compute this constant because it depends on another one
|
||||
/// which already produced an error
|
||||
ReferencedConstant(ConstEvalErr<'tcx>),
|
||||
ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
|
||||
GeneratorResumedAfterReturn,
|
||||
GeneratorResumedAfterPanic,
|
||||
}
|
||||
|
|
@ -268,6 +376,10 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
|
|||
"there were unresolved type arguments during trait selection",
|
||||
TypeckError =>
|
||||
"encountered constants with type errors, stopping evaluation",
|
||||
TooGeneric =>
|
||||
"encountered overly generic constant",
|
||||
CheckMatchError =>
|
||||
"match checking failed",
|
||||
ReferencedConstant(_) =>
|
||||
"referenced constant has errors",
|
||||
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ macro_rules! err {
|
|||
mod error;
|
||||
mod value;
|
||||
|
||||
pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
|
||||
pub use self::error::{
|
||||
EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
|
||||
FrameInfo, ConstEvalResult,
|
||||
};
|
||||
|
||||
pub use self::value::{Scalar, Value, ConstValue};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,19 @@
|
|||
|
||||
use ty::layout::{Align, HasDataLayout, Size};
|
||||
use ty;
|
||||
use ty::subst::Substs;
|
||||
use hir::def_id::DefId;
|
||||
|
||||
use super::{EvalResult, Pointer, PointerArithmetic, Allocation};
|
||||
|
||||
/// Represents a constant value in Rust. ByVal and ScalarPair are optimizations which
|
||||
/// matches Value's optimizations for easy conversions between these two types
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub enum ConstValue<'tcx> {
|
||||
/// Never returned from the `const_eval` query, but the HIR contains these frequently in order
|
||||
/// to allow HIR creation to happen for everything before needing to be able to run constant
|
||||
/// evaluation
|
||||
Unevaluated(DefId, &'tcx Substs<'tcx>),
|
||||
/// Used only for types with layout::abi::Scalar ABI and ZSTs which use Scalar::undef()
|
||||
Scalar(Scalar),
|
||||
/// Used only for types with layout::abi::ScalarPair
|
||||
|
|
@ -30,6 +36,7 @@ impl<'tcx> ConstValue<'tcx> {
|
|||
#[inline]
|
||||
pub fn to_byval_value(&self) -> Option<Value> {
|
||||
match *self {
|
||||
ConstValue::Unevaluated(..) |
|
||||
ConstValue::ByRef(..) => None,
|
||||
ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a, b)),
|
||||
ConstValue::Scalar(val) => Some(Value::Scalar(val)),
|
||||
|
|
@ -44,7 +51,8 @@ impl<'tcx> ConstValue<'tcx> {
|
|||
#[inline]
|
||||
pub fn to_scalar(&self) -> Option<Scalar> {
|
||||
match *self {
|
||||
ConstValue::ByRef(..) => None,
|
||||
ConstValue::Unevaluated(..) |
|
||||
ConstValue::ByRef(..) |
|
||||
ConstValue::ScalarPair(..) => None,
|
||||
ConstValue::Scalar(val) => Some(val),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2162,18 +2162,12 @@ impl<'tcx> Debug for Literal<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Write a `ConstVal` in a way closer to the original source code than the `Debug` output.
|
||||
/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
|
||||
pub fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ty::Const) -> fmt::Result {
|
||||
use middle::const_val::ConstVal;
|
||||
match const_val.val {
|
||||
ConstVal::Unevaluated(..) => write!(fmt, "{:?}", const_val),
|
||||
ConstVal::Value(val) => {
|
||||
if let Some(value) = val.to_byval_value() {
|
||||
print_miri_value(value, const_val.ty, fmt)
|
||||
} else {
|
||||
write!(fmt, "{:?}:{}", val, const_val.ty)
|
||||
}
|
||||
}
|
||||
if let Some(value) = const_val.to_byval_value() {
|
||||
print_miri_value(value, const_val.ty, fmt)
|
||||
} else {
|
||||
write!(fmt, "{:?}:{}", const_val.val, const_val.ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ use rustc_data_structures::obligation_forest::{Error, ForestObligation, Obligati
|
|||
use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
|
||||
use std::marker::PhantomData;
|
||||
use hir::def_id::DefId;
|
||||
use middle::const_val::{ConstEvalErr, ErrKind};
|
||||
use mir::interpret::ConstEvalErr;
|
||||
use mir::interpret::EvalErrorKind;
|
||||
|
||||
use super::CodeAmbiguity;
|
||||
use super::CodeProjectionError;
|
||||
|
|
@ -501,8 +502,9 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
|||
ProcessResult::Error(
|
||||
CodeSelectionError(ConstEvalFailure(ConstEvalErr {
|
||||
span: obligation.cause.span,
|
||||
kind: ErrKind::CouldNotResolve.into(),
|
||||
}))
|
||||
error: EvalErrorKind::TooGeneric.into(),
|
||||
stacktrace: vec![],
|
||||
}.into()))
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use hir;
|
|||
use hir::def_id::DefId;
|
||||
use infer::outlives::env::OutlivesEnvironment;
|
||||
use middle::region;
|
||||
use middle::const_val::ConstEvalErr;
|
||||
use mir::interpret::ConstEvalErr;
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, AdtKind, Slice, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
|
||||
use ty::error::{ExpectedFound, TypeError};
|
||||
|
|
@ -381,7 +381,7 @@ pub enum SelectionError<'tcx> {
|
|||
ty::PolyTraitRef<'tcx>,
|
||||
ty::error::TypeError<'tcx>),
|
||||
TraitNotObjectSafe(DefId),
|
||||
ConstEvalFailure(ConstEvalErr<'tcx>),
|
||||
ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
|
||||
Overflow,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use super::util;
|
|||
use hir::def_id::DefId;
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use infer::type_variable::TypeVariableOrigin;
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use mir::interpret::{GlobalId};
|
||||
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
|
||||
use syntax::ast::Ident;
|
||||
|
|
@ -426,7 +426,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
|
|||
}
|
||||
|
||||
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
|
||||
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
|
||||
let tcx = self.selcx.tcx().global_tcx();
|
||||
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
|
||||
if substs.needs_infer() || substs.has_skol() {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@
|
|||
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use infer::at::At;
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::GlobalId;
|
||||
use mir::interpret::{GlobalId, ConstValue};
|
||||
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
|
||||
use traits::project::Normalized;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
|
|
@ -195,7 +194,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
|
|||
}
|
||||
|
||||
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
|
||||
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
|
||||
let tcx = self.infcx.tcx.global_tcx();
|
||||
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
|
||||
if substs.needs_infer() || substs.has_skol() {
|
||||
|
|
|
|||
|
|
@ -172,7 +172,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
|
|||
})
|
||||
}
|
||||
super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
|
||||
super::ConstEvalFailure(ref err) => tcx.lift(err).map(super::ConstEvalFailure),
|
||||
super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
|
||||
err.into(),
|
||||
)),
|
||||
super::Overflow => bug!(), // FIXME: ape ConstEvalFailure?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, Ty, TypeFlags, TypeFoldable};
|
||||
|
||||
|
|
@ -233,12 +233,9 @@ impl FlagComputation {
|
|||
|
||||
fn add_const(&mut self, constant: &ty::Const) {
|
||||
self.add_ty(constant.ty);
|
||||
match constant.val {
|
||||
ConstVal::Value(_) => {}
|
||||
ConstVal::Unevaluated(_, substs) => {
|
||||
self.add_flags(TypeFlags::HAS_PROJECTION);
|
||||
self.add_substs(substs);
|
||||
}
|
||||
if let ConstValue::Unevaluated(_, substs) = constant.val {
|
||||
self.add_flags(TypeFlags::HAS_PROJECTION);
|
||||
self.add_substs(substs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
//! These methods return true to indicate that the visitor has found what it is looking for
|
||||
//! and does not need to visit anything else.
|
||||
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use hir::def_id::DefId;
|
||||
use ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||
|
||||
|
|
@ -685,7 +685,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
|
|||
}
|
||||
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
|
||||
if let ConstVal::Unevaluated(..) = c.val {
|
||||
if let ConstValue::Unevaluated(..) = c.val {
|
||||
let projection_flags = TypeFlags::HAS_NORMALIZABLE_PROJECTION |
|
||||
TypeFlags::HAS_PROJECTION;
|
||||
if projection_flags.intersects(self.flags) {
|
||||
|
|
|
|||
|
|
@ -2065,7 +2065,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
|||
})
|
||||
} else {
|
||||
info!("invalid enum discriminant: {:#?}", val);
|
||||
::middle::const_val::struct_error(
|
||||
::mir::interpret::struct_error(
|
||||
tcx.at(tcx.def_span(expr_did)),
|
||||
"constant evaluation of enum discriminant resulted in non-integer",
|
||||
).emit();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
use dep_graph::SerializedDepNodeIndex;
|
||||
use dep_graph::DepNode;
|
||||
use hir::def_id::{CrateNum, DefId, DefIndex};
|
||||
use mir::interpret::{GlobalId, ConstValue};
|
||||
use mir::interpret::GlobalId;
|
||||
use traits::query::{
|
||||
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal,
|
||||
CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
|
||||
|
|
@ -191,8 +191,8 @@ impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> QueryDescription<'tcx> for queries::const_value_to_allocation<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, (val, ty): (ConstValue<'tcx>, Ty<'tcx>)) -> String {
|
||||
format!("converting value `{:?}` ({}) to an allocation", val, ty)
|
||||
fn describe(_tcx: TyCtxt, val: &'tcx ty::Const<'tcx>) -> String {
|
||||
format!("converting value `{:?}` to an allocation", val)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx>{
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (mir::interpret::ConstValue<'tcx>, Ty<'tcx>) {
|
||||
impl<'tcx> Key for &'tcx ty::Const<'tcx> {
|
||||
fn query_crate(&self) -> CrateNum {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault};
|
|||
use middle::stability::{self, DeprecationEntry};
|
||||
use middle::lang_items::{LanguageItems, LangItem};
|
||||
use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
|
||||
use middle::const_val::EvalResult;
|
||||
use mir::interpret::ConstEvalResult;
|
||||
use mir::mono::{CodegenUnit, Stats};
|
||||
use mir;
|
||||
use mir::interpret::{GlobalId, Allocation, ConstValue};
|
||||
use mir::interpret::{GlobalId, Allocation};
|
||||
use session::{CompileResult, CrateDisambiguator};
|
||||
use session::config::OutputFilenames;
|
||||
use traits::{self, Vtable};
|
||||
|
|
@ -230,11 +230,11 @@ define_queries! { <'tcx>
|
|||
/// Results of evaluating const items or constants embedded in
|
||||
/// other items (such as enum variant explicit discriminants).
|
||||
[] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
|
||||
-> EvalResult<'tcx>,
|
||||
-> ConstEvalResult<'tcx>,
|
||||
|
||||
/// Converts a constant value to an constant allocation
|
||||
[] fn const_value_to_allocation: const_value_to_allocation(
|
||||
(ConstValue<'tcx>, Ty<'tcx>)
|
||||
&'tcx ty::Const<'tcx>
|
||||
) -> &'tcx Allocation,
|
||||
|
||||
[] fn check_match: CheckMatch(DefId)
|
||||
|
|
@ -570,9 +570,9 @@ fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
|
|||
}
|
||||
|
||||
fn const_value_to_allocation<'tcx>(
|
||||
(val, ty): (ConstValue<'tcx>, Ty<'tcx>)
|
||||
val: &'tcx ty::Const<'tcx>,
|
||||
) -> DepConstructor<'tcx> {
|
||||
DepConstructor::ConstValueToAllocation { val, ty }
|
||||
DepConstructor::ConstValueToAllocation { val }
|
||||
}
|
||||
|
||||
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
//! type equality, etc.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use ty::subst::{Kind, UnpackedKind, Substs};
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::error::{ExpectedFound, TypeError};
|
||||
|
|
@ -474,7 +474,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||
return Ok(s);
|
||||
}
|
||||
match x.val {
|
||||
ConstVal::Unevaluated(def_id, substs) => {
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
// FIXME(eddyb) get the right param_env.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
match tcx.lift_to_global(&substs) {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,11 @@
|
|||
//! hand, though we've recently added some macros (e.g.,
|
||||
//! `BraceStructLiftImpl!`) to help with the tedium.
|
||||
|
||||
use middle::const_val::{self, ConstVal, ConstEvalErr};
|
||||
use mir::interpret::{ConstValue, ConstEvalErr};
|
||||
use ty::{self, Lift, Ty, TyCtxt};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use mir::interpret;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
|
@ -462,10 +461,11 @@ 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.kind).map(|kind| {
|
||||
tcx.lift(&self.error).map(|error| {
|
||||
ConstEvalErr {
|
||||
span: self.span,
|
||||
kind: Lrc::new(kind),
|
||||
stacktrace: self.stacktrace.clone(),
|
||||
error,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -577,7 +577,9 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
|
|||
PathNotFound(ref v) => PathNotFound(v.clone()),
|
||||
UnimplementedTraitSelection => UnimplementedTraitSelection,
|
||||
TypeckError => TypeckError,
|
||||
ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?),
|
||||
TooGeneric => TooGeneric,
|
||||
CheckMatchError => CheckMatchError,
|
||||
ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(&**err)?.into()),
|
||||
OverflowNeg => OverflowNeg,
|
||||
Overflow(op) => Overflow(op),
|
||||
DivisionByZero => DivisionByZero,
|
||||
|
|
@ -588,20 +590,6 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for const_val::ErrKind<'a> {
|
||||
type Lifted = const_val::ErrKind<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
use middle::const_val::ErrKind::*;
|
||||
|
||||
Some(match *self {
|
||||
CouldNotResolve => CouldNotResolve,
|
||||
TypeckError => TypeckError,
|
||||
CheckMatchError => CheckMatchError,
|
||||
Miri(ref e, ref frames) => return tcx.lift(e).map(|e| Miri(e, frames.clone())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
|
|
@ -1139,20 +1127,24 @@ EnumTypeFoldableImpl! {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> {
|
||||
impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
ConstVal::Value(v) => ConstVal::Value(v),
|
||||
ConstVal::Unevaluated(def_id, substs) => {
|
||||
ConstVal::Unevaluated(def_id, substs.fold_with(folder))
|
||||
ConstValue::Scalar(v) => ConstValue::Scalar(v),
|
||||
ConstValue::ScalarPair(a, b) => ConstValue::ScalarPair(a, b),
|
||||
ConstValue::ByRef(alloc, offset) => ConstValue::ByRef(alloc, offset),
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
ConstValue::Unevaluated(def_id, substs.fold_with(folder))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
match *self {
|
||||
ConstVal::Value(_) => false,
|
||||
ConstVal::Unevaluated(_, substs) => substs.visit_with(visitor),
|
||||
ConstValue::Scalar(_) |
|
||||
ConstValue::ScalarPair(_, _) |
|
||||
ConstValue::ByRef(_, _) => false,
|
||||
ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
use hir::def_id::DefId;
|
||||
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use middle::region;
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
|
@ -20,7 +20,7 @@ use ty::subst::{Substs, Subst, Kind, UnpackedKind};
|
|||
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::{Slice, TyS, ParamEnvAnd, ParamEnv};
|
||||
use util::captures::Captures;
|
||||
use mir::interpret::{Scalar, Pointer, Value, ConstValue};
|
||||
use mir::interpret::{Scalar, Pointer, Value};
|
||||
|
||||
use std::iter;
|
||||
use std::cmp::Ordering;
|
||||
|
|
@ -1859,7 +1859,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
pub struct Const<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
|
||||
pub val: ConstVal<'tcx>,
|
||||
pub val: ConstValue<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Const<'tcx> {
|
||||
|
|
@ -1870,19 +1870,7 @@ impl<'tcx> Const<'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
) -> &'tcx Self {
|
||||
tcx.mk_const(Const {
|
||||
val: ConstVal::Unevaluated(def_id, substs),
|
||||
ty,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_const_val(
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
val: ConstVal<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> &'tcx Self {
|
||||
tcx.mk_const(Const {
|
||||
val,
|
||||
val: ConstValue::Unevaluated(def_id, substs),
|
||||
ty,
|
||||
})
|
||||
}
|
||||
|
|
@ -1893,7 +1881,10 @@ impl<'tcx> Const<'tcx> {
|
|||
val: ConstValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> &'tcx Self {
|
||||
Self::from_const_val(tcx, ConstVal::Value(val), ty)
|
||||
tcx.mk_const(Const {
|
||||
val,
|
||||
ty,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -1956,34 +1947,22 @@ impl<'tcx> Const<'tcx> {
|
|||
}
|
||||
let ty = tcx.lift_to_global(&ty).unwrap();
|
||||
let size = tcx.layout_of(ty).ok()?.size;
|
||||
match self.val {
|
||||
ConstVal::Value(val) => val.to_bits(size),
|
||||
_ => None,
|
||||
}
|
||||
self.val.to_bits(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_ptr(&self) -> Option<Pointer> {
|
||||
match self.val {
|
||||
ConstVal::Value(val) => val.to_ptr(),
|
||||
_ => None,
|
||||
}
|
||||
self.val.to_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_byval_value(&self) -> Option<Value> {
|
||||
match self.val {
|
||||
ConstVal::Value(val) => val.to_byval_value(),
|
||||
_ => None,
|
||||
}
|
||||
self.val.to_byval_value()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_scalar(&self) -> Option<Scalar> {
|
||||
match self.val {
|
||||
ConstVal::Value(val) => val.to_scalar(),
|
||||
_ => None,
|
||||
}
|
||||
self.val.to_scalar()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -1995,10 +1974,7 @@ impl<'tcx> Const<'tcx> {
|
|||
assert_eq!(self.ty, ty.value);
|
||||
let ty = tcx.lift_to_global(&ty).unwrap();
|
||||
let size = tcx.layout_of(ty).ok()?.size;
|
||||
match self.val {
|
||||
ConstVal::Value(val) => val.to_bits(size),
|
||||
_ => None,
|
||||
}
|
||||
self.val.to_bits(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
//! An iterator over the type substructure.
|
||||
//! WARNING: this does not keep track of the region depth.
|
||||
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use ty::{self, Ty};
|
||||
use rustc_data_structures::small_vec::SmallVec;
|
||||
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
|
||||
|
|
@ -141,11 +141,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
|||
}
|
||||
|
||||
fn push_const<'tcx>(stack: &mut TypeWalkerStack<'tcx>, constant: &'tcx ty::Const<'tcx>) {
|
||||
match constant.val {
|
||||
ConstVal::Value(_) => {}
|
||||
ConstVal::Unevaluated(_, substs) => {
|
||||
stack.extend(substs.types().rev());
|
||||
}
|
||||
if let ConstValue::Unevaluated(_, substs) = constant.val {
|
||||
stack.extend(substs.types().rev());
|
||||
}
|
||||
stack.push(constant.ty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use infer::InferCtxt;
|
||||
use ty::subst::Substs;
|
||||
use traits;
|
||||
|
|
@ -216,18 +216,15 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
/// into `self.out`.
|
||||
fn compute_const(&mut self, constant: &'tcx ty::Const<'tcx>) {
|
||||
self.require_sized(constant.ty, traits::ConstSized);
|
||||
match constant.val {
|
||||
ConstVal::Value(_) => {}
|
||||
ConstVal::Unevaluated(def_id, substs) => {
|
||||
let obligations = self.nominal_obligations(def_id, substs);
|
||||
self.out.extend(obligations);
|
||||
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
|
||||
let obligations = self.nominal_obligations(def_id, substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
let predicate = ty::Predicate::ConstEvaluatable(def_id, substs);
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
self.out.push(traits::Obligation::new(cause,
|
||||
self.param_env,
|
||||
predicate));
|
||||
}
|
||||
let predicate = ty::Predicate::ConstEvaluatable(def_id, substs);
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
self.out.push(traits::Obligation::new(cause,
|
||||
self.param_env,
|
||||
predicate));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use hir::def_id::DefId;
|
||||
use hir::map::definitions::DefPathData;
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::ConstValue;
|
||||
use middle::region::{self, BlockRemainder};
|
||||
use ty::subst::{self, Subst};
|
||||
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
|
||||
|
|
@ -1195,12 +1195,12 @@ define_print! {
|
|||
TyArray(ty, sz) => {
|
||||
print!(f, cx, write("["), print(ty), write("; "))?;
|
||||
match sz.val {
|
||||
ConstVal::Value(..) => ty::tls::with(|tcx| {
|
||||
write!(f, "{}", sz.unwrap_usize(tcx))
|
||||
})?,
|
||||
ConstVal::Unevaluated(_def_id, _substs) => {
|
||||
ConstValue::Unevaluated(_def_id, _substs) => {
|
||||
write!(f, "_")?;
|
||||
}
|
||||
_ => ty::tls::with(|tcx| {
|
||||
write!(f, "{}", sz.unwrap_usize(tcx))
|
||||
})?,
|
||||
}
|
||||
write!(f, "]")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1381,7 +1381,6 @@ mod temp_stable_hash_impls {
|
|||
|
||||
fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) {
|
||||
use rustc::mir::interpret::GlobalId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
||||
info!("loading wasm section {:?}", id);
|
||||
|
||||
|
|
@ -1399,12 +1398,6 @@ fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) {
|
|||
};
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
let val = tcx.const_eval(param_env.and(cid)).unwrap();
|
||||
|
||||
let const_val = match val.val {
|
||||
ConstVal::Value(val) => val,
|
||||
ConstVal::Unevaluated(..) => bug!("should be evaluated"),
|
||||
};
|
||||
|
||||
let alloc = tcx.const_value_to_allocation((const_val, val.ty));
|
||||
let alloc = tcx.const_value_to_allocation(val);
|
||||
(section.to_string(), alloc.bytes.clone())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@
|
|||
// except according to those terms.
|
||||
|
||||
use llvm::{self, ValueRef};
|
||||
use rustc::middle::const_val::{ConstVal, ConstEvalErr};
|
||||
use rustc::mir::interpret::ConstEvalErr;
|
||||
use rustc_mir::interpret::{read_target_uint, const_val_field};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size};
|
||||
|
|
@ -117,7 +118,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
|
|||
pub fn codegen_static_initializer<'a, 'tcx>(
|
||||
cx: &CodegenCx<'a, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> Result<ValueRef, ConstEvalErr<'tcx>>
|
||||
-> Result<ValueRef, Lrc<ConstEvalErr<'tcx>>>
|
||||
{
|
||||
let instance = ty::Instance::mono(cx.tcx, def_id);
|
||||
let cid = GlobalId {
|
||||
|
|
@ -128,20 +129,20 @@ pub fn codegen_static_initializer<'a, 'tcx>(
|
|||
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
|
||||
|
||||
let alloc = match static_.val {
|
||||
ConstVal::Value(ConstValue::ByRef(alloc, n)) if n.bytes() == 0 => alloc,
|
||||
ConstValue::ByRef(alloc, n) if n.bytes() == 0 => alloc,
|
||||
_ => bug!("static const eval returned {:#?}", static_),
|
||||
};
|
||||
Ok(const_alloc_to_llvm(cx, alloc))
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
fn const_to_const_value(
|
||||
fn fully_evaluate(
|
||||
&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
constant: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<ConstValue<'tcx>, ConstEvalErr<'tcx>> {
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||
match constant.val {
|
||||
ConstVal::Unevaluated(def_id, ref substs) => {
|
||||
ConstValue::Unevaluated(def_id, ref substs) => {
|
||||
let tcx = bx.tcx();
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
let instance = ty::Instance::resolve(tcx, param_env, def_id, substs).unwrap();
|
||||
|
|
@ -149,18 +150,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
let c = tcx.const_eval(param_env.and(cid))?;
|
||||
self.const_to_const_value(bx, c)
|
||||
tcx.const_eval(param_env.and(cid))
|
||||
},
|
||||
ConstVal::Value(val) => Ok(val),
|
||||
_ => Ok(constant),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mir_constant_to_const_value(
|
||||
pub fn eval_mir_constant(
|
||||
&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
constant: &mir::Constant<'tcx>,
|
||||
) -> Result<ConstValue<'tcx>, ConstEvalErr<'tcx>> {
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||
match constant.literal {
|
||||
mir::Literal::Promoted { index } => {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
|
|
@ -173,7 +173,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||
mir::Literal::Value { value } => {
|
||||
Ok(self.monomorphize(&value))
|
||||
}
|
||||
}.and_then(|c| self.const_to_const_value(bx, c))
|
||||
}.and_then(|c| self.fully_evaluate(bx, c))
|
||||
}
|
||||
|
||||
/// process constant containing SIMD shuffle indices
|
||||
|
|
@ -182,14 +182,14 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||
bx: &Builder<'a, 'tcx>,
|
||||
constant: &mir::Constant<'tcx>,
|
||||
) -> (ValueRef, Ty<'tcx>) {
|
||||
self.mir_constant_to_const_value(bx, constant)
|
||||
self.eval_mir_constant(bx, constant)
|
||||
.and_then(|c| {
|
||||
let field_ty = constant.ty.builtin_index().unwrap();
|
||||
let fields = match constant.ty.sty {
|
||||
let field_ty = c.ty.builtin_index().unwrap();
|
||||
let fields = match c.ty.sty {
|
||||
ty::TyArray(_, n) => n.unwrap_usize(bx.tcx()),
|
||||
ref other => bug!("invalid simd shuffle type: {}", other),
|
||||
};
|
||||
let values: Result<Vec<ValueRef>, _> = (0..fields).map(|field| {
|
||||
let values: Result<Vec<ValueRef>, Lrc<_>> = (0..fields).map(|field| {
|
||||
let field = const_val_field(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
|
@ -197,7 +197,6 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||
None,
|
||||
mir::Field::new(field as usize),
|
||||
c,
|
||||
constant.ty,
|
||||
)?;
|
||||
if let Some(prim) = field.to_scalar() {
|
||||
let layout = bx.cx.layout_of(field_ty);
|
||||
|
|
@ -214,7 +213,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||
}
|
||||
}).collect();
|
||||
let llval = C_struct(bx.cx, &values?, false);
|
||||
Ok((llval, constant.ty))
|
||||
Ok((llval, c.ty))
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
e.report_as_error(
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
// except according to those terms.
|
||||
|
||||
use llvm::{ValueRef, LLVMConstInBoundsGEP};
|
||||
use rustc::middle::const_val::ConstEvalErr;
|
||||
use rustc::mir::interpret::ConstEvalErr;
|
||||
use rustc::mir;
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
use base;
|
||||
use common::{self, CodegenCx, C_null, C_undef, C_usize};
|
||||
|
|
@ -95,16 +96,16 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
|||
}
|
||||
|
||||
pub fn from_const(bx: &Builder<'a, 'tcx>,
|
||||
val: ConstValue<'tcx>,
|
||||
ty: ty::Ty<'tcx>)
|
||||
-> Result<OperandRef<'tcx>, ConstEvalErr<'tcx>> {
|
||||
let layout = bx.cx.layout_of(ty);
|
||||
val: &'tcx ty::Const<'tcx>)
|
||||
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||
let layout = bx.cx.layout_of(val.ty);
|
||||
|
||||
if layout.is_zst() {
|
||||
return Ok(OperandRef::new_zst(bx.cx, layout));
|
||||
}
|
||||
|
||||
let val = match val {
|
||||
let val = match val.val {
|
||||
ConstValue::Unevaluated(..) => bug!(),
|
||||
ConstValue::Scalar(x) => {
|
||||
let scalar = match layout.abi {
|
||||
layout::Abi::Scalar(ref x) => x,
|
||||
|
|
@ -408,8 +409,8 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||
|
||||
mir::Operand::Constant(ref constant) => {
|
||||
let ty = self.monomorphize(&constant.ty);
|
||||
self.mir_constant_to_const_value(bx, constant)
|
||||
.and_then(|c| OperandRef::from_const(bx, c, ty))
|
||||
self.eval_mir_constant(bx, constant)
|
||||
.and_then(|c| OperandRef::from_const(bx, c))
|
||||
.unwrap_or_else(|err| {
|
||||
match constant.literal {
|
||||
mir::Literal::Promoted { .. } => {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ use self::Constructor::*;
|
|||
use self::Usefulness::*;
|
||||
use self::WitnessPreference::*;
|
||||
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
|
|
@ -544,14 +542,9 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
|
|||
|
||||
for row in patterns {
|
||||
match *row.kind {
|
||||
PatternKind::Constant {
|
||||
value: const_val @ &ty::Const {
|
||||
val: ConstVal::Value(..),
|
||||
..
|
||||
}
|
||||
} => {
|
||||
if let Some(ptr) = const_val.to_ptr() {
|
||||
let is_array_ptr = const_val.ty
|
||||
PatternKind::Constant { value } => {
|
||||
if let Some(ptr) = value.to_ptr() {
|
||||
let is_array_ptr = value.ty
|
||||
.builtin_deref(true)
|
||||
.and_then(|t| t.ty.builtin_index())
|
||||
.map_or(false, |t| t == cx.tcx.types.u8);
|
||||
|
|
@ -933,13 +926,14 @@ fn slice_pat_covered_by_constructor<'tcx>(
|
|||
suffix: &[Pattern<'tcx>]
|
||||
) -> Result<bool, ErrorReported> {
|
||||
let data: &[u8] = match *ctor {
|
||||
ConstantValue(&ty::Const { val: ConstVal::Value(const_val), ty }) => {
|
||||
let val = match const_val {
|
||||
ConstValue::ByRef(..) => bug!("unexpected ConstValue::ByRef"),
|
||||
ConstantValue(const_val) => {
|
||||
let val = match const_val.val {
|
||||
ConstValue::Unevaluated(..) |
|
||||
ConstValue::ByRef(..) => bug!("unexpected ConstValue: {:?}", const_val),
|
||||
ConstValue::Scalar(val) | ConstValue::ScalarPair(val, _) => val,
|
||||
};
|
||||
if let Ok(ptr) = val.to_ptr() {
|
||||
let is_array_ptr = ty
|
||||
let is_array_ptr = const_val.ty
|
||||
.builtin_deref(true)
|
||||
.and_then(|t| t.ty.builtin_index())
|
||||
.map_or(false, |t| t == tcx.types.u8);
|
||||
|
|
|
|||
|
|
@ -140,13 +140,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
|||
}
|
||||
PatternError::FloatBug => {
|
||||
// FIXME(#31407) this is only necessary because float parsing is buggy
|
||||
::rustc::middle::const_val::struct_error(
|
||||
::rustc::mir::interpret::struct_error(
|
||||
self.tcx.at(pat_span),
|
||||
"could not evaluate float literal (see issue #31407)",
|
||||
).emit();
|
||||
}
|
||||
PatternError::NonConstPath(span) => {
|
||||
::rustc::middle::const_val::struct_error(
|
||||
::rustc::mir::interpret::struct_error(
|
||||
self.tcx.at(span),
|
||||
"runtime values cannot be referenced in patterns",
|
||||
).emit();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ pub(crate) use self::check_match::check_match;
|
|||
|
||||
use interpret::{const_val_field, const_variant_index, self};
|
||||
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
|
||||
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, Value};
|
||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region};
|
||||
|
|
@ -122,13 +121,6 @@ pub enum PatternKind<'tcx> {
|
|||
},
|
||||
}
|
||||
|
||||
fn print_const_val(value: &ty::Const, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match value.val {
|
||||
ConstVal::Value(..) => fmt_const_val(f, value),
|
||||
ConstVal::Unevaluated(..) => bug!("{:?} not printable in a pattern", value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Display for Pattern<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self.kind {
|
||||
|
|
@ -236,15 +228,15 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
|
|||
write!(f, "{}", subpattern)
|
||||
}
|
||||
PatternKind::Constant { value } => {
|
||||
print_const_val(value, f)
|
||||
fmt_const_val(f, value)
|
||||
}
|
||||
PatternKind::Range { lo, hi, end } => {
|
||||
print_const_val(lo, f)?;
|
||||
fmt_const_val(f, lo)?;
|
||||
match end {
|
||||
RangeEnd::Included => write!(f, "...")?,
|
||||
RangeEnd::Excluded => write!(f, "..")?,
|
||||
}
|
||||
print_const_val(hi, f)
|
||||
fmt_const_val(f, hi)
|
||||
}
|
||||
PatternKind::Slice { ref prefix, ref slice, ref suffix } |
|
||||
PatternKind::Array { ref prefix, ref slice, ref suffix } => {
|
||||
|
|
@ -795,13 +787,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
|||
debug!("const_to_pat: cv={:#?}", cv);
|
||||
let adt_subpattern = |i, variant_opt| {
|
||||
let field = Field::new(i);
|
||||
let val = match cv.val {
|
||||
ConstVal::Value(miri) => const_val_field(
|
||||
self.tcx, self.param_env, instance,
|
||||
variant_opt, field, miri, cv.ty,
|
||||
).expect("field access failed"),
|
||||
_ => bug!("{:#?} is not a valid adt", cv),
|
||||
};
|
||||
let val = const_val_field(
|
||||
self.tcx, self.param_env, instance,
|
||||
variant_opt, field, cv,
|
||||
).expect("field access failed");
|
||||
self.const_to_pat(instance, val, id, span)
|
||||
};
|
||||
let adt_subpatterns = |n, variant_opt| {
|
||||
|
|
@ -840,24 +829,18 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
|||
PatternKind::Wild
|
||||
},
|
||||
ty::TyAdt(adt_def, substs) if adt_def.is_enum() => {
|
||||
match cv.val {
|
||||
ConstVal::Value(val) => {
|
||||
let variant_index = const_variant_index(
|
||||
self.tcx, self.param_env, instance, val, cv.ty
|
||||
).expect("const_variant_index failed");
|
||||
let subpatterns = adt_subpatterns(
|
||||
adt_def.variants[variant_index].fields.len(),
|
||||
Some(variant_index),
|
||||
);
|
||||
PatternKind::Variant {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index,
|
||||
subpatterns,
|
||||
}
|
||||
},
|
||||
ConstVal::Unevaluated(..) =>
|
||||
span_bug!(span, "{:#?} is not a valid enum constant", cv),
|
||||
let variant_index = const_variant_index(
|
||||
self.tcx, self.param_env, instance, cv
|
||||
).expect("const_variant_index failed");
|
||||
let subpatterns = adt_subpatterns(
|
||||
adt_def.variants[variant_index].fields.len(),
|
||||
Some(variant_index),
|
||||
);
|
||||
PatternKind::Variant {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index,
|
||||
subpatterns,
|
||||
}
|
||||
},
|
||||
ty::TyAdt(adt_def, _) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use rustc::hir;
|
||||
use rustc::middle::const_val::{ConstEvalErr, ErrKind};
|
||||
use rustc::middle::const_val::ErrKind::{TypeckError, CheckMatchError};
|
||||
use rustc::mir::interpret::{ConstEvalErr};
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, TyCtxt, Ty, Instance};
|
||||
use rustc::ty::layout::{self, LayoutOf, Primitive};
|
||||
|
|
@ -18,7 +17,6 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory, Memo
|
|||
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
|
@ -106,7 +104,8 @@ pub fn value_to_const_value<'tcx>(
|
|||
let (frames, span) = ecx.generate_stacktrace(None);
|
||||
let err = ConstEvalErr {
|
||||
span,
|
||||
kind: ErrKind::Miri(err, frames).into(),
|
||||
error: err,
|
||||
stacktrace: frames,
|
||||
};
|
||||
err.report_as_error(
|
||||
ecx.tcx,
|
||||
|
|
@ -426,13 +425,13 @@ pub fn const_val_field<'a, 'tcx>(
|
|||
instance: ty::Instance<'tcx>,
|
||||
variant: Option<usize>,
|
||||
field: mir::Field,
|
||||
value: ConstValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> ::rustc::middle::const_val::EvalResult<'tcx> {
|
||||
trace!("const_val_field: {:?}, {:?}, {:?}, {:?}", instance, field, value, ty);
|
||||
value: &'tcx ty::Const<'tcx>,
|
||||
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||
trace!("const_val_field: {:?}, {:?}, {:?}", instance, field, value);
|
||||
let mut ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
||||
let result = (|| {
|
||||
let value = ecx.const_value_to_value(value, ty)?;
|
||||
let ty = value.ty;
|
||||
let value = ecx.const_to_value(value.val)?;
|
||||
let layout = ecx.layout_of(ty)?;
|
||||
let (ptr, align) = match value {
|
||||
Value::ByRef(ptr, align) => (ptr, align),
|
||||
|
|
@ -467,11 +466,11 @@ pub fn const_val_field<'a, 'tcx>(
|
|||
})();
|
||||
result.map_err(|err| {
|
||||
let (trace, span) = ecx.generate_stacktrace(None);
|
||||
let err = ErrKind::Miri(err, trace);
|
||||
ConstEvalErr {
|
||||
kind: err.into(),
|
||||
error: err,
|
||||
stacktrace: trace,
|
||||
span,
|
||||
}
|
||||
}.into()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -479,30 +478,29 @@ pub fn const_variant_index<'a, 'tcx>(
|
|||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
val: ConstValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
val: &'tcx ty::Const<'tcx>,
|
||||
) -> EvalResult<'tcx, usize> {
|
||||
trace!("const_variant_index: {:?}, {:?}, {:?}", instance, val, ty);
|
||||
trace!("const_variant_index: {:?}, {:?}", instance, val);
|
||||
let mut ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
||||
let value = ecx.const_value_to_value(val, ty)?;
|
||||
let value = ecx.const_to_value(val.val)?;
|
||||
let (ptr, align) = match value {
|
||||
Value::ScalarPair(..) | Value::Scalar(_) => {
|
||||
let layout = ecx.layout_of(ty)?;
|
||||
let layout = ecx.layout_of(val.ty)?;
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?.into();
|
||||
ecx.write_value_to_ptr(value, ptr, layout.align, ty)?;
|
||||
ecx.write_value_to_ptr(value, ptr, layout.align, val.ty)?;
|
||||
(ptr, layout.align)
|
||||
},
|
||||
Value::ByRef(ptr, align) => (ptr, align),
|
||||
};
|
||||
let place = Place::from_scalar_ptr(ptr, align);
|
||||
ecx.read_discriminant_as_variant_index(place, ty)
|
||||
ecx.read_discriminant_as_variant_index(place, val.ty)
|
||||
}
|
||||
|
||||
pub fn const_value_to_allocation_provider<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
(val, ty): (ConstValue<'tcx>, Ty<'tcx>),
|
||||
val: &'tcx ty::Const<'tcx>,
|
||||
) -> &'tcx Allocation {
|
||||
match val {
|
||||
match val.val {
|
||||
ConstValue::ByRef(alloc, offset) => {
|
||||
assert_eq!(offset.bytes(), 0);
|
||||
return alloc;
|
||||
|
|
@ -515,20 +513,20 @@ pub fn const_value_to_allocation_provider<'a, 'tcx>(
|
|||
ty::ParamEnv::reveal_all(),
|
||||
CompileTimeEvaluator,
|
||||
());
|
||||
let value = ecx.const_value_to_value(val, ty)?;
|
||||
let layout = ecx.layout_of(ty)?;
|
||||
let value = ecx.const_to_value(val.val)?;
|
||||
let layout = ecx.layout_of(val.ty)?;
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?;
|
||||
ecx.write_value_to_ptr(value, ptr.into(), layout.align, ty)?;
|
||||
ecx.write_value_to_ptr(value, ptr.into(), layout.align, val.ty)?;
|
||||
let alloc = ecx.memory.get(ptr.alloc_id)?;
|
||||
Ok(tcx.intern_const_alloc(alloc.clone()))
|
||||
};
|
||||
result().expect("unable to convert ConstVal to Allocation")
|
||||
result().expect("unable to convert ConstValue to Allocation")
|
||||
}
|
||||
|
||||
pub fn const_eval_provider<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||
) -> ::rustc::middle::const_val::EvalResult<'tcx> {
|
||||
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||
trace!("const eval: {:?}", key);
|
||||
let cid = key.value;
|
||||
let def_id = cid.instance.def.def_id();
|
||||
|
|
@ -540,9 +538,10 @@ pub fn const_eval_provider<'a, 'tcx>(
|
|||
// Do match-check before building MIR
|
||||
if tcx.check_match(def_id).is_err() {
|
||||
return Err(ConstEvalErr {
|
||||
kind: Lrc::new(CheckMatchError),
|
||||
error: EvalErrorKind::CheckMatchError.into(),
|
||||
stacktrace: vec![],
|
||||
span,
|
||||
});
|
||||
}.into());
|
||||
}
|
||||
|
||||
if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) {
|
||||
|
|
@ -552,9 +551,10 @@ pub fn const_eval_provider<'a, 'tcx>(
|
|||
// Do not continue into miri if typeck errors occurred; it will fail horribly
|
||||
if tables.tainted_by_errors {
|
||||
return Err(ConstEvalErr {
|
||||
kind: Lrc::new(TypeckError),
|
||||
error: EvalErrorKind::CheckMatchError.into(),
|
||||
stacktrace: vec![],
|
||||
span,
|
||||
});
|
||||
}.into());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -566,15 +566,15 @@ pub fn const_eval_provider<'a, 'tcx>(
|
|||
Ok(value_to_const_value(&ecx, val, miri_ty))
|
||||
}).map_err(|err| {
|
||||
let (trace, span) = ecx.generate_stacktrace(None);
|
||||
let err = ErrKind::Miri(err, trace);
|
||||
let err = ConstEvalErr {
|
||||
kind: err.into(),
|
||||
error: err,
|
||||
stacktrace: trace,
|
||||
span,
|
||||
};
|
||||
if tcx.is_static(def_id).is_some() {
|
||||
err.report_as_error(ecx.tcx, "could not evaluate static initializer");
|
||||
}
|
||||
err
|
||||
err.into()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@ use std::fmt::Write;
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::map::definitions::DefPathData;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout};
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
|
||||
use rustc::ty::query::TyCtxtAt;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc::middle::const_val::FrameInfo;
|
||||
use rustc::mir::interpret::FrameInfo;
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::ast::Mutability;
|
||||
use rustc::mir::interpret::{
|
||||
|
|
@ -233,12 +232,18 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
Ok(Scalar::Ptr(ptr).to_value_with_len(s.len() as u64, self.tcx.tcx))
|
||||
}
|
||||
|
||||
pub fn const_value_to_value(
|
||||
pub fn const_to_value(
|
||||
&mut self,
|
||||
val: ConstValue<'tcx>,
|
||||
_ty: Ty<'tcx>,
|
||||
) -> EvalResult<'tcx, Value> {
|
||||
match val {
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
self.read_global_as_value(GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
})
|
||||
}
|
||||
ConstValue::ByRef(alloc, offset) => {
|
||||
// FIXME: Allocate new AllocId for all constants inside
|
||||
let id = self.memory.allocate_value(alloc.clone(), Some(MemoryKind::Stack))?;
|
||||
|
|
@ -249,23 +254,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn const_to_value(
|
||||
&mut self,
|
||||
const_val: &ConstVal<'tcx>,
|
||||
ty: Ty<'tcx>
|
||||
) -> EvalResult<'tcx, Value> {
|
||||
match *const_val {
|
||||
ConstVal::Unevaluated(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
self.read_global_as_value(GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
}, ty)
|
||||
}
|
||||
ConstVal::Value(val) => self.const_value_to_value(val, ty)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve(&self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> EvalResult<'tcx, ty::Instance<'tcx>> {
|
||||
trace!("resolve: {:?}, {:#?}", def_id, substs);
|
||||
trace!("substs: {:#?}", self.substs());
|
||||
|
|
@ -280,7 +268,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| EvalErrorKind::TypeckError.into()) // turn error prop into a panic to expose associated type in const issue
|
||||
).ok_or_else(|| EvalErrorKind::TooGeneric.into())
|
||||
}
|
||||
|
||||
pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||
|
|
@ -739,7 +727,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| EvalErrorKind::TypeckError.into());
|
||||
).ok_or_else(|| EvalErrorKind::TooGeneric.into());
|
||||
let fn_ptr = self.memory.create_fn_alloc(instance?);
|
||||
let valty = ValTy {
|
||||
value: Value::Scalar(fn_ptr.into()),
|
||||
|
|
@ -849,14 +837,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
use rustc::mir::Literal;
|
||||
let mir::Constant { ref literal, .. } = **constant;
|
||||
let value = match *literal {
|
||||
Literal::Value { ref value } => self.const_to_value(&value.val, ty)?,
|
||||
Literal::Value { ref value } => self.const_to_value(value.val)?,
|
||||
|
||||
Literal::Promoted { index } => {
|
||||
let instance = self.frame().instance;
|
||||
self.read_global_as_value(GlobalId {
|
||||
instance,
|
||||
promoted: Some(index),
|
||||
}, ty)?
|
||||
})?
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1036,18 +1024,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_global_as_value(&mut self, gid: GlobalId<'tcx>, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
|
||||
if self.tcx.is_static(gid.instance.def_id()).is_some() {
|
||||
let alloc_id = self
|
||||
.tcx
|
||||
.alloc_map
|
||||
.lock()
|
||||
.intern_static(gid.instance.def_id());
|
||||
let layout = self.layout_of(ty)?;
|
||||
return Ok(Value::ByRef(Scalar::Ptr(alloc_id.into()), layout.align))
|
||||
}
|
||||
pub fn read_global_as_value(&mut self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, Value> {
|
||||
let cv = self.const_eval(gid)?;
|
||||
self.const_to_value(&cv.val, ty)
|
||||
self.const_to_value(cv.val)
|
||||
}
|
||||
|
||||
pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use rustc::ty::ParamEnv;
|
|||
use rustc::ty::query::TyCtxtAt;
|
||||
use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
|
||||
use syntax::ast::Mutability;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value,
|
||||
|
|
@ -285,16 +284,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
|||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|_| {
|
||||
self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|err| {
|
||||
// no need to report anything, the const_eval call takes care of that for statics
|
||||
assert!(self.tcx.is_static(def_id).is_some());
|
||||
EvalErrorKind::TypeckError.into()
|
||||
EvalErrorKind::ReferencedConstant(err).into()
|
||||
}).map(|val| {
|
||||
let const_val = match val.val {
|
||||
ConstVal::Value(val) => val,
|
||||
ConstVal::Unevaluated(..) => bug!("should be evaluated"),
|
||||
};
|
||||
self.tcx.const_value_to_allocation((const_val, val.ty))
|
||||
self.tcx.const_value_to_allocation(val)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,6 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
|||
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::interpret::{AllocId, ConstValue};
|
||||
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
|
||||
use rustc::ty::subst::Substs;
|
||||
|
|
@ -1210,15 +1209,12 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
match tcx.const_eval(param_env.and(cid)) {
|
||||
Ok(val) => collect_const(tcx, val, instance.substs, output),
|
||||
Err(err) => {
|
||||
use rustc::middle::const_val::ErrKind;
|
||||
use rustc::mir::interpret::EvalErrorKind;
|
||||
if let ErrKind::Miri(ref miri, ..) = *err.kind {
|
||||
if let EvalErrorKind::ReferencedConstant(_) = miri.kind {
|
||||
err.report_as_error(
|
||||
tcx.at(mir.promoted[i].span),
|
||||
"erroneous constant used",
|
||||
);
|
||||
}
|
||||
if let EvalErrorKind::ReferencedConstant(_) = err.error.kind {
|
||||
err.report_as_error(
|
||||
tcx.at(mir.promoted[i].span),
|
||||
"erroneous constant used",
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -1243,7 +1239,7 @@ fn collect_const<'a, 'tcx>(
|
|||
debug!("visiting const {:?}", *constant);
|
||||
|
||||
let val = match constant.val {
|
||||
ConstVal::Unevaluated(def_id, substs) => {
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
let substs = tcx.subst_and_normalize_erasing_regions(
|
||||
param_substs,
|
||||
|
|
@ -1274,16 +1270,16 @@ fn collect_const<'a, 'tcx>(
|
|||
_ => constant.val,
|
||||
};
|
||||
match val {
|
||||
ConstVal::Unevaluated(..) => bug!("const eval yielded unevaluated const"),
|
||||
ConstVal::Value(ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b))) => {
|
||||
ConstValue::Unevaluated(..) => bug!("const eval yielded unevaluated const"),
|
||||
ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => {
|
||||
collect_miri(tcx, a.alloc_id, output);
|
||||
collect_miri(tcx, b.alloc_id, output);
|
||||
}
|
||||
ConstVal::Value(ConstValue::ScalarPair(_, Scalar::Ptr(ptr))) |
|
||||
ConstVal::Value(ConstValue::ScalarPair(Scalar::Ptr(ptr), _)) |
|
||||
ConstVal::Value(ConstValue::Scalar(Scalar::Ptr(ptr))) =>
|
||||
ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) |
|
||||
ConstValue::ScalarPair(Scalar::Ptr(ptr), _) |
|
||||
ConstValue::Scalar(Scalar::Ptr(ptr)) =>
|
||||
collect_miri(tcx, ptr.alloc_id, output),
|
||||
ConstVal::Value(ConstValue::ByRef(alloc, _offset)) => {
|
||||
ConstValue::ByRef(alloc, _offset) => {
|
||||
for &id in alloc.relocations.values() {
|
||||
collect_miri(tcx, id, output);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local
|
|||
use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind};
|
||||
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
|
||||
use rustc::mir::visit::{Visitor, PlaceContext};
|
||||
use rustc::middle::const_val::{ConstVal, ConstEvalErr, ErrKind};
|
||||
use rustc::mir::interpret::ConstEvalErr;
|
||||
use rustc::ty::{TyCtxt, self, Instance};
|
||||
use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult};
|
||||
use interpret::EvalContext;
|
||||
|
|
@ -45,8 +45,11 @@ impl MirPass for ConstProp {
|
|||
return;
|
||||
}
|
||||
match tcx.describe_def(source.def_id) {
|
||||
// skip statics because they'll be evaluated by miri anyway
|
||||
// skip statics/consts because they'll be evaluated by miri anyway
|
||||
Some(Def::Const(..)) |
|
||||
Some(Def::Static(..)) => return,
|
||||
// we still run on associated constants, because they might not get evaluated
|
||||
// within the current crate
|
||||
_ => {},
|
||||
}
|
||||
trace!("ConstProp starting for {:?}", source.def_id);
|
||||
|
|
@ -145,7 +148,8 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
|||
let (frames, span) = self.ecx.generate_stacktrace(None);
|
||||
let err = ConstEvalErr {
|
||||
span,
|
||||
kind: ErrKind::Miri(err, frames).into(),
|
||||
error: err,
|
||||
stacktrace: frames,
|
||||
};
|
||||
err.report_as_lint(
|
||||
self.ecx.tcx,
|
||||
|
|
@ -159,54 +163,30 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
|||
r
|
||||
}
|
||||
|
||||
fn const_eval(&mut self, cid: GlobalId<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
|
||||
let value = match self.tcx.const_eval(self.param_env.and(cid)) {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
err.report_as_error(
|
||||
self.tcx.at(err.span),
|
||||
"constant evaluation error",
|
||||
);
|
||||
return None;
|
||||
},
|
||||
};
|
||||
let val = match value.val {
|
||||
ConstVal::Value(v) => {
|
||||
self.use_ecx(source_info, |this| this.ecx.const_value_to_value(v, value.ty))?
|
||||
},
|
||||
_ => bug!("eval produced: {:?}", value),
|
||||
};
|
||||
let val = (val, value.ty, source_info.span);
|
||||
trace!("evaluated {:?} to {:?}", cid, val);
|
||||
Some(val)
|
||||
}
|
||||
|
||||
fn eval_constant(
|
||||
&mut self,
|
||||
c: &Constant<'tcx>,
|
||||
source_info: SourceInfo,
|
||||
) -> Option<Const<'tcx>> {
|
||||
match c.literal {
|
||||
Literal::Value { value } => match value.val {
|
||||
ConstVal::Value(v) => {
|
||||
let v = self.use_ecx(source_info, |this| {
|
||||
this.ecx.const_value_to_value(v, value.ty)
|
||||
})?;
|
||||
Some((v, value.ty, c.span))
|
||||
},
|
||||
ConstVal::Unevaluated(did, substs) => {
|
||||
let instance = Instance::resolve(
|
||||
self.tcx,
|
||||
self.param_env,
|
||||
did,
|
||||
substs,
|
||||
)?;
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
self.const_eval(cid, source_info)
|
||||
},
|
||||
Literal::Value { value } => {
|
||||
self.ecx.tcx.span = source_info.span;
|
||||
match self.ecx.const_to_value(value.val) {
|
||||
Ok(val) => Some((val, value.ty, c.span)),
|
||||
Err(error) => {
|
||||
let (stacktrace, span) = self.ecx.generate_stacktrace(None);
|
||||
let err = ConstEvalErr {
|
||||
span,
|
||||
error,
|
||||
stacktrace,
|
||||
};
|
||||
err.report_as_error(
|
||||
self.tcx.at(source_info.span),
|
||||
"could not evaluate constant",
|
||||
);
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
// evaluate the promoted and replace the constant with the evaluated result
|
||||
Literal::Promoted { index } => {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
use rustc::traits::{self, TraitEngine};
|
||||
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
|
||||
use rustc::ty::cast::CastTy;
|
||||
|
|
@ -611,7 +611,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
}
|
||||
Operand::Constant(ref constant) => {
|
||||
if let Literal::Value {
|
||||
value: &ty::Const { val: ConstVal::Unevaluated(def_id, _), ty, .. }
|
||||
value: &ty::Const { val: ConstValue::Unevaluated(def_id, _), ty, .. }
|
||||
} = constant.literal {
|
||||
// Don't peek inside trait associated constants.
|
||||
if self.tcx.trait_of_item(def_id).is_some() {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ use syntax::symbol::keywords::{self, Keyword};
|
|||
use syntax::symbol::{Symbol, InternedString};
|
||||
use syntax_pos::{self, DUMMY_SP, Pos, FileName};
|
||||
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::middle::resolve_lifetime as rl;
|
||||
use rustc::ty::fold::TypeFolder;
|
||||
|
|
@ -3014,7 +3014,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
ty::TySlice(ty) => Slice(box ty.clean(cx)),
|
||||
ty::TyArray(ty, n) => {
|
||||
let mut n = cx.tcx.lift(&n).unwrap();
|
||||
if let ConstVal::Unevaluated(def_id, substs) = n.val {
|
||||
if let ConstValue::Unevaluated(def_id, substs) = n.val {
|
||||
let param_env = cx.tcx.param_env(def_id);
|
||||
let cid = GlobalId {
|
||||
instance: ty::Instance::new(def_id, substs),
|
||||
|
|
@ -4096,14 +4096,14 @@ fn name_from_pat(p: &hir::Pat) -> String {
|
|||
|
||||
fn print_const(cx: &DocContext, n: &ty::Const) -> String {
|
||||
match n.val {
|
||||
ConstVal::Unevaluated(def_id, _) => {
|
||||
ConstValue::Unevaluated(def_id, _) => {
|
||||
if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) {
|
||||
print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id))
|
||||
} else {
|
||||
inline::print_inlined_const(cx, def_id)
|
||||
}
|
||||
},
|
||||
ConstVal::Value(..) => {
|
||||
_ => {
|
||||
let mut s = String::new();
|
||||
::rustc::mir::fmt_const_val(&mut s, n).unwrap();
|
||||
// array lengths are obviously usize
|
||||
|
|
|
|||
|
|
@ -11,16 +11,10 @@
|
|||
#![deny(const_err)]
|
||||
|
||||
pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
|
||||
//~^ ERROR this constant cannot be used
|
||||
//~| ERROR this expression will panic at runtime
|
||||
pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
|
||||
//~^ ERROR this constant cannot be used
|
||||
pub const C: u8 = 200u8 * 4; //~ ERROR const_err
|
||||
//~^ ERROR this constant cannot be used
|
||||
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
|
||||
//~^ ERROR this constant cannot be used
|
||||
pub const E: u8 = [5u8][1]; //~ ERROR const_err
|
||||
//~| ERROR this constant cannot be used
|
||||
|
||||
fn main() {
|
||||
let _a = A;
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@
|
|||
#![deny(const_err)]
|
||||
|
||||
pub const A: i8 = -std::i8::MIN;
|
||||
//~^ ERROR E0080
|
||||
//~| ERROR attempt to negate with overflow
|
||||
//~| ERROR this expression will panic at runtime
|
||||
//~| ERROR this constant cannot be used
|
||||
//~^ ERROR this constant cannot be used
|
||||
pub const B: i8 = A;
|
||||
//~^ ERROR const_err
|
||||
//~| ERROR const_err
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ fn black_box<T>(_: T) {
|
|||
// Make sure that the two uses get two errors.
|
||||
const FOO: u8 = [5u8][1];
|
||||
//~^ ERROR constant evaluation error
|
||||
//~| ERROR constant evaluation error
|
||||
//~| index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
fn main() {
|
||||
black_box((FOO, FOO));
|
||||
//~^ ERROR referenced constant has errors
|
||||
//~| ERROR could not evaluate constant
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,54 +25,46 @@ const VALS_I8: (i8,) =
|
|||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i8::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_I16: (i16,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i16::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_I32: (i32,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i32::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_I64: (i64,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i64::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_U8: (u8,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
u8::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_U16: (u16,) = (
|
||||
//~^ ERROR this constant cannot be used
|
||||
u16::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_U32: (u32,) = (
|
||||
//~^ ERROR this constant cannot be used
|
||||
u32::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
const VALS_U64: (u64,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
u64::MIN - 1,
|
||||
//~^ ERROR attempt to subtract with overflow
|
||||
);
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -25,54 +25,46 @@ const VALS_I8: (i8,) =
|
|||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i8::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_I16: (i16,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i16::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_I32: (i32,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i32::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_I64: (i64,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i64::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_U8: (u8,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
u8::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_U16: (u16,) = (
|
||||
//~^ ERROR this constant cannot be used
|
||||
u16::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_U32: (u32,) = (
|
||||
//~^ ERROR this constant cannot be used
|
||||
u32::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
const VALS_U64: (u64,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
u64::MAX + 1,
|
||||
//~^ ERROR attempt to add with overflow
|
||||
);
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -25,54 +25,46 @@ const VALS_I8: (i8,) =
|
|||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i8::MIN * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_I16: (i16,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i16::MIN * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_I32: (i32,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i32::MIN * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_I64: (i64,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
i64::MIN * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_U8: (u8,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
u8::MAX * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_U16: (u16,) = (
|
||||
//~^ ERROR this constant cannot be used
|
||||
u16::MAX * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_U32: (u32,) = (
|
||||
//~^ ERROR this constant cannot be used
|
||||
u32::MAX * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
const VALS_U64: (u64,) =
|
||||
//~^ ERROR this constant cannot be used
|
||||
(
|
||||
u64::MAX * 2,
|
||||
//~^ ERROR attempt to multiply with overflow
|
||||
);
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
warning: attempt to subtract with overflow
|
||||
--> $DIR/conditional_array_execution.rs:15:19
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/conditional_array_execution.rs:11:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/conditional_array_execution.rs:15:1
|
||||
|
|
||||
|
|
@ -17,9 +5,15 @@ 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)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: referenced constant
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
warning: referenced constant has errors
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ----- attempt to subtract with overflow
|
||||
|
|
@ -28,13 +22,13 @@ LL | println!("{}", FOO);
|
|||
| ^^^
|
||||
|
||||
warning: this expression will panic at runtime
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | println!("{}", FOO);
|
||||
| ^^^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/conditional_array_execution.rs:20:5
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/conditional_array_execution.rs:19:5
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ----- attempt to subtract with overflow
|
||||
|
|
@ -45,7 +39,7 @@ LL | println!("{}", FOO);
|
|||
= 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[E0080]: erroneous constant used
|
||||
--> $DIR/conditional_array_execution.rs:20:5
|
||||
--> $DIR/conditional_array_execution.rs:19:5
|
||||
|
|
||||
LL | println!("{}", FOO);
|
||||
| ^^^^^^^^^^^^^^^---^^
|
||||
|
|
@ -54,8 +48,8 @@ LL | println!("{}", FOO);
|
|||
|
|
||||
= 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[E0080]: referenced constant
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ----- attempt to subtract with overflow
|
||||
|
|
@ -64,7 +58,7 @@ LL | println!("{}", FOO);
|
|||
| ^^^
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | println!("{}", FOO);
|
||||
| ^^^ referenced constant has errors
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@
|
|||
const X: u32 = 5;
|
||||
const Y: u32 = 6;
|
||||
const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
//~| WARN this constant cannot be used
|
||||
//~^ WARN this constant cannot be used
|
||||
|
||||
fn main() {
|
||||
println!("{}", FOO);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
warning: attempt to subtract with overflow
|
||||
--> $DIR/conditional_array_execution.rs:15:19
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/conditional_array_execution.rs:11:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/conditional_array_execution.rs:15:1
|
||||
|
|
||||
|
|
@ -17,9 +5,15 @@ 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)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: referenced constant
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
warning: referenced constant has errors
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ----- attempt to subtract with overflow
|
||||
|
|
@ -28,13 +22,13 @@ LL | println!("{}", FOO);
|
|||
| ^^^
|
||||
|
||||
warning: this expression will panic at runtime
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | println!("{}", FOO);
|
||||
| ^^^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ----- attempt to subtract with overflow
|
||||
|
|
@ -43,7 +37,7 @@ LL | println!("{}", FOO);
|
|||
| ^^^
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/conditional_array_execution.rs:20:20
|
||||
--> $DIR/conditional_array_execution.rs:19:20
|
||||
|
|
||||
LL | println!("{}", FOO);
|
||||
| ^^^ referenced constant has errors
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
warning: attempt to subtract with overflow
|
||||
--> $DIR/issue-43197.rs:20:20
|
||||
warning: this constant cannot be used
|
||||
--> $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
|
||||
|
|
@ -11,29 +13,15 @@ LL | #![warn(const_err)]
|
|||
| ^^^^^^^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/issue-43197.rs:20:5
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| ^^^^^^^^^^^^^^^---^
|
||||
| |
|
||||
| attempt to subtract with overflow
|
||||
|
||||
warning: attempt to subtract with overflow
|
||||
--> $DIR/issue-43197.rs:23:24
|
||||
|
|
||||
LL | const Y: u32 = foo(0-1);
|
||||
| ^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/issue-43197.rs:23:5
|
||||
--> $DIR/issue-43197.rs:22:5
|
||||
|
|
||||
LL | const Y: u32 = foo(0-1);
|
||||
| ^^^^^^^^^^^^^^^^^^^---^^
|
||||
| |
|
||||
| attempt to subtract with overflow
|
||||
|
||||
warning: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
warning: referenced constant has errors
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| --- attempt to subtract with overflow
|
||||
|
|
@ -42,28 +30,28 @@ LL | println!("{} {}", X, Y);
|
|||
| ^
|
||||
|
||||
warning: this expression will panic at runtime
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
||||
warning: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:26
|
||||
warning: referenced constant has errors
|
||||
--> $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);
|
||||
| ^
|
||||
|
||||
warning: this expression will panic at runtime
|
||||
--> $DIR/issue-43197.rs:26:26
|
||||
--> $DIR/issue-43197.rs:24:26
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:5
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-43197.rs:24:5
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| --- attempt to subtract with overflow
|
||||
|
|
@ -74,7 +62,7 @@ LL | println!("{} {}", X, Y);
|
|||
= 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[E0080]: erroneous constant used
|
||||
--> $DIR/issue-43197.rs:26:5
|
||||
--> $DIR/issue-43197.rs:24:5
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^^^^^^^^^^^^^^^^^^-^^^^^
|
||||
|
|
@ -83,23 +71,23 @@ LL | println!("{} {}", X, Y);
|
|||
|
|
||||
= 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[E0080]: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:26
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $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:26:26
|
||||
--> $DIR/issue-43197.rs:24:26
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| --- attempt to subtract with overflow
|
||||
|
|
@ -108,7 +96,7 @@ LL | println!("{} {}", X, Y);
|
|||
| ^
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
|
|
|||
|
|
@ -18,11 +18,9 @@ const fn foo(x: u32) -> u32 {
|
|||
|
||||
fn main() {
|
||||
const X: u32 = 0-1;
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
//~| WARN this constant cannot be used
|
||||
//~^ WARN this constant cannot be used
|
||||
const Y: u32 = foo(0-1);
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
//~| WARN this constant cannot be used
|
||||
//~^ WARN this constant cannot be used
|
||||
println!("{} {}", X, Y);
|
||||
//~^ WARN this expression will panic at runtime
|
||||
//~| WARN this expression will panic at runtime
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
warning: attempt to subtract with overflow
|
||||
--> $DIR/issue-43197.rs:20:20
|
||||
warning: this constant cannot be used
|
||||
--> $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
|
||||
|
|
@ -11,29 +13,15 @@ LL | #![warn(const_err)]
|
|||
| ^^^^^^^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/issue-43197.rs:20:5
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| ^^^^^^^^^^^^^^^---^
|
||||
| |
|
||||
| attempt to subtract with overflow
|
||||
|
||||
warning: attempt to subtract with overflow
|
||||
--> $DIR/issue-43197.rs:23:24
|
||||
|
|
||||
LL | const Y: u32 = foo(0-1);
|
||||
| ^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/issue-43197.rs:23:5
|
||||
--> $DIR/issue-43197.rs:22:5
|
||||
|
|
||||
LL | const Y: u32 = foo(0-1);
|
||||
| ^^^^^^^^^^^^^^^^^^^---^^
|
||||
| |
|
||||
| attempt to subtract with overflow
|
||||
|
||||
warning: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
warning: referenced constant has errors
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| --- attempt to subtract with overflow
|
||||
|
|
@ -42,43 +30,43 @@ LL | println!("{} {}", X, Y);
|
|||
| ^
|
||||
|
||||
warning: this expression will panic at runtime
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
||||
warning: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:26
|
||||
warning: referenced constant has errors
|
||||
--> $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);
|
||||
| ^
|
||||
|
||||
warning: this expression will panic at runtime
|
||||
--> $DIR/issue-43197.rs:26:26
|
||||
--> $DIR/issue-43197.rs:24:26
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:26
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $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:26:26
|
||||
--> $DIR/issue-43197.rs:24:26
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | const X: u32 = 0-1;
|
||||
| --- attempt to subtract with overflow
|
||||
|
|
@ -87,7 +75,7 @@ LL | println!("{} {}", X, Y);
|
|||
| ^
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/issue-43197.rs:26:23
|
||||
--> $DIR/issue-43197.rs:24:23
|
||||
|
|
||||
LL | println!("{} {}", X, Y);
|
||||
| ^ referenced constant has errors
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0080]: referenced constant
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-44578.rs:35:5
|
||||
|
|
||||
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
|
||||
|
|
@ -19,7 +19,7 @@ LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
|
|||
|
|
||||
= 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[E0080]: referenced constant
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-44578.rs:35:20
|
||||
|
|
||||
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0080]: referenced constant
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-44578.rs:35:20
|
||||
|
|
||||
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0080]: referenced constant
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-50814-2.rs:26:5
|
||||
|
|
||||
LL | const BAR: usize = [5, 6, 7][T::BOO];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0080]: referenced constant
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/issue-50814.rs:27:5
|
||||
|
|
||||
LL | const MAX: u8 = A::MAX + B::MAX;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
pub const Z: u32 = 0 - 1;
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
//~| WARN this constant cannot be used
|
||||
//~^ WARN this constant cannot be used
|
||||
|
||||
pub type Foo = [i32; 0 - 1];
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
warning: attempt to subtract with overflow
|
||||
--> $DIR/pub_const_err.rs:16:20
|
||||
|
|
||||
LL | pub const Z: u32 = 0 - 1;
|
||||
| ^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/pub_const_err.rs:12:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/pub_const_err.rs:16:1
|
||||
|
|
||||
|
|
@ -17,15 +5,21 @@ LL | pub const Z: u32 = 0 - 1;
|
|||
| ^^^^^^^^^^^^^^^^^^^-----^
|
||||
| |
|
||||
| attempt to subtract with overflow
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/pub_const_err.rs:12:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: attempt to subtract with overflow
|
||||
--> $DIR/pub_const_err.rs:20:22
|
||||
--> $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:20:22
|
||||
--> $DIR/pub_const_err.rs:19:22
|
||||
|
|
||||
LL | pub type Foo = [i32; 0 - 1];
|
||||
| ^^^^^ attempt to subtract with overflow
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
#![warn(const_err)]
|
||||
|
||||
pub const Z: u32 = 0 - 1;
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
//~| WARN this constant cannot be used
|
||||
//~^ WARN this constant cannot be used
|
||||
|
||||
pub type Foo = [i32; 0 - 1];
|
||||
//~^ WARN attempt to subtract with overflow
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
warning: attempt to subtract with overflow
|
||||
--> $DIR/pub_const_err_bin.rs:14:20
|
||||
|
|
||||
LL | pub const Z: u32 = 0 - 1;
|
||||
| ^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/pub_const_err_bin.rs:12:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: this constant cannot be used
|
||||
--> $DIR/pub_const_err_bin.rs:14:1
|
||||
|
|
||||
|
|
@ -17,15 +5,21 @@ LL | pub const Z: u32 = 0 - 1;
|
|||
| ^^^^^^^^^^^^^^^^^^^-----^
|
||||
| |
|
||||
| attempt to subtract with overflow
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/pub_const_err_bin.rs:12:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: attempt to subtract with overflow
|
||||
--> $DIR/pub_const_err_bin.rs:18:22
|
||||
--> $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:18:22
|
||||
--> $DIR/pub_const_err_bin.rs:17:22
|
||||
|
|
||||
LL | pub type Foo = [i32; 0 - 1];
|
||||
| ^^^^^ attempt to subtract with overflow
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@
|
|||
const ONE: usize = 1;
|
||||
const TWO: usize = 2;
|
||||
const LEN: usize = ONE - TWO;
|
||||
//~^ ERROR E0080
|
||||
//~| ERROR attempt to subtract with overflow
|
||||
|
||||
fn main() {
|
||||
let a: [i8; LEN] = unimplemented!();
|
||||
//~^ ERROR E0080
|
||||
//~| ERROR E0080
|
||||
//~| ERROR E0080
|
||||
//~| ERROR E0080
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
error: attempt to subtract with overflow
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:17:20
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:20:17
|
||||
|
|
||||
LL | const LEN: usize = ONE - TWO;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: #[deny(const_err)] on by default
|
||||
| --------- attempt to subtract with overflow
|
||||
...
|
||||
LL | let a: [i8; LEN] = unimplemented!();
|
||||
| ^^^
|
||||
|
||||
error[E0080]: constant evaluation error
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:17:20
|
||||
error[E0080]: could not evaluate constant
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:20:17
|
||||
|
|
||||
LL | const LEN: usize = ONE - TWO;
|
||||
| ^^^^^^^^^ attempt to subtract with overflow
|
||||
LL | let a: [i8; LEN] = unimplemented!();
|
||||
| ^^^ referenced constant has errors
|
||||
|
||||
error[E0080]: referenced constant
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:22:12
|
||||
error[E0080]: referenced constant has errors
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:20:12
|
||||
|
|
||||
LL | const LEN: usize = ONE - TWO;
|
||||
| --------- attempt to subtract with overflow
|
||||
|
|
@ -22,7 +23,7 @@ LL | let a: [i8; LEN] = unimplemented!();
|
|||
| ^^^^^^^^^
|
||||
|
||||
error[E0080]: could not evaluate constant expression
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:22:12
|
||||
--> $DIR/const-len-underflow-separate-spans.rs:20:12
|
||||
|
|
||||
LL | let a: [i8; LEN] = unimplemented!();
|
||||
| ^^^^^---^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue