From 6b0c2fd1d6caf3317da930912b9dc85ed92747f7 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 24 Jun 2018 20:11:56 +0200 Subject: [PATCH 01/16] Use assert_eq! in copy_from_slice This will print both lengths when the assertion fails instead of just saying that they're different. --- src/libcore/slice/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 6f4c130d8f318..e4ed5f61d1c79 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()); From 0fa166ad7f2684cecb184204141abe159b5b7b4f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 27 Jun 2018 13:47:19 +0200 Subject: [PATCH 02/16] Detect overflows of non u32 shifts --- src/librustc_mir/interpret/operator.rs | 3 ++- src/test/ui/const-eval/shift_overflow.rs | 19 +++++++++++++++++++ src/test/ui/const-eval/shift_overflow.stderr | 9 +++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/const-eval/shift_overflow.rs create mode 100644 src/test/ui/const-eval/shift_overflow.stderr 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/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`. From 58fdac638ea57f60bb2bea4b35f8fc5988df9387 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 15 Jun 2018 01:26:56 +0200 Subject: [PATCH 03/16] Simplify const error reporting --- src/librustc/middle/const_val.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 2fa77be644e31..8a824c66ec47b 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -93,14 +93,14 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { message: &str) -> Option> { - self.struct_generic(tcx, message, None, true) + 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, true); + let err = self.struct_generic(tcx, message, None); if let Some(mut err) = err { err.emit(); } @@ -115,7 +115,6 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { tcx, message, Some(lint_root), - false, ); if let Some(mut lint) = lint { lint.emit(); @@ -127,7 +126,6 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { 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, @@ -136,7 +134,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { ::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(); + inner.struct_generic(tcx, "referenced constant", lint_root)?.emit(); (miri.to_string(), frames) }, _ => (miri.to_string(), frames), @@ -145,22 +143,21 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { _ => (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 mut err = if let Some(lint_root) = lint_root { 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"); + .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, msg); for FrameInfo { span, location, .. } in frames { From 6f8fe4eaefe8fbc4f8a8d314ded0fe1a300c35f7 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 19 Jun 2018 16:40:53 +0200 Subject: [PATCH 04/16] Eliminate old CTFE's `ErrKind` --- src/librustc/ich/impls_ty.rs | 27 ++-------- src/librustc/middle/const_val.rs | 61 +++++----------------- src/librustc/mir/interpret/error.rs | 7 +++ src/librustc/traits/fulfill.rs | 6 ++- src/librustc/ty/structural_impls.rs | 22 ++------ src/librustc_mir/interpret/const_eval.rs | 16 +++--- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/interpret/memory.rs | 4 +- src/librustc_mir/monomorphize/collector.rs | 13 ++--- src/librustc_mir/transform/const_prop.rs | 4 +- 10 files changed, 50 insertions(+), 114 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 684a1d2965838..0d3ac8edbd31d 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -505,7 +505,7 @@ impl_stable_hash_for!(struct ty::Const<'tcx> { impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> { span, - kind + data }); impl_stable_hash_for!(struct ::middle::const_val::FrameInfo { @@ -514,29 +514,6 @@ impl_stable_hash_for!(struct ::middle::const_val::FrameInfo { 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 }); @@ -593,6 +570,8 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> { ReadFromReturnPointer | UnimplementedTraitSelection | TypeckError | + ResolutionFailed | + CheckMatchError | DerefFunctionPointer | ExecuteMemory | OverflowNeg | diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8a824c66ec47b..588265dffa75f 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -33,16 +33,7 @@ pub enum ConstVal<'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), + pub data: Lrc<(::mir::interpret::EvalError<'tcx>, Vec)>, } #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] @@ -69,25 +60,6 @@ impl<'a, 'tcx> ConstEvalErrDescription<'a, 'tcx> { } 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) @@ -127,24 +99,19 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> 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)?.emit(); - (miri.to_string(), frames) - }, - _ => (miri.to_string(), frames), - } - } - _ => (self.description().into_oneline().to_string(), &[]), - }; + match self.data.0.kind { + ::mir::interpret::EvalErrorKind::TypeckError | + ::mir::interpret::EvalErrorKind::ResolutionFailed | + ::mir::interpret::EvalErrorKind::CheckMatchError | + ::mir::interpret::EvalErrorKind::Layout(_) => return None, + ::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => { + inner.struct_generic(tcx, "referenced constant", lint_root)?.emit(); + }, + _ => {}, + } trace!("reporting const eval failure at {:?}", self.span); let mut err = if let Some(lint_root) = lint_root { - let node_id = frames + let node_id = self.data.1 .iter() .rev() .filter_map(|frame| frame.lint_root) @@ -159,8 +126,8 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { } else { struct_error(tcx, message) }; - err.span_label(self.span, msg); - for FrameInfo { span, location, .. } in frames { + err.span_label(self.span, self.data.0.to_string()); + for FrameInfo { span, location, .. } in &self.data.1 { err.span_label(*span, format!("inside call to `{}`", location)); } Some(err) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index bf5bae6b20c42..4771875760df1 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -150,6 +150,9 @@ 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 + ResolutionFailed, + CheckMatchError, /// Cannot compute this constant because it depends on another one /// which already produced an error ReferencedConstant(ConstEvalErr<'tcx>), @@ -268,6 +271,10 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> { "there were unresolved type arguments during trait selection", TypeckError => "encountered constants with type errors, stopping evaluation", + ResolutionFailed => + "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/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index b3f56d4de6534..288634a800c61 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 middle::const_val::ConstEvalErr; +use mir::interpret::EvalErrorKind; use super::CodeAmbiguity; use super::CodeProjectionError; @@ -498,10 +499,11 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, CodeSelectionError(ConstEvalFailure(err))) } } else { + let err = EvalErrorKind::ResolutionFailed.into(); ProcessResult::Error( CodeSelectionError(ConstEvalFailure(ConstEvalErr { span: obligation.cause.span, - kind: ErrKind::CouldNotResolve.into(), + data: (err, Vec::new()).into(), })) ) } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 79a6311185076..2bc4698c44aa2 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -13,7 +13,7 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. -use middle::const_val::{self, ConstVal, ConstEvalErr}; +use middle::const_val::{ConstVal, ConstEvalErr}; use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; @@ -462,10 +462,10 @@ 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.data.0).map(|data| { ConstEvalErr { span: self.span, - kind: Lrc::new(kind), + data: Lrc::new((data, self.data.1.clone())), } }) } @@ -577,6 +577,8 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> { PathNotFound(ref v) => PathNotFound(v.clone()), UnimplementedTraitSelection => UnimplementedTraitSelection, TypeckError => TypeckError, + ResolutionFailed => ResolutionFailed, + CheckMatchError => CheckMatchError, ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?), OverflowNeg => OverflowNeg, Overflow(op) => Overflow(op), @@ -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 { diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 592c9dbe6ffe4..831b3bfd8d1ff 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::middle::const_val::{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,7 @@ pub fn value_to_const_value<'tcx>( let (frames, span) = ecx.generate_stacktrace(None); let err = ConstEvalErr { span, - kind: ErrKind::Miri(err, frames).into(), + data: (err, frames).into(), }; err.report_as_error( ecx.tcx, @@ -467,9 +465,8 @@ 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(), + data: (err, trace).into(), span, } }) @@ -540,7 +537,7 @@ 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), + data: (EvalErrorKind::CheckMatchError.into(), Vec::new()).into(), span, }); } @@ -552,7 +549,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do not continue into miri if typeck errors occurred; it will fail horribly if tables.tainted_by_errors { return Err(ConstEvalErr { - kind: Lrc::new(TypeckError), + data: (EvalErrorKind::TypeckError.into(), Vec::new()).into(), span, }); } @@ -566,9 +563,8 @@ 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(), + data: (err, trace).into(), span, }; if tcx.is_static(def_id).is_some() { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ea667273ecead..32ec48e15b47b 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -280,7 +280,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::ResolutionFailed.into()) } pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { @@ -739,7 +739,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::ResolutionFailed.into()); let fn_ptr = self.memory.create_fn_alloc(instance?); let valty = ValTy { value: Value::Scalar(fn_ptr.into()), diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index ad571fbe90d5d..3810aedb90c6a 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -285,10 +285,10 @@ 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, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index ef69cb574e07e..8e13ac3d41533 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1209,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.data.0.kind { + err.report_as_error( + tcx.at(mir.promoted[i].span), + "erroneous constant used", + ); } }, } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2438281508461..ee53cfb7b6b74 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::middle::const_val::{ConstVal, ConstEvalErr}; use rustc::ty::{TyCtxt, self, Instance}; use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult}; use interpret::EvalContext; @@ -145,7 +145,7 @@ 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(), + data: (err, frames).into(), }; err.report_as_lint( self.ecx.tcx, From 57e190c85024de27f1c8df8936e0b610a96908f5 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 25 Jun 2018 15:08:05 +0200 Subject: [PATCH 05/16] Address review comments --- src/librustc/ich/impls_ty.rs | 2 +- src/librustc/middle/const_val.rs | 2 +- src/librustc/mir/interpret/error.rs | 4 ++-- src/librustc/traits/fulfill.rs | 4 ++-- src/librustc/ty/structural_impls.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 0d3ac8edbd31d..8779d3d3f0779 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -570,7 +570,7 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> { ReadFromReturnPointer | UnimplementedTraitSelection | TypeckError | - ResolutionFailed | + TooGeneric | CheckMatchError | DerefFunctionPointer | ExecuteMemory | diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 588265dffa75f..94273287f07c5 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { ) -> Option> { match self.data.0.kind { ::mir::interpret::EvalErrorKind::TypeckError | - ::mir::interpret::EvalErrorKind::ResolutionFailed | + ::mir::interpret::EvalErrorKind::TooGeneric | ::mir::interpret::EvalErrorKind::CheckMatchError | ::mir::interpret::EvalErrorKind::Layout(_) => return None, ::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => { diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 4771875760df1..827ac7ef7fc96 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -151,7 +151,7 @@ pub enum EvalErrorKind<'tcx, O> { /// Abort in case type errors are reached TypeckError, /// Resolution can fail if we are in a too generic context - ResolutionFailed, + TooGeneric, CheckMatchError, /// Cannot compute this constant because it depends on another one /// which already produced an error @@ -271,7 +271,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> { "there were unresolved type arguments during trait selection", TypeckError => "encountered constants with type errors, stopping evaluation", - ResolutionFailed => + TooGeneric => "encountered overly generic constant", CheckMatchError => "match checking failed", diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 288634a800c61..c9021bcd410da 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -499,11 +499,11 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, CodeSelectionError(ConstEvalFailure(err))) } } else { - let err = EvalErrorKind::ResolutionFailed.into(); + let err = EvalErrorKind::TooGeneric.into(); ProcessResult::Error( CodeSelectionError(ConstEvalFailure(ConstEvalErr { span: obligation.cause.span, - data: (err, Vec::new()).into(), + data: (err, vec![]).into(), })) ) } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 2bc4698c44aa2..3ff714d89c444 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -577,7 +577,7 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> { PathNotFound(ref v) => PathNotFound(v.clone()), UnimplementedTraitSelection => UnimplementedTraitSelection, TypeckError => TypeckError, - ResolutionFailed => ResolutionFailed, + TooGeneric => TooGeneric, CheckMatchError => CheckMatchError, ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?), OverflowNeg => OverflowNeg, diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 32ec48e15b47b..ccdabe86d2252 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -280,7 +280,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::ResolutionFailed.into()) + ).ok_or_else(|| EvalErrorKind::TooGeneric.into()) } pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { @@ -739,7 +739,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::ResolutionFailed.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()), From 6e5951c7343cc1addecffb7de97b89c15a7030dd Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 25 Jun 2018 15:10:33 +0200 Subject: [PATCH 06/16] Remove unused type --- src/librustc/middle/const_val.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 94273287f07c5..c39422d21c060 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -15,11 +15,9 @@ 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>>; @@ -43,22 +41,6 @@ pub struct FrameInfo { 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 struct_error(&self, tcx: TyCtxtAt<'a, 'gcx, 'tcx>, From 6005b0ad2fc1398d7d4f757cc96eb783ee8fc1ac Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 25 Jun 2018 17:41:20 +0200 Subject: [PATCH 07/16] Move the Lrc outside the error type and name the fields --- src/librustc/ich/impls_ty.rs | 3 ++- src/librustc/middle/const_val.rs | 13 ++++++------ src/librustc/mir/interpret/error.rs | 3 ++- src/librustc/traits/fulfill.rs | 6 +++--- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/structural_impls.rs | 4 +++- src/librustc/ty/structural_impls.rs | 8 ++++---- src/librustc_codegen_llvm/mir/constant.rs | 9 +++++---- src/librustc_codegen_llvm/mir/operand.rs | 3 ++- src/librustc_mir/interpret/const_eval.rs | 23 +++++++++++++--------- src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 3 ++- 12 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 8779d3d3f0779..a8e1c04207d3d 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -505,7 +505,8 @@ impl_stable_hash_for!(struct ty::Const<'tcx> { impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> { span, - data + stacktrace, + error }); impl_stable_hash_for!(struct ::middle::const_val::FrameInfo { diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index c39422d21c060..9177b70d1a4aa 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -20,7 +20,7 @@ use syntax::ast; use rustc_data_structures::sync::Lrc; -pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; +pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc>>; #[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)] pub enum ConstVal<'tcx> { @@ -31,7 +31,8 @@ pub enum ConstVal<'tcx> { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub data: Lrc<(::mir::interpret::EvalError<'tcx>, Vec)>, + pub error: ::mir::interpret::EvalError<'tcx>, + pub stacktrace: Vec, } #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] @@ -81,7 +82,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> Option> { - match self.data.0.kind { + match self.error.kind { ::mir::interpret::EvalErrorKind::TypeckError | ::mir::interpret::EvalErrorKind::TooGeneric | ::mir::interpret::EvalErrorKind::CheckMatchError | @@ -93,7 +94,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { } trace!("reporting const eval failure at {:?}", self.span); let mut err = if let Some(lint_root) = lint_root { - let node_id = self.data.1 + let node_id = self.stacktrace .iter() .rev() .filter_map(|frame| frame.lint_root) @@ -108,8 +109,8 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { } else { struct_error(tcx, message) }; - err.span_label(self.span, self.data.0.to_string()); - for FrameInfo { span, location, .. } in &self.data.1 { + 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) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 827ac7ef7fc96..b018b2c0391ea 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -4,6 +4,7 @@ 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 @@ -155,7 +156,7 @@ pub enum EvalErrorKind<'tcx, O> { CheckMatchError, /// Cannot compute this constant because it depends on another one /// which already produced an error - ReferencedConstant(ConstEvalErr<'tcx>), + ReferencedConstant(Lrc>), GeneratorResumedAfterReturn, GeneratorResumedAfterPanic, } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index c9021bcd410da..398c99ffaf92f 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -499,12 +499,12 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, CodeSelectionError(ConstEvalFailure(err))) } } else { - let err = EvalErrorKind::TooGeneric.into(); ProcessResult::Error( CodeSelectionError(ConstEvalFailure(ConstEvalErr { span: obligation.cause.span, - data: (err, vec![]).into(), - })) + error: EvalErrorKind::TooGeneric.into(), + stacktrace: vec![], + }.into())) ) } }, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index c7e55fa574f94..88236aa8b67ec 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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/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/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 3ff714d89c444..f00ec8be195ea 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -18,7 +18,6 @@ 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.data.0).map(|data| { + tcx.lift(&self.error).map(|error| { ConstEvalErr { span: self.span, - data: Lrc::new((data, self.data.1.clone())), + stacktrace: self.stacktrace.clone(), + error, } }) } @@ -579,7 +579,7 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> { TypeckError => TypeckError, TooGeneric => TooGeneric, CheckMatchError => CheckMatchError, - ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?), + ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(&**err)?.into()), OverflowNeg => OverflowNeg, Overflow(op) => Overflow(op), DivisionByZero => DivisionByZero, diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index 7c1035e2fcb88..fc219df9b04b2 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -14,6 +14,7 @@ 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 { @@ -139,7 +140,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { &mut self, bx: &Builder<'a, 'tcx>, constant: &'tcx ty::Const<'tcx>, - ) -> Result, ConstEvalErr<'tcx>> { + ) -> Result, Lrc>> { match constant.val { ConstVal::Unevaluated(def_id, ref substs) => { let tcx = bx.tcx(); @@ -160,7 +161,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { &mut self, bx: &Builder<'a, 'tcx>, constant: &mir::Constant<'tcx>, - ) -> Result, ConstEvalErr<'tcx>> { + ) -> Result, Lrc>> { match constant.literal { mir::Literal::Promoted { index } => { let param_env = ty::ParamEnv::reveal_all(); @@ -189,7 +190,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { 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(), diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 9f32b41cb13e7..0381a5e298706 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -15,6 +15,7 @@ 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}; @@ -97,7 +98,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { pub fn from_const(bx: &Builder<'a, 'tcx>, val: ConstValue<'tcx>, ty: ty::Ty<'tcx>) - -> Result, ConstEvalErr<'tcx>> { + -> Result, Lrc>> { let layout = bx.cx.layout_of(ty); if layout.is_zst() { diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 831b3bfd8d1ff..52edd22f02765 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -104,7 +104,8 @@ pub fn value_to_const_value<'tcx>( let (frames, span) = ecx.generate_stacktrace(None); let err = ConstEvalErr { span, - data: (err, frames).into(), + error: err, + stacktrace: frames, }; err.report_as_error( ecx.tcx, @@ -466,9 +467,10 @@ pub fn const_val_field<'a, 'tcx>( result.map_err(|err| { let (trace, span) = ecx.generate_stacktrace(None); ConstEvalErr { - data: (err, trace).into(), + error: err, + stacktrace: trace, span, - } + }.into() }) } @@ -537,9 +539,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 { - data: (EvalErrorKind::CheckMatchError.into(), Vec::new()).into(), + error: EvalErrorKind::CheckMatchError.into(), + stacktrace: vec![], span, - }); + }.into()); } if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) { @@ -549,9 +552,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 { - data: (EvalErrorKind::TypeckError.into(), Vec::new()).into(), + error: EvalErrorKind::CheckMatchError.into(), + stacktrace: vec![], span, - }); + }.into()); } }; @@ -564,13 +568,14 @@ pub fn const_eval_provider<'a, 'tcx>( }).map_err(|err| { let (trace, span) = ecx.generate_stacktrace(None); let err = ConstEvalErr { - data: (err, trace).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/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 8e13ac3d41533..2d364f24b6b94 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1210,7 +1210,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Ok(val) => collect_const(tcx, val, instance.substs, output), Err(err) => { use rustc::mir::interpret::EvalErrorKind; - if let EvalErrorKind::ReferencedConstant(_) = err.data.0.kind { + if let EvalErrorKind::ReferencedConstant(_) = err.error.kind { err.report_as_error( tcx.at(mir.promoted[i].span), "erroneous constant used", diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index ee53cfb7b6b74..2233c5c798026 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -145,7 +145,8 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { let (frames, span) = self.ecx.generate_stacktrace(None); let err = ConstEvalErr { span, - data: (err, frames).into(), + error: err, + stacktrace: frames, }; err.report_as_lint( self.ecx.tcx, From 05994779ea953bdbd7fb015e1afffdd91203a1e8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 25 Jun 2018 18:46:02 +0200 Subject: [PATCH 08/16] Move everything over from `middle::const_val` to `mir::interpret` --- src/librustc/ich/impls_ty.rs | 8 +- src/librustc/lib.rs | 1 - src/librustc/middle/const_val.rs | 125 ------------------- src/librustc/mir/interpret/error.rs | 110 +++++++++++++++- src/librustc/mir/interpret/mod.rs | 5 +- src/librustc/mir/interpret/value.rs | 8 ++ src/librustc/mir/mod.rs | 2 +- src/librustc/traits/fulfill.rs | 2 +- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/project.rs | 2 +- src/librustc/traits/query/normalize.rs | 3 +- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/fold.rs | 2 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/query/mod.rs | 4 +- src/librustc/ty/relate.rs | 2 +- src/librustc/ty/structural_impls.rs | 2 +- src/librustc/ty/sty.rs | 2 +- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 2 +- src/librustc_codegen_llvm/base.rs | 2 +- src/librustc_codegen_llvm/mir/constant.rs | 2 +- src/librustc_codegen_llvm/mir/operand.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 2 +- src/librustc_mir/hair/pattern/check_match.rs | 4 +- src/librustc_mir/hair/pattern/mod.rs | 2 +- src/librustc_mir/interpret/const_eval.rs | 6 +- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/interpret/memory.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- 34 files changed, 158 insertions(+), 166 deletions(-) delete mode 100644 src/librustc/middle/const_val.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index a8e1c04207d3d..d3280a9130ea9 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -370,11 +370,11 @@ impl<'a, 'gcx> HashStable> for ty::FieldDef { } impl<'a, 'gcx> HashStable> -for ::middle::const_val::ConstVal<'gcx> { +for ::mir::interpret::ConstVal<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use middle::const_val::ConstVal::*; + use mir::interpret::ConstVal::*; mem::discriminant(self).hash_stable(hcx, hasher); @@ -503,13 +503,13 @@ 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, stacktrace, error }); -impl_stable_hash_for!(struct ::middle::const_val::FrameInfo { +impl_stable_hash_for!(struct ::mir::interpret::FrameInfo { span, lint_root, location 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 9177b70d1a4aa..0000000000000 --- a/src/librustc/middle/const_val.rs +++ /dev/null @@ -1,125 +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 syntax_pos::Span; -use syntax::ast; - -use rustc_data_structures::sync::Lrc; - -pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc>>; - -#[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 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", 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) -} diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index b018b2c0391ea..ab3fb0d2180ab 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -1,7 +1,6 @@ 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; @@ -12,6 +11,115 @@ use super::{ use backtrace::Backtrace; + +use hir::def_id::DefId; +use ty; +use ty::subst::Substs; +use ty::query::TyCtxtAt; +use mir::interpret::ConstValue; +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", 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>, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 6bd5814799ae0..bd8970f5ea69c 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, ConstVal, 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..b17b774101769 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -5,10 +5,18 @@ use ty; use super::{EvalResult, Pointer, PointerArithmetic, Allocation}; +#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)] +pub enum ConstVal<'tcx> { + Value(ConstValue<'tcx>), +} + /// 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)] 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 + 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 diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ee6cb398acdce..31d5ef2e16036 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2164,7 +2164,7 @@ impl<'tcx> Debug for Literal<'tcx> { /// Write a `ConstVal` 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; + use mir::interpret::ConstVal; match const_val.val { ConstVal::Unevaluated(..) => write!(fmt, "{:?}", const_val), ConstVal::Value(val) => { diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 398c99ffaf92f..e97171c481f1d 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -16,7 +16,7 @@ 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; +use mir::interpret::ConstEvalErr; use mir::interpret::EvalErrorKind; use super::CodeAmbiguity; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 88236aa8b67ec..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}; diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 82f351782bbcd..73d288761a0ce 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::ConstVal; use mir::interpret::{GlobalId}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use syntax::symbol::Symbol; diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 8d10195941e0d..c33f028ae1e48 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, ConstVal}; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::project::Normalized; use ty::{self, Ty, TyCtxt}; diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index e3fbadc271206..3c798648e19af 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::ConstVal; use ty::subst::Substs; use ty::{self, Ty, TypeFlags, TypeFoldable}; diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 307e1b238386c..713aca38df9ec 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::ConstVal; use hir::def_id::DefId; use ty::{self, Binder, Ty, TyCtxt, TypeFlags}; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e89a022f81870..4a9de92681a66 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/mod.rs b/src/librustc/ty/query/mod.rs index 178ee7cf8e9ac..1095b943836ec 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -26,7 +26,7 @@ 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}; @@ -230,7 +230,7 @@ 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( diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 7603ed7102327..407d4c51847b9 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::ConstVal; use ty::subst::{Kind, UnpackedKind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index f00ec8be195ea..254f5b5eb7bb5 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -13,7 +13,7 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. -use middle::const_val::{ConstVal, ConstEvalErr}; +use mir::interpret::{ConstVal, ConstEvalErr}; use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 412dc7dc7e715..e6c2cadc9bb4f 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::ConstVal; use middle::region; use polonius_engine::Atom; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index ebe88d60ed12f..21cd9affce0a2 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::ConstVal; use ty::{self, Ty}; use rustc_data_structures::small_vec::SmallVec; use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter; diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 62fed1ecb668a..d5e5ea527f255 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::ConstVal; use infer::InferCtxt; use ty::subst::Substs; use traits; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 4fe9c34c140cb..78bf89cb0d41a 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::ConstVal; use middle::region::{self, BlockRemainder}; use ty::subst::{self, Subst}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 322924535d1f7..3f0d68f869a6a 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -1381,7 +1381,7 @@ 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; + use rustc::mir::interpret::ConstVal; info!("loading wasm section {:?}", id); diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index fc219df9b04b2..3adef1c415ada 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::{self, ValueRef}; -use rustc::middle::const_val::{ConstVal, ConstEvalErr}; +use rustc::mir::interpret::{ConstVal, ConstEvalErr}; use rustc_mir::interpret::{read_target_uint, const_val_field}; use rustc::hir::def_id::DefId; use rustc::mir; diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 0381a5e298706..21b67b2c3888f 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -9,7 +9,7 @@ // 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; diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 41024e6020273..c04a011cb02f4 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -12,7 +12,7 @@ use self::Constructor::*; use self::Usefulness::*; use self::WitnessPreference::*; -use rustc::middle::const_val::ConstVal; +use rustc::mir::interpret::ConstVal; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 24301e970f506..9975687f907db 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 9b92a8b5e7861..e66539b3e5f72 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -18,7 +18,7 @@ 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::interpret::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}; diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 52edd22f02765..57a703c783f79 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -1,5 +1,5 @@ use rustc::hir; -use rustc::middle::const_val::{ConstEvalErr}; +use rustc::mir::interpret::{ConstEvalErr}; use rustc::mir; use rustc::ty::{self, TyCtxt, Ty, Instance}; use rustc::ty::layout::{self, LayoutOf, Primitive}; @@ -427,7 +427,7 @@ pub fn const_val_field<'a, 'tcx>( field: mir::Field, value: ConstValue<'tcx>, ty: Ty<'tcx>, -) -> ::rustc::middle::const_val::EvalResult<'tcx> { +) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { trace!("const_val_field: {:?}, {:?}, {:?}, {:?}", instance, field, value, ty); let mut ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); let result = (|| { @@ -527,7 +527,7 @@ pub fn const_value_to_allocation_provider<'a, 'tcx>( 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(); diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ccdabe86d2252..b3ec2459b05ef 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -3,14 +3,14 @@ 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::interpret::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::{ diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3810aedb90c6a..1d4df97ce76ca 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -7,7 +7,7 @@ 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::mir::interpret::ConstVal; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 2d364f24b6b94..59af0478073a5 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -193,7 +193,7 @@ 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::ConstVal; use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::Substs; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2233c5c798026..38b9ae3c3cec3 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}; +use rustc::mir::interpret::{ConstVal, ConstEvalErr}; use rustc::ty::{TyCtxt, self, Instance}; use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult}; use interpret::EvalContext; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 6448ba17e3464..c897e9dc1f6bc 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::ConstVal; use rustc::traits::{self, TraitEngine}; use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::cast::CastTy; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3cc0745b195e6..3cd434e08fa35 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::ConstVal; use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime as rl; use rustc::ty::fold::TypeFolder; From 221a499bf111c02f0d2cffa3ffa520d842d1877d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 25 Jun 2018 18:48:11 +0200 Subject: [PATCH 09/16] Fixup --- src/librustc/mir/interpret/error.rs | 6 ++++++ src/librustc/mir/interpret/value.rs | 8 -------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index ab3fb0d2180ab..dca1c12b51df1 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -24,6 +24,12 @@ use syntax::ast; pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc>>; +#[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, diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index b17b774101769..9e3d4e60603ec 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -5,18 +5,10 @@ use ty; use super::{EvalResult, Pointer, PointerArithmetic, Allocation}; -#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)] -pub enum ConstVal<'tcx> { - Value(ConstValue<'tcx>), -} - /// 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)] 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 - 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 From 4bb9648b27e2c9f9efdb9e29a0d90b229aaff562 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 25 Jun 2018 20:53:02 +0200 Subject: [PATCH 10/16] Merge `ConstVal` and `ConstValue` --- src/librustc/dep_graph/dep_node.rs | 6 +- src/librustc/ich/impls_ty.rs | 21 +------ src/librustc/mir/interpret/error.rs | 10 ---- src/librustc/mir/interpret/mod.rs | 2 +- src/librustc/mir/interpret/value.rs | 12 +++- src/librustc/mir/mod.rs | 16 ++---- src/librustc/traits/project.rs | 4 +- src/librustc/traits/query/normalize.rs | 2 +- src/librustc/ty/flags.rs | 11 ++-- src/librustc/ty/fold.rs | 4 +- src/librustc/ty/query/config.rs | 6 +- src/librustc/ty/query/keys.rs | 2 +- src/librustc/ty/query/mod.rs | 8 +-- src/librustc/ty/relate.rs | 4 +- src/librustc/ty/structural_impls.rs | 18 +++--- src/librustc/ty/sty.rs | 46 ++++------------ src/librustc/ty/walk.rs | 9 +-- src/librustc/ty/wf.rs | 23 ++++---- src/librustc/util/ppaux.rs | 10 ++-- src/librustc_codegen_llvm/base.rs | 9 +-- src/librustc_codegen_llvm/mir/constant.rs | 30 +++++----- src/librustc_codegen_llvm/mir/operand.rs | 12 ++-- src/librustc_mir/hair/pattern/_match.rs | 22 +++----- src/librustc_mir/hair/pattern/mod.rs | 55 +++++++------------ src/librustc_mir/interpret/const_eval.rs | 33 ++++++----- src/librustc_mir/interpret/eval_context.rs | 45 ++++----------- src/librustc_mir/interpret/memory.rs | 7 +-- src/librustc_mir/monomorphize/collector.rs | 15 +++-- src/librustc_mir/transform/const_prop.rs | 49 ++--------------- src/librustc_mir/transform/qualify_consts.rs | 4 +- src/librustdoc/clean/mod.rs | 8 +-- src/test/compile-fail/const-err-multi.rs | 9 ++- src/test/compile-fail/const-err.rs | 1 - .../ui/const-len-underflow-separate-spans.rs | 5 +- .../const-len-underflow-separate-spans.stderr | 21 +++++-- 35 files changed, 201 insertions(+), 338 deletions(-) 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 d3280a9130ea9..4eb677732c2a2 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -370,11 +370,11 @@ impl<'a, 'gcx> HashStable> for ty::FieldDef { } impl<'a, 'gcx> HashStable> -for ::mir::interpret::ConstVal<'gcx> { +for ::mir::interpret::ConstValue<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use mir::interpret::ConstVal::*; + use mir::interpret::ConstValue::*; mem::discriminant(self).hash_stable(hcx, hasher); @@ -383,23 +383,6 @@ for ::mir::interpret::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); } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index dca1c12b51df1..3291d6bf1521f 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -11,12 +11,8 @@ use super::{ use backtrace::Backtrace; - -use hir::def_id::DefId; use ty; -use ty::subst::Substs; use ty::query::TyCtxtAt; -use mir::interpret::ConstValue; use errors::DiagnosticBuilder; use syntax_pos::Span; @@ -24,12 +20,6 @@ use syntax::ast; pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc>>; -#[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, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index bd8970f5ea69c..018c2446054be 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -9,7 +9,7 @@ mod error; mod value; pub use self::error::{ - EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstVal, ConstEvalErr, struct_error, + EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error, FrameInfo, ConstEvalResult, }; 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 31d5ef2e16036..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 mir::interpret::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/project.rs b/src/librustc/traits/project.rs index 73d288761a0ce..c49bcbf8f0316 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 mir::interpret::ConstVal; +use mir::interpret::ConstValue; use mir::interpret::{GlobalId}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use syntax::symbol::Symbol; @@ -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 c33f028ae1e48..bc2f1b7f6c7c8 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -194,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/ty/flags.rs b/src/librustc/ty/flags.rs index 3c798648e19af..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 mir::interpret::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 713aca38df9ec..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 mir::interpret::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/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 1095b943836ec..77644cdf02b11 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -29,7 +29,7 @@ use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; 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}; @@ -234,7 +234,7 @@ define_queries! { <'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 407d4c51847b9..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 mir::interpret::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 254f5b5eb7bb5..a648dc6e7e788 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -13,7 +13,7 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. -use mir::interpret::{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; @@ -1127,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 e6c2cadc9bb4f..b9446621eae6c 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -12,7 +12,7 @@ use hir::def_id::DefId; -use mir::interpret::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 21cd9affce0a2..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 mir::interpret::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 d5e5ea527f255..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 mir::interpret::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 78bf89cb0d41a..343f729804631 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 mir::interpret::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 3f0d68f869a6a..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::mir::interpret::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 3adef1c415ada..bbe0e34b48f26 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::{self, ValueRef}; -use rustc::mir::interpret::{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; @@ -129,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, Lrc>> { + ) -> 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(); @@ -150,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, Lrc>> { + ) -> Result<&'tcx ty::Const<'tcx>, Lrc>> { match constant.literal { mir::Literal::Promoted { index } => { let param_env = ty::ParamEnv::reveal_all(); @@ -174,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 @@ -183,10 +182,10 @@ 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), }; @@ -198,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); @@ -215,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 21b67b2c3888f..3d3a4400bd810 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -96,16 +96,16 @@ impl<'a, 'tcx> OperandRef<'tcx> { } pub fn from_const(bx: &Builder<'a, 'tcx>, - val: ConstValue<'tcx>, - ty: ty::Ty<'tcx>) + val: &'tcx ty::Const<'tcx>) -> Result, Lrc>> { - let layout = bx.cx.layout_of(ty); + 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, @@ -409,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 c04a011cb02f4..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::mir::interpret::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/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index e66539b3e5f72..6e736e9284ee3 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::mir::interpret::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 57a703c783f79..35422b11bd733 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -425,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>, + value: &'tcx ty::Const<'tcx>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { - trace!("const_val_field: {:?}, {:?}, {:?}, {:?}", instance, field, value, ty); + 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), @@ -478,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; @@ -514,14 +513,14 @@ 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>( diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b3ec2459b05ef..6dc65a2404d11 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -3,7 +3,6 @@ use std::fmt::Write; use rustc::hir::def_id::DefId; use rustc::hir::def::Def; use rustc::hir::map::definitions::DefPathData; -use rustc::mir::interpret::ConstVal; use rustc::mir; use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout}; use rustc::ty::subst::{Subst, Substs}; @@ -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()); @@ -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 1d4df97ce76ca..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::mir::interpret::ConstVal; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value, @@ -290,11 +289,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { assert!(self.tcx.is_static(def_id).is_some()); 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/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 59af0478073a5..744c65a05a716 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::mir::interpret::ConstVal; use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::Substs; @@ -1239,7 +1238,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, @@ -1270,16 +1269,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 38b9ae3c3cec3..649309c4eb4ff 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::mir::interpret::{ConstVal, ConstEvalErr}; +use rustc::mir::interpret::ConstEvalErr; use rustc::ty::{TyCtxt, self, Instance}; use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult}; use interpret::EvalContext; @@ -160,54 +160,17 @@ 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 } => { + let v = self.use_ecx(source_info, |this| { + this.ecx.const_to_value(value.val) + })?; + Some((v, value.ty, c.span)) }, // 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 c897e9dc1f6bc..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::mir::interpret::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/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3cd434e08fa35..4d7fc7fb1c487 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::mir::interpret::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-multi.rs b/src/test/compile-fail/const-err-multi.rs index 4a5e78b381ed0..9405b4134bcaa 100644 --- a/src/test/compile-fail/const-err-multi.rs +++ b/src/test/compile-fail/const-err-multi.rs @@ -11,19 +11,24 @@ #![deny(const_err)] pub const A: i8 = -std::i8::MIN; -//~^ ERROR E0080 -//~| ERROR attempt to negate with overflow +//~^ ERROR attempt to negate with overflow //~| ERROR this expression will panic at runtime //~| ERROR this constant cannot be used pub const B: i8 = A; //~^ ERROR const_err //~| ERROR const_err +//~| ERROR const_err +//~| ERROR const_err pub const C: u8 = A as u8; //~^ ERROR const_err //~| ERROR const_err +//~| ERROR const_err +//~| ERROR const_err pub const D: i8 = 50 - A; //~^ ERROR const_err //~| ERROR const_err +//~| ERROR const_err +//~| ERROR const_err fn main() { let _ = (A, B, C, D); diff --git a/src/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs index f77603b3ebafc..f6a64bcba21c3 100644 --- a/src/test/compile-fail/const-err.rs +++ b/src/test/compile-fail/const-err.rs @@ -23,7 +23,6 @@ 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() { diff --git a/src/test/ui/const-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs index 20b8865767459..3d299988a960c 100644 --- a/src/test/ui/const-len-underflow-separate-spans.rs +++ b/src/test/ui/const-len-underflow-separate-spans.rs @@ -15,11 +15,12 @@ const ONE: usize = 1; const TWO: usize = 2; const LEN: usize = ONE - TWO; -//~^ ERROR E0080 -//~| ERROR attempt to subtract with overflow +//~^ ERROR attempt to subtract with overflow fn main() { let a: [i8; LEN] = unimplemented!(); //~^ ERROR E0080 //~| ERROR E0080 +//~| ERROR const_err +//~| ERROR const_err } diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr index 630828ef8f517..cc851624e0e68 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -6,14 +6,23 @@ LL | const LEN: usize = ONE - TWO; | = note: #[deny(const_err)] on by default -error[E0080]: constant evaluation error - --> $DIR/const-len-underflow-separate-spans.rs:17:20 +error: referenced constant + --> $DIR/const-len-underflow-separate-spans.rs:21:17 | LL | const LEN: usize = ONE - TWO; - | ^^^^^^^^^ attempt to subtract with overflow + | --------- attempt to subtract with overflow +... +LL | let a: [i8; LEN] = unimplemented!(); + | ^^^ + +error: this expression will panic at runtime + --> $DIR/const-len-underflow-separate-spans.rs:21:17 + | +LL | let a: [i8; LEN] = unimplemented!(); + | ^^^ referenced constant has errors error[E0080]: referenced constant - --> $DIR/const-len-underflow-separate-spans.rs:22:12 + --> $DIR/const-len-underflow-separate-spans.rs:21:12 | LL | const LEN: usize = ONE - TWO; | --------- attempt to subtract with overflow @@ -22,13 +31,13 @@ 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:21:12 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^^^---^ | | | referenced constant has errors -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0080`. From 4eea1a4e5e28a9a84579ee6a52f115375adefde6 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 27 Jun 2018 13:36:30 +0200 Subject: [PATCH 11/16] Don't const propagate the body of constants --- src/librustc_mir/transform/const_prop.rs | 5 +- src/test/compile-fail/const-err-early.rs | 6 --- src/test/compile-fail/const-err-multi.rs | 10 +--- src/test/compile-fail/const-eval-overflow2.rs | 8 ---- .../compile-fail/const-eval-overflow2b.rs | 8 ---- .../compile-fail/const-eval-overflow2c.rs | 8 ---- .../conditional_array_execution.nll.stderr | 28 +++++------ .../const-eval/conditional_array_execution.rs | 3 +- .../conditional_array_execution.stderr | 24 ++++------ src/test/ui/const-eval/issue-43197.nll.stderr | 48 +++++++------------ src/test/ui/const-eval/issue-43197.rs | 6 +-- src/test/ui/const-eval/issue-43197.stderr | 44 +++++++---------- src/test/ui/const-eval/pub_const_err.rs | 3 +- src/test/ui/const-eval/pub_const_err.stderr | 20 +++----- src/test/ui/const-eval/pub_const_err_bin.rs | 3 +- .../ui/const-eval/pub_const_err_bin.stderr | 20 +++----- .../ui/const-len-underflow-separate-spans.rs | 2 +- .../const-len-underflow-separate-spans.stderr | 27 ++++++----- 18 files changed, 94 insertions(+), 179 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 649309c4eb4ff..95bac24a77bd5 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -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); 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 9405b4134bcaa..f2ee8a7078c7c 100644 --- a/src/test/compile-fail/const-err-multi.rs +++ b/src/test/compile-fail/const-err-multi.rs @@ -11,24 +11,16 @@ #![deny(const_err)] pub const A: i8 = -std::i8::MIN; -//~^ 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 -//~| ERROR const_err -//~| ERROR const_err pub const C: u8 = A as u8; //~^ ERROR const_err //~| ERROR const_err -//~| ERROR const_err -//~| ERROR const_err pub const D: i8 = 50 - A; //~^ ERROR const_err //~| ERROR const_err -//~| ERROR const_err -//~| ERROR const_err fn main() { let _ = (A, B, C, D); 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..7be9202a2f565 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 + --> $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 + --> $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); | ^^^^^^^^^^^^^^^---^^ @@ -55,7 +49,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]: referenced constant - --> $DIR/conditional_array_execution.rs:20:20 + --> $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..8a1b75721798f 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 + --> $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 + --> $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..6437369214b3f 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,15 +5,15 @@ 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); | ^^^^^^^^^^^^^^^^^^^---^^ @@ -33,7 +21,7 @@ LL | const Y: u32 = foo(0-1); | attempt to subtract with overflow warning: referenced constant - --> $DIR/issue-43197.rs:26:23 + --> $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 + --> $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 + --> $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); | ^^^^^^^^^^^^^^^^^^-^^^^^ @@ -84,22 +72,22 @@ 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 + --> $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 + --> $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..3cb8b345c673c 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,15 +5,15 @@ 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); | ^^^^^^^^^^^^^^^^^^^---^^ @@ -33,7 +21,7 @@ LL | const Y: u32 = foo(0-1); | attempt to subtract with overflow warning: referenced constant - --> $DIR/issue-43197.rs:26:23 + --> $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 + --> $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 + --> $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 + --> $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/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-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs index 3d299988a960c..242561da9d54c 100644 --- a/src/test/ui/const-len-underflow-separate-spans.rs +++ b/src/test/ui/const-len-underflow-separate-spans.rs @@ -15,7 +15,6 @@ const ONE: usize = 1; const TWO: usize = 2; const LEN: usize = ONE - TWO; -//~^ ERROR attempt to subtract with overflow fn main() { let a: [i8; LEN] = unimplemented!(); @@ -23,4 +22,5 @@ fn main() { //~| ERROR E0080 //~| ERROR const_err //~| ERROR const_err +//~| ERROR const_err } diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr index cc851624e0e68..a941b0c703fe8 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -1,28 +1,31 @@ -error: attempt to subtract with overflow - --> $DIR/const-len-underflow-separate-spans.rs:17:20 - | -LL | const LEN: usize = ONE - TWO; - | ^^^^^^^^^ - | - = note: #[deny(const_err)] on by default - error: referenced constant - --> $DIR/const-len-underflow-separate-spans.rs:21:17 + --> $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!(); | ^^^ + | + = note: #[deny(const_err)] on by default error: this expression will panic at runtime - --> $DIR/const-len-underflow-separate-spans.rs:21:17 + --> $DIR/const-len-underflow-separate-spans.rs:20:17 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^ referenced constant has errors +error: referenced 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!(); + | ^^^ + error[E0080]: referenced constant - --> $DIR/const-len-underflow-separate-spans.rs:21:12 + --> $DIR/const-len-underflow-separate-spans.rs:20:12 | LL | const LEN: usize = ONE - TWO; | --------- attempt to subtract with overflow @@ -31,7 +34,7 @@ LL | let a: [i8; LEN] = unimplemented!(); | ^^^^^^^^^ error[E0080]: could not evaluate constant expression - --> $DIR/const-len-underflow-separate-spans.rs:21:12 + --> $DIR/const-len-underflow-separate-spans.rs:20:12 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^^^---^ From 4d473300a200b26b04335dcd32200878ce8e6e04 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 27 Jun 2018 14:55:06 +0200 Subject: [PATCH 12/16] Turn the use of erroneous constants into errors again --- src/librustc/mir/interpret/error.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 21 +++++++++++++++---- src/test/compile-fail/const-err.rs | 2 ++ .../conditional_array_execution.nll.stderr | 6 +++--- .../conditional_array_execution.stderr | 4 ++-- src/test/ui/const-eval/issue-43197.nll.stderr | 10 ++++----- src/test/ui/const-eval/issue-43197.stderr | 8 +++---- src/test/ui/const-eval/issue-44578.nll.stderr | 4 ++-- src/test/ui/const-eval/issue-44578.stderr | 2 +- src/test/ui/const-eval/issue-50814-2.stderr | 2 +- src/test/ui/const-eval/issue-50814.stderr | 2 +- .../ui/const-len-underflow-separate-spans.rs | 5 ++--- .../const-len-underflow-separate-spans.stderr | 19 ++++------------- 13 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 3291d6bf1521f..86427bb2382cb 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -80,7 +80,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { ::mir::interpret::EvalErrorKind::CheckMatchError | ::mir::interpret::EvalErrorKind::Layout(_) => return None, ::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => { - inner.struct_generic(tcx, "referenced constant", lint_root)?.emit(); + inner.struct_generic(tcx, "referenced constant has errors", lint_root)?.emit(); }, _ => {}, } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 95bac24a77bd5..3b3c28f6ae265 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -170,10 +170,23 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { ) -> Option> { match c.literal { Literal::Value { value } => { - let v = self.use_ecx(source_info, |this| { - this.ecx.const_to_value(value.val) - })?; - Some((v, value.ty, c.span)) + 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/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs index f6a64bcba21c3..8683f6a023192 100644 --- a/src/test/compile-fail/const-err.rs +++ b/src/test/compile-fail/const-err.rs @@ -27,4 +27,6 @@ const FOO: u8 = [5u8][1]; fn main() { black_box((FOO, FOO)); + //~^ ERROR referenced constant has errors + //~| ERROR could not evaluate constant } 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 7be9202a2f565..8bc302a2befa4 100644 --- a/src/test/ui/const-eval/conditional_array_execution.nll.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.nll.stderr @@ -12,7 +12,7 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: referenced constant +warning: referenced constant has errors --> $DIR/conditional_array_execution.rs:19:20 | LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; @@ -27,7 +27,7 @@ warning: this expression will panic at runtime LL | println!("{}", FOO); | ^^^ referenced constant has errors -error[E0080]: referenced constant +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]; @@ -48,7 +48,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]: referenced constant +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]; diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr index 8a1b75721798f..649da03a5e7fa 100644 --- a/src/test/ui/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.stderr @@ -12,7 +12,7 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: referenced constant +warning: referenced constant has errors --> $DIR/conditional_array_execution.rs:19:20 | LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; @@ -27,7 +27,7 @@ warning: this expression will panic at runtime LL | println!("{}", FOO); | ^^^ referenced constant has errors -error[E0080]: referenced constant +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]; diff --git a/src/test/ui/const-eval/issue-43197.nll.stderr b/src/test/ui/const-eval/issue-43197.nll.stderr index 6437369214b3f..5819e6a9254a7 100644 --- a/src/test/ui/const-eval/issue-43197.nll.stderr +++ b/src/test/ui/const-eval/issue-43197.nll.stderr @@ -20,7 +20,7 @@ LL | const Y: u32 = foo(0-1); | | | attempt to subtract with overflow -warning: referenced constant +warning: referenced constant has errors --> $DIR/issue-43197.rs:24:23 | LL | const X: u32 = 0-1; @@ -35,7 +35,7 @@ warning: this expression will panic at runtime LL | println!("{} {}", X, Y); | ^ referenced constant has errors -warning: referenced constant +warning: referenced constant has errors --> $DIR/issue-43197.rs:24:26 | LL | const Y: u32 = foo(0-1); @@ -50,7 +50,7 @@ warning: this expression will panic at runtime LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: referenced constant +error[E0080]: referenced constant has errors --> $DIR/issue-43197.rs:24:5 | LL | const X: u32 = 0-1; @@ -71,7 +71,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]: referenced constant +error[E0080]: referenced constant has errors --> $DIR/issue-43197.rs:24:26 | LL | const Y: u32 = foo(0-1); @@ -86,7 +86,7 @@ error[E0080]: erroneous constant used LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: referenced constant +error[E0080]: referenced constant has errors --> $DIR/issue-43197.rs:24:23 | LL | const X: u32 = 0-1; diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr index 3cb8b345c673c..bf864d81ea3ca 100644 --- a/src/test/ui/const-eval/issue-43197.stderr +++ b/src/test/ui/const-eval/issue-43197.stderr @@ -20,7 +20,7 @@ LL | const Y: u32 = foo(0-1); | | | attempt to subtract with overflow -warning: referenced constant +warning: referenced constant has errors --> $DIR/issue-43197.rs:24:23 | LL | const X: u32 = 0-1; @@ -35,7 +35,7 @@ warning: this expression will panic at runtime LL | println!("{} {}", X, Y); | ^ referenced constant has errors -warning: referenced constant +warning: referenced constant has errors --> $DIR/issue-43197.rs:24:26 | LL | const Y: u32 = foo(0-1); @@ -50,7 +50,7 @@ warning: this expression will panic at runtime LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: referenced constant +error[E0080]: referenced constant has errors --> $DIR/issue-43197.rs:24:26 | LL | const Y: u32 = foo(0-1); @@ -65,7 +65,7 @@ error[E0080]: erroneous constant used LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: referenced constant +error[E0080]: referenced constant has errors --> $DIR/issue-43197.rs:24:23 | LL | const X: u32 = 0-1; 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-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs index 242561da9d54c..8db1411005e57 100644 --- a/src/test/ui/const-len-underflow-separate-spans.rs +++ b/src/test/ui/const-len-underflow-separate-spans.rs @@ -20,7 +20,6 @@ fn main() { let a: [i8; LEN] = unimplemented!(); //~^ ERROR E0080 //~| ERROR E0080 -//~| ERROR const_err -//~| ERROR const_err -//~| ERROR const_err +//~| 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 a941b0c703fe8..cf97a0dc55578 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -1,4 +1,4 @@ -error: referenced constant +error[E0080]: referenced constant has errors --> $DIR/const-len-underflow-separate-spans.rs:20:17 | LL | const LEN: usize = ONE - TWO; @@ -6,25 +6,14 @@ LL | const LEN: usize = ONE - TWO; ... LL | let a: [i8; LEN] = unimplemented!(); | ^^^ - | - = note: #[deny(const_err)] on by default -error: this expression will panic at runtime +error[E0080]: could not evaluate constant --> $DIR/const-len-underflow-separate-spans.rs:20:17 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^ referenced constant has errors -error: referenced 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!(); - | ^^^ - -error[E0080]: referenced constant +error[E0080]: referenced constant has errors --> $DIR/const-len-underflow-separate-spans.rs:20:12 | LL | const LEN: usize = ONE - TWO; @@ -41,6 +30,6 @@ LL | let a: [i8; LEN] = unimplemented!(); | | | referenced constant has errors -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. From 2a55d2fc4550753bebc65defd5d9c735268e7321 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 28 Jun 2018 11:19:45 +0200 Subject: [PATCH 13/16] Rebase fallout --- src/librustc/traits/query/normalize.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index bc2f1b7f6c7c8..a67383fb79aa0 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -14,7 +14,7 @@ use infer::{InferCtxt, InferOk}; use infer::at::At; -use mir::interpret::{GlobalId, ConstVal}; +use mir::interpret::{GlobalId, ConstValue}; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::project::Normalized; use ty::{self, Ty, TyCtxt}; From fc8f852ebeb5263273734200d0dd7596d0023c86 Mon Sep 17 00:00:00 2001 From: Lireer Date: Thu, 28 Jun 2018 11:30:53 +0200 Subject: [PATCH 14/16] Remove process::id from 'Stabilized APIs' in 1.27 --- RELEASES.md | 1 - 1 file changed, 1 deletion(-) 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`] From 8983ff522691249f1c38e36cb56c6b9a9e5348b1 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 28 Jun 2018 12:24:14 +0200 Subject: [PATCH 15/16] Explicitely disable WASM code generation for Emscripten Emscripten changed the default behavior recently: https://github.com/kripken/emscripten/blob/bd050e64bb0d9952df1344b8ea9356252328ad83/ChangeLog.markdown#v1381-05172018 It now defaults to WebAssembly and requires an explicit flag to generate asm.js. WASM=0 is also valid for older emcc and thus doesn't break it. Closes #51856 --- src/librustc_target/spec/asmjs_unknown_emscripten.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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, From 54a04b3b036e318dd08d4947e33669c79152ace4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 26 Jun 2018 11:39:37 -0700 Subject: [PATCH 16/16] Provide existing ref suggestions for more E0308 errors --- src/librustc_typeck/check/coercion.rs | 11 +++- src/librustc_typeck/check/demand.rs | 56 ++++++++----------- src/librustc_typeck/check/mod.rs | 25 ++++++++- .../suggestions/str-array-assignment.stderr | 5 +- 4 files changed, 59 insertions(+), 38 deletions(-) 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/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`