Skip to content

Commit

Permalink
Rollup merge of rust-lang#56723 - oli-obk:lazy_const, r=nikomatsakis
Browse files Browse the repository at this point in the history
Don't emit `Unevaluated` from `const_eval`

cc @eddyb @RalfJung
  • Loading branch information
Mark-Simulacrum authored Jan 3, 2019
2 parents be8a496 + 03b8928 commit fee93ea
Show file tree
Hide file tree
Showing 56 changed files with 486 additions and 584 deletions.
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

0 comments on commit fee93ea

Please sign in to comment.