diff --git a/RELEASES.md b/RELEASES.md index 068e9e7263e7d..fba68ce043e26 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -56,7 +56,6 @@ Stabilized APIs - [`Take::set_limit`] - [`hint::unreachable_unchecked`] - [`os::unix::process::parent_id`] -- [`process::id`] - [`ptr::swap_nonoverlapping`] - [`slice::rsplit_mut`] - [`slice::rsplit`] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index e74e527927d7b..0cbdbc4ad663a 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1642,8 +1642,8 @@ impl [T] { /// [`split_at_mut`]: #method.split_at_mut #[stable(feature = "copy_from_slice", since = "1.9.0")] pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy { - assert!(self.len() == src.len(), - "destination and source slices have different lengths"); + assert_eq!(self.len(), src.len(), + "destination and source slices have different lengths"); unsafe { ptr::copy_nonoverlapping( src.as_ptr(), self.as_mut_ptr(), self.len()); diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 33322993b1db6..6cc61d748001a 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -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), diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 55bcaad1a4ea2..8391cc6d9ba99 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -364,11 +364,11 @@ impl_stable_hash_for!(struct ty::FieldDef { }); impl<'a, 'gcx> HashStable> -for ::middle::const_val::ConstVal<'gcx> { +for ::mir::interpret::ConstValue<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use middle::const_val::ConstVal::*; + use mir::interpret::ConstValue::*; mem::discriminant(self).hash_stable(hcx, hasher); @@ -377,23 +377,6 @@ for ::middle::const_val::ConstVal<'gcx> { def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); } - Value(ref value) => { - value.hash_stable(hcx, hasher); - } - } - } -} - -impl<'a, 'gcx> HashStable> -for ::mir::interpret::ConstValue<'gcx> { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - use mir::interpret::ConstValue::*; - - mem::discriminant(self).hash_stable(hcx, hasher); - - match *self { 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> -for ::middle::const_val::ErrKind<'gcx> { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - 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 | diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 102efe2bef3f7..c500800a30f9c 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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; diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs deleted file mode 100644 index 2fa77be644e31..0000000000000 --- a/src/librustc/middle/const_val.rs +++ /dev/null @@ -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 or the MIT license -// , 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>, -} - -#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] -pub enum ErrKind<'tcx> { - - CouldNotResolve, - TypeckError, - CheckMatchError, - Miri(::mir::interpret::EvalError<'tcx>, Vec), -} - -#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] -pub struct FrameInfo { - pub span: Span, - pub location: String, - pub lint_root: Option, -} - -#[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> - { - 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, - as_err: bool, - ) -> Option> { - 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) -} diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index bf5bae6b20c42..86427bb2382cb 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -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>>; + +#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +pub struct ConstEvalErr<'tcx> { + pub span: Span, + pub error: ::mir::interpret::EvalError<'tcx>, + pub stacktrace: Vec, +} + +#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +pub struct FrameInfo { + pub span: Span, + pub location: String, + pub lint_root: Option, +} + +impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { + pub fn struct_error(&self, + tcx: TyCtxtAt<'a, 'gcx, 'tcx>, + message: &str) + -> Option> + { + 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, + ) -> Option> { + 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>), 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", diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 6bd5814799ae0..018c2446054be 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -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}; diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 9e3d4e60603ec..24595c9328208 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -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 { 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 { match *self { - ConstValue::ByRef(..) => None, + ConstValue::Unevaluated(..) | + ConstValue::ByRef(..) | ConstValue::ScalarPair(..) => None, ConstValue::Scalar(val) => Some(val), } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ee6cb398acdce..2198e3f6b318e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -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(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) } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index b3f56d4de6534..e97171c481f1d 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -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())) ) } }, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index c7e55fa574f94..0290f2e3b13f0 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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>), Overflow, } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 97b15048b48f6..1052d029e0d64 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -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() { diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 8d10195941e0d..a67383fb79aa0 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -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() { diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index d24c84b2556f8..39e358803cbe8 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -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? } } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index e3fbadc271206..3718c436b3a00 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -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); } } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 307e1b238386c..f55a512908499 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -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) { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d8fa978a6a07c..1f647d811b089 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -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(); diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index eadfc62244f81..229caeb95d621 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -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) } } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index cad3a6586829e..8423b02ee7582 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -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 } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 178ee7cf8e9ac..77644cdf02b11 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -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> { diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 7603ed7102327..265c6aee39726 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -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) { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 79a6311185076..a648dc6e7e788 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -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 { - 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 { - 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 { @@ -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>(&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), } } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 186ebd73b4cc5..996ebd722fd4d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -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,15 +1870,15 @@ impl<'tcx> Const<'tcx> { ty: Ty<'tcx>, ) -> &'tcx Self { tcx.mk_const(Const { - val: ConstVal::Unevaluated(def_id, substs), + val: ConstValue::Unevaluated(def_id, substs), ty, }) } #[inline] - pub fn from_const_val( + pub fn from_const_value( tcx: TyCtxt<'_, '_, 'tcx>, - val: ConstVal<'tcx>, + val: ConstValue<'tcx>, ty: Ty<'tcx>, ) -> &'tcx Self { tcx.mk_const(Const { @@ -1887,15 +1887,6 @@ impl<'tcx> Const<'tcx> { }) } - #[inline] - pub fn from_const_value( - tcx: TyCtxt<'_, '_, 'tcx>, - val: ConstValue<'tcx>, - ty: Ty<'tcx>, - ) -> &'tcx Self { - Self::from_const_val(tcx, ConstVal::Value(val), ty) - } - #[inline] pub fn from_byval_value( tcx: TyCtxt<'_, '_, 'tcx>, @@ -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 { - match self.val { - ConstVal::Value(val) => val.to_ptr(), - _ => None, - } + self.val.to_ptr() } #[inline] pub fn to_byval_value(&self) -> Option { - match self.val { - ConstVal::Value(val) => val.to_byval_value(), - _ => None, - } + self.val.to_byval_value() } #[inline] pub fn to_scalar(&self) -> Option { - 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] diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index ebe88d60ed12f..d12f73144269b 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -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); } diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 62fed1ecb668a..5376acca0d8cd 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -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); - - 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)); - } + 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)); } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index ff6d711cef0c8..deb8ac691fb3b 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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, "]") } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 322924535d1f7..a4709739a23dd 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -1381,7 +1381,6 @@ mod temp_stable_hash_impls { fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec) { 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) { }; 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()) } diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index 7c1035e2fcb88..bbe0e34b48f26 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -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> + -> Result>> { 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, ConstEvalErr<'tcx>> { + ) -> Result<&'tcx ty::Const<'tcx>, Lrc>> { 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, ConstEvalErr<'tcx>> { + ) -> Result<&'tcx ty::Const<'tcx>, Lrc>> { 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, _> = (0..fields).map(|field| { + let values: Result, 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( diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 9f32b41cb13e7..3d3a4400bd810 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -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, ConstEvalErr<'tcx>> { - let layout = bx.cx.layout_of(ty); + val: &'tcx ty::Const<'tcx>) + -> Result, Lrc>> { + 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 { .. } => { diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 41024e6020273..83361ea57c371 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -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 { 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); diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 19b3654d2c7dc..e04cdcfa02773 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -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(); diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 3f3e29a808a4f..4d0e3e826e878 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -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, _) => { diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 592c9dbe6ffe4..35422b11bd733 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -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, 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() }) } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ea667273ecead..6dc65a2404d11 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -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>> { diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index ad571fbe90d5d..9e5b6be3e9122 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -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) }) } diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 8a2a78daa3570..8320add715769 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -95,9 +95,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { // These ops can have an RHS with a different numeric type. if right_kind.is_int() && (bin_op == Shl || bin_op == Shr) { let signed = left_layout.abi.is_signed(); + let mut oflo = (r as u32 as u128) != r; let mut r = r as u32; let size = left_layout.size.bits() as u32; - let oflo = r >= size; + oflo |= r >= size; if oflo { r %= size; } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a65ee065ca68f..3a046cd800a3e 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -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); } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2438281508461..3b3c28f6ae265 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -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> { - 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> { 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 } => { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 6448ba17e3464..144ebce76e14c 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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() { diff --git a/src/librustc_target/spec/asmjs_unknown_emscripten.rs b/src/librustc_target/spec/asmjs_unknown_emscripten.rs index e2cf714f0ead3..4e716fb207fab 100644 --- a/src/librustc_target/spec/asmjs_unknown_emscripten.rs +++ b/src/librustc_target/spec/asmjs_unknown_emscripten.rs @@ -16,7 +16,9 @@ pub fn target() -> Result { vec!["-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(), "-s".to_string(), - "ABORTING_MALLOC=0".to_string()]); + "ABORTING_MALLOC=0".to_string(), + "-s".to_string(), + "WASM=0".to_string()]); let opts = TargetOptions { dynamic_linking: false, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 76219c6971b22..e276dcff0601d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1203,9 +1203,14 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> "supposed to be part of a block tail expression, but the \ expression is empty"); }); - fcx.suggest_mismatched_types_on_tail(&mut db, expr, - expected, found, - cause.span, blk_id); + fcx.suggest_mismatched_types_on_tail( + &mut db, + expr, + expected, + found, + cause.span, + blk_id, + ); } _ => { db = fcx.report_mismatched_types(cause, expected, found, err); diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 8582eb3fbd87c..08d8dd2e498b6 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::iter; - use check::FnCtxt; use rustc::infer::InferOk; use rustc::traits::ObligationCause; @@ -140,25 +138,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - if let Some((sp, msg, suggestion)) = self.check_ref(expr, checked_ty, expected) { - err.span_suggestion(sp, msg, suggestion); - } else if !self.check_for_cast(&mut err, expr, expr_ty, expected) { - let methods = self.get_conversion_methods(expr.span, expected, checked_ty); - if let Ok(expr_text) = self.tcx.sess.codemap().span_to_snippet(expr.span) { - let suggestions = iter::repeat(expr_text).zip(methods.iter()) - .map(|(receiver, method)| format!("{}.{}()", receiver, method.ident)) - .collect::>(); - if !suggestions.is_empty() { - err.span_suggestions(expr.span, - "try using a conversion method", - suggestions); - } - } - } + self.suggest_ref_or_into(&mut err, expr, expected, expr_ty); + (expected, Some(err)) } - fn get_conversion_methods(&self, span: Span, expected: Ty<'tcx>, checked_ty: Ty<'tcx>) + pub fn get_conversion_methods(&self, span: Span, expected: Ty<'tcx>, checked_ty: Ty<'tcx>) -> Vec { let mut methods = self.probe_for_return_type(span, probe::Mode::MethodCall, @@ -261,19 +246,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// In addition of this check, it also checks between references mutability state. If the /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with /// `&mut`!". - fn check_ref(&self, + pub fn check_ref(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) -> Option<(Span, &'static str, String)> { - let sp = expr.span; + let cm = self.sess().codemap(); + // Use the callsite's span if this is a macro call. #41858 + let sp = cm.call_span_if_macro(expr.span); + if !cm.span_to_filename(sp).is_real() { + return None; + } + match (&expected.sty, &checked_ty.sty) { (&ty::TyRef(_, exp, _), &ty::TyRef(_, check, _)) => match (&exp.sty, &check.sty) { (&ty::TyStr, &ty::TyArray(arr, _)) | (&ty::TyStr, &ty::TySlice(arr)) if arr == self.tcx.types.u8 => { if let hir::ExprLit(_) = expr.node { - let sp = self.sess().codemap().call_span_if_macro(expr.span); - if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { + if let Ok(src) = cm.span_to_snippet(sp) { return Some((sp, "consider removing the leading `b`", src[1..].to_string())); @@ -283,8 +273,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (&ty::TyArray(arr, _), &ty::TyStr) | (&ty::TySlice(arr), &ty::TyStr) if arr == self.tcx.types.u8 => { if let hir::ExprLit(_) = expr.node { - let sp = self.sess().codemap().call_span_if_macro(expr.span); - if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { + if let Ok(src) = cm.span_to_snippet(sp) { return Some((sp, "consider adding a leading `b`", format!("b{}", src))); @@ -311,9 +300,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { checked_ty), }; if self.can_coerce(ref_ty, expected) { - // Use the callsite's span if this is a macro call. #41858 - let sp = self.sess().codemap().call_span_if_macro(expr.span); - if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { + if let Ok(src) = cm.span_to_snippet(sp) { let sugg_expr = match expr.node { // parenthesize if needed (Issue #46756) hir::ExprCast(_, _) | hir::ExprBinary(_, _, _) => format!("({})", src), _ => src, @@ -342,11 +329,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // a macro; if so, it's hard to extract the text and make a good // suggestion, so don't bother.) if self.infcx.can_sub(self.param_env, checked, &expected).is_ok() && - expr.span.ctxt().outer().expn_info().is_none() { + sp.ctxt().outer().expn_info().is_none() { match expr.node { // Maybe remove `&`? hir::ExprAddrOf(_, ref expr) => { - if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(expr.span) { + if !cm.span_to_filename(expr.span).is_real() { + return None; + } + if let Ok(code) = cm.span_to_snippet(expr.span) { return Some((sp, "consider removing the borrow", code)); } } @@ -355,9 +345,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => { if !self.infcx.type_moves_by_default(self.param_env, checked, - expr.span) { - let sp = self.sess().codemap().call_span_if_macro(expr.span); - if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(sp) { + sp) { + let sp = cm.call_span_if_macro(sp); + if let Ok(code) = cm.span_to_snippet(sp) { return Some((sp, "consider dereferencing the borrow", format!("*{}", code))); @@ -372,7 +362,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None } - fn check_for_cast(&self, + pub fn check_for_cast(&self, err: &mut DiagnosticBuilder<'tcx>, expr: &hir::Expr, checked_ty: Ty<'tcx>, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f8c4bfc9ad723..0185d00518699 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -116,6 +116,7 @@ use rustc_data_structures::sync::Lrc; use std::collections::hash_map::Entry; use std::cmp; use std::fmt::Display; +use std::iter; use std::mem::replace; use std::ops::{self, Deref}; use rustc_target::spec::abi::Abi; @@ -4539,10 +4540,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { cause_span: Span, blk_id: ast::NodeId) { self.suggest_missing_semicolon(err, expression, expected, cause_span); - if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); } + self.suggest_ref_or_into(err, expression, expected, found); + } + + pub fn suggest_ref_or_into( + &self, + err: &mut DiagnosticBuilder<'tcx>, + expr: &hir::Expr, + expected: Ty<'tcx>, + found: Ty<'tcx>, + ) { + if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) { + err.span_suggestion(sp, msg, suggestion); + } else if !self.check_for_cast(err, expr, found, expected) { + let methods = self.get_conversion_methods(expr.span, expected, found); + if let Ok(expr_text) = self.sess().codemap().span_to_snippet(expr.span) { + let suggestions = iter::repeat(expr_text).zip(methods.iter()) + .map(|(receiver, method)| format!("{}.{}()", receiver, method.ident)) + .collect::>(); + if !suggestions.is_empty() { + err.span_suggestions(expr.span, "try using a conversion method", suggestions); + } + } + } } /// A common error is to forget to add a semicolon at the end of a block: diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e9f8aeb9ec8c5..8cdffcd558d75 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 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 diff --git a/src/test/compile-fail/const-err-early.rs b/src/test/compile-fail/const-err-early.rs index 92c6b1fd0b582..39b1b342eac31 100644 --- a/src/test/compile-fail/const-err-early.rs +++ b/src/test/compile-fail/const-err-early.rs @@ -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; diff --git a/src/test/compile-fail/const-err-multi.rs b/src/test/compile-fail/const-err-multi.rs index 4a5e78b381ed0..f2ee8a7078c7c 100644 --- a/src/test/compile-fail/const-err-multi.rs +++ b/src/test/compile-fail/const-err-multi.rs @@ -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 diff --git a/src/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs index f77603b3ebafc..8683f6a023192 100644 --- a/src/test/compile-fail/const-err.rs +++ b/src/test/compile-fail/const-err.rs @@ -23,9 +23,10 @@ fn black_box(_: 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 } diff --git a/src/test/compile-fail/const-eval-overflow2.rs b/src/test/compile-fail/const-eval-overflow2.rs index 7b5db7a4f6db0..88fc518277535 100644 --- a/src/test/compile-fail/const-eval-overflow2.rs +++ b/src/test/compile-fail/const-eval-overflow2.rs @@ -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() { diff --git a/src/test/compile-fail/const-eval-overflow2b.rs b/src/test/compile-fail/const-eval-overflow2b.rs index ce4dc72555dc0..1878daea93198 100644 --- a/src/test/compile-fail/const-eval-overflow2b.rs +++ b/src/test/compile-fail/const-eval-overflow2b.rs @@ -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() { diff --git a/src/test/compile-fail/const-eval-overflow2c.rs b/src/test/compile-fail/const-eval-overflow2c.rs index 88eb14a133019..f3d28295bf81c 100644 --- a/src/test/compile-fail/const-eval-overflow2c.rs +++ b/src/test/compile-fail/const-eval-overflow2c.rs @@ -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() { diff --git a/src/test/ui/const-eval/conditional_array_execution.nll.stderr b/src/test/ui/const-eval/conditional_array_execution.nll.stderr index 3580950854dc7..8bc302a2befa4 100644 --- a/src/test/ui/const-eval/conditional_array_execution.nll.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.nll.stderr @@ -1,8 +1,10 @@ -warning: attempt to subtract with overflow - --> $DIR/conditional_array_execution.rs:15:19 +warning: this constant cannot be used + --> $DIR/conditional_array_execution.rs:15:1 | LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | attempt to subtract with overflow | note: lint level defined here --> $DIR/conditional_array_execution.rs:11:9 @@ -10,16 +12,8 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: this constant cannot be used - --> $DIR/conditional_array_execution.rs:15:1 - | -LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; - | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | attempt to subtract with overflow - -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 diff --git a/src/test/ui/const-eval/conditional_array_execution.rs b/src/test/ui/const-eval/conditional_array_execution.rs index ac555b25afdcd..99487eb497923 100644 --- a/src/test/ui/const-eval/conditional_array_execution.rs +++ b/src/test/ui/const-eval/conditional_array_execution.rs @@ -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); diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr index 64010c946a7f1..649da03a5e7fa 100644 --- a/src/test/ui/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.stderr @@ -1,8 +1,10 @@ -warning: attempt to subtract with overflow - --> $DIR/conditional_array_execution.rs:15:19 +warning: this constant cannot be used + --> $DIR/conditional_array_execution.rs:15:1 | LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | attempt to subtract with overflow | note: lint level defined here --> $DIR/conditional_array_execution.rs:11:9 @@ -10,16 +12,8 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: this constant cannot be used - --> $DIR/conditional_array_execution.rs:15:1 - | -LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; - | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | attempt to subtract with overflow - -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 diff --git a/src/test/ui/const-eval/issue-43197.nll.stderr b/src/test/ui/const-eval/issue-43197.nll.stderr index 3bde12ade90c3..5819e6a9254a7 100644 --- a/src/test/ui/const-eval/issue-43197.nll.stderr +++ b/src/test/ui/const-eval/issue-43197.nll.stderr @@ -1,15 +1,3 @@ -warning: attempt to subtract with overflow - --> $DIR/issue-43197.rs:20:20 - | -LL | const X: u32 = 0-1; - | ^^^ - | -note: lint level defined here - --> $DIR/issue-43197.rs:11:9 - | -LL | #![warn(const_err)] - | ^^^^^^^^^ - warning: this constant cannot be used --> $DIR/issue-43197.rs:20:5 | @@ -17,23 +5,23 @@ 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); - | ^^^ +note: lint level defined here + --> $DIR/issue-43197.rs:11:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ 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 diff --git a/src/test/ui/const-eval/issue-43197.rs b/src/test/ui/const-eval/issue-43197.rs index 03aa65eb27467..9304af7b811cf 100644 --- a/src/test/ui/const-eval/issue-43197.rs +++ b/src/test/ui/const-eval/issue-43197.rs @@ -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 diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr index 071d878730744..bf864d81ea3ca 100644 --- a/src/test/ui/const-eval/issue-43197.stderr +++ b/src/test/ui/const-eval/issue-43197.stderr @@ -1,15 +1,3 @@ -warning: attempt to subtract with overflow - --> $DIR/issue-43197.rs:20:20 - | -LL | const X: u32 = 0-1; - | ^^^ - | -note: lint level defined here - --> $DIR/issue-43197.rs:11:9 - | -LL | #![warn(const_err)] - | ^^^^^^^^^ - warning: this constant cannot be used --> $DIR/issue-43197.rs:20:5 | @@ -17,23 +5,23 @@ 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); - | ^^^ +note: lint level defined here + --> $DIR/issue-43197.rs:11:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ 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 diff --git a/src/test/ui/const-eval/issue-44578.nll.stderr b/src/test/ui/const-eval/issue-44578.nll.stderr index ad4f08966c012..eeb152e00ea47 100644 --- a/src/test/ui/const-eval/issue-44578.nll.stderr +++ b/src/test/ui/const-eval/issue-44578.nll.stderr @@ -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!("{}", 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]; diff --git a/src/test/ui/const-eval/issue-44578.stderr b/src/test/ui/const-eval/issue-44578.stderr index 28a723a069edf..06174f37dcad1 100644 --- a/src/test/ui/const-eval/issue-44578.stderr +++ b/src/test/ui/const-eval/issue-44578.stderr @@ -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]; diff --git a/src/test/ui/const-eval/issue-50814-2.stderr b/src/test/ui/const-eval/issue-50814-2.stderr index 3c59cb0e2bc72..1e37e9498120f 100644 --- a/src/test/ui/const-eval/issue-50814-2.stderr +++ b/src/test/ui/const-eval/issue-50814-2.stderr @@ -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]; diff --git a/src/test/ui/const-eval/issue-50814.stderr b/src/test/ui/const-eval/issue-50814.stderr index 145279ccc033d..16160207c573b 100644 --- a/src/test/ui/const-eval/issue-50814.stderr +++ b/src/test/ui/const-eval/issue-50814.stderr @@ -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; diff --git a/src/test/ui/const-eval/pub_const_err.rs b/src/test/ui/const-eval/pub_const_err.rs index ef8fdb33d748a..b7cfa949bac95 100644 --- a/src/test/ui/const-eval/pub_const_err.rs +++ b/src/test/ui/const-eval/pub_const_err.rs @@ -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 diff --git a/src/test/ui/const-eval/pub_const_err.stderr b/src/test/ui/const-eval/pub_const_err.stderr index 352289417547e..fa3a79a5f1790 100644 --- a/src/test/ui/const-eval/pub_const_err.stderr +++ b/src/test/ui/const-eval/pub_const_err.stderr @@ -1,8 +1,10 @@ -warning: attempt to subtract with overflow - --> $DIR/pub_const_err.rs:16:20 +warning: this constant cannot be used + --> $DIR/pub_const_err.rs:16:1 | LL | pub const Z: u32 = 0 - 1; - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^-----^ + | | + | attempt to subtract with overflow | note: lint level defined here --> $DIR/pub_const_err.rs:12:9 @@ -10,22 +12,14 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: this constant cannot be used - --> $DIR/pub_const_err.rs:16:1 - | -LL | pub const Z: u32 = 0 - 1; - | ^^^^^^^^^^^^^^^^^^^-----^ - | | - | attempt to subtract with overflow - 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 diff --git a/src/test/ui/const-eval/pub_const_err_bin.rs b/src/test/ui/const-eval/pub_const_err_bin.rs index f65da1d8674a2..bafa5b2f4da12 100644 --- a/src/test/ui/const-eval/pub_const_err_bin.rs +++ b/src/test/ui/const-eval/pub_const_err_bin.rs @@ -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 diff --git a/src/test/ui/const-eval/pub_const_err_bin.stderr b/src/test/ui/const-eval/pub_const_err_bin.stderr index a6db2176011d5..73229c60d14db 100644 --- a/src/test/ui/const-eval/pub_const_err_bin.stderr +++ b/src/test/ui/const-eval/pub_const_err_bin.stderr @@ -1,8 +1,10 @@ -warning: attempt to subtract with overflow - --> $DIR/pub_const_err_bin.rs:14:20 +warning: this constant cannot be used + --> $DIR/pub_const_err_bin.rs:14:1 | 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 @@ -10,22 +12,14 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: this constant cannot be used - --> $DIR/pub_const_err_bin.rs:14:1 - | -LL | pub const Z: u32 = 0 - 1; - | ^^^^^^^^^^^^^^^^^^^-----^ - | | - | attempt to subtract with overflow - 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 diff --git a/src/test/ui/const-eval/shift_overflow.rs b/src/test/ui/const-eval/shift_overflow.rs new file mode 100644 index 0000000000000..a2c6ed36d30c2 --- /dev/null +++ b/src/test/ui/const-eval/shift_overflow.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Foo { + // test that we detect overflows for non-u32 discriminants + X = 1 << ((u32::max_value() as u64) + 1), //~ ERROR E0080 + Y = 42, +} + + +fn main() { +} diff --git a/src/test/ui/const-eval/shift_overflow.stderr b/src/test/ui/const-eval/shift_overflow.stderr new file mode 100644 index 0000000000000..00a748249ea0a --- /dev/null +++ b/src/test/ui/const-eval/shift_overflow.stderr @@ -0,0 +1,9 @@ +error[E0080]: could not evaluate enum discriminant + --> $DIR/shift_overflow.rs:13:9 + | +LL | X = 1 << ((u32::max_value() as u64) + 1), //~ ERROR E0080 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to shift left with overflow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs index 20b8865767459..8db1411005e57 100644 --- a/src/test/ui/const-len-underflow-separate-spans.rs +++ b/src/test/ui/const-len-underflow-separate-spans.rs @@ -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 } diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr index 630828ef8f517..cf97a0dc55578 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -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!(); | ^^^^^---^ diff --git a/src/test/ui/suggestions/str-array-assignment.stderr b/src/test/ui/suggestions/str-array-assignment.stderr index 12699d8b25f81..041bae4a42108 100644 --- a/src/test/ui/suggestions/str-array-assignment.stderr +++ b/src/test/ui/suggestions/str-array-assignment.stderr @@ -14,7 +14,10 @@ LL | fn main() { | - expected `()` because of default return type ... LL | let u: &str = if true { s[..2] } else { s }; - | ^^^^^^ expected &str, found str + | ^^^^^^ + | | + | expected &str, found str + | help: consider borrowing here: `&s[..2]` | = note: expected type `&str` found type `str`