Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't emit Unevaluated from const_eval #56723

Merged
merged 16 commits into from
Jan 4, 2019
Merged
5 changes: 5 additions & 0 deletions src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ impl<T> Default for TypedArena<T> {
}

impl<T> TypedArena<T> {
pub fn in_arena(&self, ptr: *const T) -> bool {
let ptr = ptr as *const T as *mut T;

self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
}
/// Allocates an object in the `TypedArena`, returning a reference to it.
#[inline]
pub fn alloc(&self, object: T) -> &mut T {
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ impl_stable_hash_for!(struct ty::FieldDef {

impl_stable_hash_for!(
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
Unevaluated(def_id, substs),
Scalar(val),
ScalarPair(a, b),
ByRef(id, alloc, offset),
Expand Down Expand Up @@ -378,6 +377,11 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
val
});

impl_stable_hash_for!(impl<'tcx> for enum ty::LazyConst<'tcx> [ty::LazyConst] {
Unevaluated(did, substs),
Evaluated(c)
});

impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
Reported,
TooGeneric
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl ErrorHandled {
}

pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
pub type ConstEvalResult<'tcx> = Result<ty::Const<'tcx>, ErrorHandled>;

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ConstEvalErr<'tcx> {
Expand Down
10 changes: 1 addition & 9 deletions src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::fmt;

use crate::ty::{Ty, subst::Substs, layout::{HasDataLayout, Size}};
use crate::hir::def_id::DefId;
use crate::ty::{Ty, layout::{HasDataLayout, Size}};

use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate};

Expand All @@ -18,12 +17,6 @@ pub struct RawConst<'tcx> {
/// matches the LocalValue optimizations for easy conversions between Value and ConstValue.
#[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
/// FIXME: The query should then return a type that does not even have this variant.
Unevaluated(DefId, &'tcx Substs<'tcx>),

/// Used only for types with layout::abi::Scalar ABI and ZSTs
///
/// Not using the enum `Value` to encode that this must not be `Undef`
Expand All @@ -43,7 +36,6 @@ impl<'tcx> ConstValue<'tcx> {
#[inline]
pub fn try_to_scalar(&self) -> Option<Scalar> {
match *self {
ConstValue::Unevaluated(..) |
ConstValue::ByRef(..) |
ConstValue::ScalarPair(..) => None,
ConstValue::Scalar(val) => Some(val),
Expand Down
20 changes: 15 additions & 5 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ impl<'tcx> TerminatorKind<'tcx> {
),
ty: switch_ty,
};
fmt_const_val(&mut s, &c).unwrap();
fmt_const_val(&mut s, c).unwrap();
s.into()
}).chain(iter::once("otherwise".into()))
.collect()
Expand Down Expand Up @@ -2154,7 +2154,9 @@ impl<'tcx> Operand<'tcx> {
span,
ty,
user_ty: None,
literal: ty::Const::zero_sized(tcx, ty),
literal: tcx.intern_lazy_const(
ty::LazyConst::Evaluated(ty::Const::zero_sized(ty)),
),
})
}

Expand Down Expand Up @@ -2457,7 +2459,7 @@ pub struct Constant<'tcx> {
/// Needed for NLL to impose user-given type constraints.
pub user_ty: Option<UserTypeAnnotationIndex>,

pub literal: &'tcx ty::Const<'tcx>,
pub literal: &'tcx ty::LazyConst<'tcx>,
}

/// A collection of projections into user types.
Expand Down Expand Up @@ -2655,12 +2657,20 @@ newtype_index! {
impl<'tcx> Debug for Constant<'tcx> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
write!(fmt, "const ")?;
fmt_const_val(fmt, self.literal)
fmt_lazy_const_val(fmt, self.literal)
}
}

/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
pub fn fmt_lazy_const_val(f: &mut impl Write, const_val: &ty::LazyConst<'_>) -> fmt::Result {
match *const_val {
ty::LazyConst::Unevaluated(..) => write!(f, "{:?}", const_val),
ty::LazyConst::Evaluated(c) => fmt_const_val(f, c),
}
}

/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const<'_>) -> fmt::Result {
pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Result {
use ty::TyKind::*;
let value = const_val.val;
let ty = const_val.ty;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ macro_rules! make_mir_visitor {
}

fn visit_const(&mut self,
constant: & $($mutability)* &'tcx ty::Const<'tcx>,
constant: & $($mutability)* &'tcx ty::LazyConst<'tcx>,
_: Location) {
self.super_const(constant);
}
Expand Down Expand Up @@ -892,7 +892,7 @@ macro_rules! make_mir_visitor {
fn super_region(&mut self, _region: & $($mutability)* ty::Region<'tcx>) {
}

fn super_const(&mut self, _const: & $($mutability)* &'tcx ty::Const<'tcx>) {
fn super_const(&mut self, _const: & $($mutability)* &'tcx ty::LazyConst<'tcx>) {
}

fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) {
Expand Down
4 changes: 1 addition & 3 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
Some(format!("[{}]", self.tcx.type_of(def.did).to_string())),
));
let tcx = self.tcx;
if let Some(len) = len.val.try_to_scalar().and_then(|scalar| {
scalar.to_usize(&tcx).ok()
}) {
if let Some(len) = len.assert_usize(tcx) {
flags.push((
"_Self".to_owned(),
Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use super::util;
use hir::def_id::DefId;
use infer::{InferCtxt, InferOk};
use infer::type_variable::TypeVariableOrigin;
use mir::interpret::ConstValue;
use mir::interpret::{GlobalId};
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use syntax::ast::Ident;
Expand Down Expand Up @@ -410,8 +409,8 @@ 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 ConstValue::Unevaluated(def_id, substs) = constant.val {
fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
if let ty::LazyConst::Unevaluated(def_id, substs) = *constant {
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_placeholders() {
Expand All @@ -423,8 +422,9 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
promoted: None
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let evaluated = evaluated.subst(self.tcx(), substs);
return self.fold_const(evaluated);
let substs = tcx.lift_to_global(&substs).unwrap();
let evaluated = evaluated.subst(tcx, substs);
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
} else {
Expand All @@ -436,7 +436,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
promoted: None
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
return self.fold_const(evaluated)
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/librustc/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use infer::at::At;
use infer::canonical::OriginalQueryValues;
use infer::{InferCtxt, InferOk};
use mir::interpret::{ConstValue, GlobalId};
use mir::interpret::GlobalId;
use traits::project::Normalized;
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use ty::fold::{TypeFoldable, TypeFolder};
Expand Down Expand Up @@ -188,8 +188,8 @@ 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 ConstValue::Unevaluated(def_id, substs) = constant.val {
fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
if let ty::LazyConst::Unevaluated(def_id, substs) = *constant {
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_placeholders() {
Expand All @@ -201,8 +201,9 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
promoted: None,
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let evaluated = evaluated.subst(self.tcx(), substs);
return self.fold_const(evaluated);
let substs = tcx.lift_to_global(&substs).unwrap();
let evaluated = evaluated.subst(tcx, substs);
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
} else {
Expand All @@ -214,7 +215,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
promoted: None,
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
return self.fold_const(evaluated)
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@ pub fn decode_canonical_var_infos<'a, 'tcx, D>(decoder: &mut D)
}

#[inline]
pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
-> Result<&'tcx ty::Const<'tcx>, D::Error>
pub fn decode_lazy_const<'a, 'tcx, D>(decoder: &mut D)
-> Result<&'tcx ty::LazyConst<'tcx>, D::Error>
where D: TyDecoder<'a, 'tcx>,
'tcx: 'a,
{
Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
Ok(decoder.tcx().intern_lazy_const(Decodable::decode(decoder)?))
}

#[inline]
Expand Down Expand Up @@ -389,10 +389,10 @@ macro_rules! implement_ty_decoder {
}
}

impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>>
impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::LazyConst<'tcx>>
for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
decode_const(self)
fn specialized_decode(&mut self) -> Result<&'tcx ty::LazyConst<'tcx>, Self::Error> {
decode_lazy_const(self)
}
}

Expand Down
Loading