Skip to content

Commit b903cb9

Browse files
committed
Move the Unevaluated constant arm upwards in the type structure
1 parent cae1647 commit b903cb9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+405
-316
lines changed

src/librustc/ich/impls_ty.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@ impl_stable_hash_for!(struct ty::FieldDef {
301301

302302
impl_stable_hash_for!(
303303
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
304-
Unevaluated(def_id, substs),
305304
Scalar(val),
306305
ScalarPair(a, b),
307306
ByRef(id, alloc, offset),
@@ -378,6 +377,11 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
378377
val
379378
});
380379

380+
impl_stable_hash_for!(impl<'tcx> for enum ty::LazyConst<'tcx> [ty::LazyConst] {
381+
Unevaluated(did, substs),
382+
Evaluated(c)
383+
});
384+
381385
impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
382386
Reported,
383387
TooGeneric

src/librustc/mir/interpret/value.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::fmt;
22

3-
use crate::ty::{Ty, subst::Substs, layout::{HasDataLayout, Size}};
4-
use crate::hir::def_id::DefId;
3+
use crate::ty::{Ty, layout::{HasDataLayout, Size}};
54

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

@@ -18,12 +17,6 @@ pub struct RawConst<'tcx> {
1817
/// matches the LocalValue optimizations for easy conversions between Value and ConstValue.
1918
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
2019
pub enum ConstValue<'tcx> {
21-
/// Never returned from the `const_eval` query, but the HIR contains these frequently in order
22-
/// to allow HIR creation to happen for everything before needing to be able to run constant
23-
/// evaluation
24-
/// FIXME: The query should then return a type that does not even have this variant.
25-
Unevaluated(DefId, &'tcx Substs<'tcx>),
26-
2720
/// Used only for types with layout::abi::Scalar ABI and ZSTs
2821
///
2922
/// Not using the enum `Value` to encode that this must not be `Undef`
@@ -43,7 +36,6 @@ impl<'tcx> ConstValue<'tcx> {
4336
#[inline]
4437
pub fn try_to_scalar(&self) -> Option<Scalar> {
4538
match *self {
46-
ConstValue::Unevaluated(..) |
4739
ConstValue::ByRef(..) |
4840
ConstValue::ScalarPair(..) => None,
4941
ConstValue::Scalar(val) => Some(val),

src/librustc/mir/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,7 +2154,9 @@ impl<'tcx> Operand<'tcx> {
21542154
span,
21552155
ty,
21562156
user_ty: None,
2157-
literal: ty::Const::zero_sized(tcx, ty),
2157+
literal: tcx.intern_lazy_const(
2158+
ty::LazyConst::Evaluated(ty::Const::zero_sized(tcx, ty)),
2159+
),
21582160
})
21592161
}
21602162

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

2460-
pub literal: &'tcx ty::Const<'tcx>,
2462+
pub literal: &'tcx ty::LazyConst<'tcx>,
24612463
}
24622464

24632465
/// A collection of projections into user types.
@@ -2655,7 +2657,15 @@ newtype_index! {
26552657
impl<'tcx> Debug for Constant<'tcx> {
26562658
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
26572659
write!(fmt, "const ")?;
2658-
fmt_const_val(fmt, self.literal)
2660+
fmt_lazy_const_val(fmt, self.literal)
2661+
}
2662+
}
2663+
2664+
/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
2665+
pub fn fmt_lazy_const_val(f: &mut impl Write, const_val: &ty::LazyConst<'_>) -> fmt::Result {
2666+
match const_val {
2667+
ty::LazyConst::Unevaluated(..) => write!(f, "{:?}", const_val),
2668+
ty::LazyConst::Evaluated(c) => fmt_const_val(f, c),
26592669
}
26602670
}
26612671

src/librustc/mir/tcx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
114114
PlaceTy::Ty {
115115
ty: match ty.sty {
116116
ty::Array(inner, size) => {
117-
let size = size.unwrap_usize(tcx);
117+
let size = size.unwrap_evaluated().unwrap_usize(tcx);
118118
let len = size - (from as u64) - (to as u64);
119119
tcx.mk_array(inner, len)
120120
}

src/librustc/mir/visit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ macro_rules! make_mir_visitor {
233233
}
234234

235235
fn visit_const(&mut self,
236-
constant: & $($mutability)* &'tcx ty::Const<'tcx>,
236+
constant: & $($mutability)* &'tcx ty::LazyConst<'tcx>,
237237
_: Location) {
238238
self.super_const(constant);
239239
}
@@ -892,7 +892,7 @@ macro_rules! make_mir_visitor {
892892
fn super_region(&mut self, _region: & $($mutability)* ty::Region<'tcx>) {
893893
}
894894

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

898898
fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) {

src/librustc/traits/error_reporting.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -418,18 +418,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
418418
Some(format!("[{}]", self.tcx.type_of(def.did).to_string())),
419419
));
420420
let tcx = self.tcx;
421-
if let Some(len) = len.val.try_to_scalar().and_then(|scalar| {
422-
scalar.to_usize(&tcx).ok()
423-
}) {
424-
flags.push((
425-
"_Self".to_owned(),
426-
Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),
427-
));
428-
} else {
429-
flags.push((
430-
"_Self".to_owned(),
431-
Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())),
432-
));
421+
if let ty::LazyConst::Evaluated(len) = len {
422+
if let Some(len) = len.val.try_to_scalar().and_then(|scalar| {
423+
scalar.to_usize(&tcx).ok()
424+
}) {
425+
flags.push((
426+
"_Self".to_owned(),
427+
Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),
428+
));
429+
} else {
430+
flags.push((
431+
"_Self".to_owned(),
432+
Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())),
433+
));
434+
}
433435
}
434436
}
435437
}

src/librustc/traits/project.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use super::util;
1515
use hir::def_id::DefId;
1616
use infer::{InferCtxt, InferOk};
1717
use infer::type_variable::TypeVariableOrigin;
18-
use mir::interpret::ConstValue;
1918
use mir::interpret::{GlobalId};
2019
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
2120
use syntax::ast::Ident;
@@ -410,8 +409,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
410409
}
411410
}
412411

413-
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
414-
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
412+
fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
413+
if let ty::LazyConst::Unevaluated(def_id, substs) = *constant {
415414
let tcx = self.selcx.tcx().global_tcx();
416415
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
417416
if substs.needs_infer() || substs.has_placeholders() {
@@ -423,8 +422,9 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
423422
promoted: None
424423
};
425424
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
426-
let evaluated = evaluated.subst(self.tcx(), substs);
427-
return self.fold_const(evaluated);
425+
let substs = tcx.lift_to_global(&substs).unwrap();
426+
let evaluated = evaluated.subst(tcx, substs);
427+
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
428428
}
429429
}
430430
} else {
@@ -436,7 +436,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
436436
promoted: None
437437
};
438438
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
439-
return self.fold_const(evaluated)
439+
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
440440
}
441441
}
442442
}

src/librustc/traits/query/normalize.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use infer::at::At;
66
use infer::canonical::OriginalQueryValues;
77
use infer::{InferCtxt, InferOk};
8-
use mir::interpret::{ConstValue, GlobalId};
8+
use mir::interpret::GlobalId;
99
use traits::project::Normalized;
1010
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
1111
use ty::fold::{TypeFoldable, TypeFolder};
@@ -188,8 +188,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
188188
}
189189
}
190190

191-
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
192-
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
191+
fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
192+
if let ty::LazyConst::Unevaluated(def_id, substs) = *constant {
193193
let tcx = self.infcx.tcx.global_tcx();
194194
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
195195
if substs.needs_infer() || substs.has_placeholders() {
@@ -201,8 +201,9 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
201201
promoted: None,
202202
};
203203
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
204-
let evaluated = evaluated.subst(self.tcx(), substs);
205-
return self.fold_const(evaluated);
204+
let substs = tcx.lift_to_global(&substs).unwrap();
205+
let evaluated = evaluated.subst(tcx, substs);
206+
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
206207
}
207208
}
208209
} else {
@@ -214,7 +215,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
214215
promoted: None,
215216
};
216217
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
217-
return self.fold_const(evaluated)
218+
return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
218219
}
219220
}
220221
}

src/librustc/ty/codec.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,15 @@ pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
255255
Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
256256
}
257257

258+
#[inline]
259+
pub fn decode_lazy_const<'a, 'tcx, D>(decoder: &mut D)
260+
-> Result<&'tcx ty::LazyConst<'tcx>, D::Error>
261+
where D: TyDecoder<'a, 'tcx>,
262+
'tcx: 'a,
263+
{
264+
Ok(decoder.tcx().intern_lazy_const(Decodable::decode(decoder)?))
265+
}
266+
258267
#[inline]
259268
pub fn decode_allocation<'a, 'tcx, D>(decoder: &mut D)
260269
-> Result<&'tcx Allocation, D::Error>
@@ -396,6 +405,13 @@ macro_rules! implement_ty_decoder {
396405
}
397406
}
398407

408+
impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::LazyConst<'tcx>>
409+
for $DecoderName<$($typaram),*> {
410+
fn specialized_decode(&mut self) -> Result<&'tcx ty::LazyConst<'tcx>, Self::Error> {
411+
decode_lazy_const(self)
412+
}
413+
}
414+
399415
impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::mir::interpret::Allocation>
400416
for $DecoderName<$($typaram),*> {
401417
fn specialized_decode(

src/librustc/ty/context.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use traits;
2929
use traits::{Clause, Clauses, GoalKind, Goal, Goals};
3030
use ty::{self, Ty, TypeAndMut};
3131
use ty::{TyS, TyKind, List};
32-
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
32+
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
3333
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
3434
use ty::RegionKind;
3535
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
@@ -1112,6 +1112,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11121112
})
11131113
}
11141114

1115+
pub fn intern_lazy_const(self, c: ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
1116+
self.global_interners.arena.alloc(c)
1117+
}
1118+
11151119
pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
11161120
self.layout_interner.borrow_mut().intern(layout, |layout| {
11171121
self.global_arenas.layout.alloc(layout)
@@ -1814,6 +1818,21 @@ impl<'a, 'tcx> Lift<'tcx> for &'a List<Clause<'a>> {
18141818
}
18151819
}
18161820

1821+
impl<'a, 'tcx> Lift<'tcx> for &'a LazyConst<'a> {
1822+
type Lifted = &'tcx LazyConst<'tcx>;
1823+
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx LazyConst<'tcx>> {
1824+
if tcx.interners.arena.in_arena(*self as *const _) {
1825+
return Some(unsafe { mem::transmute(*self) });
1826+
}
1827+
// Also try in the global tcx if we're not that.
1828+
if !tcx.is_global() {
1829+
self.lift_to_tcx(tcx.global_tcx())
1830+
} else {
1831+
None
1832+
}
1833+
}
1834+
}
1835+
18171836
impl<'a, 'tcx> Lift<'tcx> for &'a Const<'a> {
18181837
type Lifted = &'tcx Const<'tcx>;
18191838
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Const<'tcx>> {
@@ -2683,7 +2702,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26832702

26842703
#[inline]
26852704
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
2686-
self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
2705+
self.mk_ty(Array(ty, self.intern_lazy_const(
2706+
ty::LazyConst::Evaluated(ty::Const::from_usize(self.global_tcx(), n))
2707+
)))
26872708
}
26882709

26892710
#[inline]

0 commit comments

Comments
 (0)