}
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> {
),
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()
ty,
user_ty: None,
literal: tcx.intern_lazy_const(
- ty::LazyConst::Evaluated(ty::Const::zero_sized(tcx, ty)),
+ ty::LazyConst::Evaluated(ty::Const::zero_sized(ty)),
),
})
}
/// 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 {
+ 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;
.intern_canonical_var_infos(interned?.as_slice()))
}
-#[inline]
-pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
- -> Result<&'tcx ty::Const<'tcx>, D::Error>
- where D: TyDecoder<'a, 'tcx>,
- 'tcx: 'a,
-{
- Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
-}
-
#[inline]
pub fn decode_lazy_const<'a, 'tcx, D>(decoder: &mut D)
-> Result<&'tcx ty::LazyConst<'tcx>, D::Error>
}
}
- impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>>
- for $DecoderName<$($typaram),*> {
- fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
- decode_const(self)
- }
- }
-
impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::LazyConst<'tcx>>
for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::LazyConst<'tcx>, Self::Error> {
region: InternedSet<'tcx, RegionKind>,
existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
- const_: InternedSet<'tcx, Const<'tcx>>,
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
goal: InternedSet<'tcx, GoalKind<'tcx>>,
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
existential_predicates: Default::default(),
canonical_var_infos: Default::default(),
predicates: Default::default(),
- const_: Default::default(),
clauses: Default::default(),
goal: Default::default(),
goal_list: Default::default(),
}
}
- pub fn alloc_const_slice(self, values: &[&'tcx ty::Const<'tcx>])
- -> &'tcx [&'tcx ty::Const<'tcx>] {
- if values.is_empty() {
- &[]
- } else {
- self.interners.arena.alloc_slice(values)
- }
- }
-
- pub fn alloc_name_const_slice(self, values: &[(ast::Name, &'tcx ty::Const<'tcx>)])
- -> &'tcx [(ast::Name, &'tcx ty::Const<'tcx>)] {
- if values.is_empty() {
- &[]
- } else {
- self.interners.arena.alloc_slice(values)
- }
- }
-
pub fn intern_const_alloc(
self,
alloc: Allocation,
}
}
-impl<'a, 'tcx> Lift<'tcx> for &'a Const<'a> {
- type Lifted = &'tcx Const<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Const<'tcx>> {
+impl<'a, 'tcx> Lift<'tcx> for &'a mir::interpret::Allocation {
+ type Lifted = &'tcx mir::interpret::Allocation;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
if tcx.interners.arena.in_arena(*self as *const _) {
return Some(unsafe { mem::transmute(*self) });
}
direct_interners!('tcx,
region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
- const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>,
goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>
);
}
}
-impl<'tcx> Key for &'tcx ty::Const<'tcx> {
+impl<'tcx> Key for ty::Const<'tcx> {
fn query_crate(&self) -> CrateNum {
LOCAL_CRATE
}
::ty::UniverseIndex,
::ty::Variance,
::syntax_pos::Span,
- ConstValue<'tcx>,
}
///////////////////////////////////////////////////////////////////////////
}
}
+BraceStructLiftImpl! {
+ impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
+ type Lifted = ty::Const<'tcx>;
+ val, ty
+ }
+}
+
+impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
+ type Lifted = ConstValue<'tcx>;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+ match *self {
+ ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
+ ConstValue::ScalarPair(x, y) => Some(ConstValue::ScalarPair(x, y)),
+ ConstValue::ByRef(x, alloc, z) => Some(ConstValue::ByRef(
+ x, alloc.lift_to_tcx(tcx)?, z,
+ )),
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////
// TypeFoldable implementations.
//
}
}
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let ty = self.ty.fold_with(folder);
let val = self.val.fold_with(folder);
- folder.tcx().mk_const(ty::Const {
+ ty::Const {
ty,
val
- })
+ }
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.ty.visit_with(visitor) || self.val.visit_with(visitor)
}
}
+
+impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+ *self
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
+ false
+ }
+}
/// code is monomorphic enough for that.
pub enum LazyConst<'tcx> {
Unevaluated(DefId, &'tcx Substs<'tcx>),
- Evaluated(&'tcx Const<'tcx>),
+ Evaluated(Const<'tcx>),
}
-static_assert!(MEM_SIZE_OF_LAZY_CONST: ::std::mem::size_of::<LazyConst<'_>>() <= 24);
-
impl<'tcx> LazyConst<'tcx> {
- pub fn map_evaluated<R>(self, f: impl FnOnce(&'tcx Const<'tcx>) -> Option<R>) -> Option<R> {
+ pub fn map_evaluated<R>(self, f: impl FnOnce(Const<'tcx>) -> Option<R>) -> Option<R> {
match self {
LazyConst::Evaluated(c) => f(c),
LazyConst::Unevaluated(..) => None,
}
impl<'tcx> Const<'tcx> {
- #[inline]
- pub fn from_const_value(
- tcx: TyCtxt<'_, '_, 'tcx>,
- val: ConstValue<'tcx>,
- ty: Ty<'tcx>,
- ) -> &'tcx Self {
- tcx.mk_const(Const {
- val,
- ty,
- })
- }
-
#[inline]
pub fn from_scalar(
- tcx: TyCtxt<'_, '_, 'tcx>,
val: Scalar,
ty: Ty<'tcx>,
- ) -> &'tcx Self {
- Self::from_const_value(tcx, ConstValue::Scalar(val), ty)
+ ) -> Self {
+ Self {
+ val: ConstValue::Scalar(val),
+ ty,
+ }
}
#[inline]
tcx: TyCtxt<'_, '_, 'tcx>,
bits: u128,
ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
- ) -> &'tcx Self {
+ ) -> Self {
let ty = tcx.lift_to_global(&ty).unwrap();
let size = tcx.layout_of(ty).unwrap_or_else(|e| {
panic!("could not compute layout for {:?}: {:?}", ty, e)
let shift = 128 - size.bits();
let truncated = (bits << shift) >> shift;
assert_eq!(truncated, bits, "from_bits called with untruncated value");
- Self::from_scalar(tcx, Scalar::Bits { bits, size: size.bytes() as u8 }, ty.value)
+ Self::from_scalar(Scalar::Bits { bits, size: size.bytes() as u8 }, ty.value)
}
#[inline]
- pub fn zero_sized(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
- Self::from_scalar(tcx, Scalar::Bits { bits: 0, size: 0 }, ty)
+ pub fn zero_sized(ty: Ty<'tcx>) -> Self {
+ Self::from_scalar(Scalar::Bits { bits: 0, size: 0 }, ty)
}
#[inline]
- pub fn from_bool(tcx: TyCtxt<'_, '_, 'tcx>, v: bool) -> &'tcx Self {
+ pub fn from_bool(tcx: TyCtxt<'_, '_, 'tcx>, v: bool) -> Self {
Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
}
#[inline]
- pub fn from_usize(tcx: TyCtxt<'_, '_, 'tcx>, n: u64) -> &'tcx Self {
+ pub fn from_usize(tcx: TyCtxt<'_, '_, 'tcx>, n: u64) -> Self {
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
}
}
}
-impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx LazyConst<'tcx> {}
&mut self,
bx: &Bx,
constant: &'tcx ty::LazyConst<'tcx>,
- ) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
+ ) -> Result<ty::Const<'tcx>, ErrorHandled> {
match *constant {
ty::LazyConst::Unevaluated(def_id, ref substs) => {
let tcx = bx.tcx();
&mut self,
bx: &Bx,
constant: &mir::Constant<'tcx>,
- ) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
+ ) -> Result<ty::Const<'tcx>, ErrorHandled> {
let c = self.monomorphize(&constant.literal);
self.fully_evaluate(bx, c)
}
bx: &Bx,
span: Span,
ty: Ty<'tcx>,
- constant: Result<&'tcx ty::Const<'tcx>, ErrorHandled>,
+ constant: Result<ty::Const<'tcx>, ErrorHandled>,
) -> (Bx::Value, Ty<'tcx>) {
constant
.and_then(|c| {
pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
- val: &'tcx ty::Const<'tcx>
+ val: ty::Const<'tcx>
) -> Result<Self, ErrorHandled> {
let layout = bx.cx().layout_of(val.ty);
SwitchInt {
switch_ty: Ty<'tcx>,
options: Vec<u128>,
- indices: FxHashMap<&'tcx ty::Const<'tcx>, usize>,
+ indices: FxHashMap<ty::Const<'tcx>, usize>,
},
// test for equality
Eq {
- value: &'tcx ty::Const<'tcx>,
+ value: ty::Const<'tcx>,
ty: Ty<'tcx>,
},
candidate: &Candidate<'pat, 'tcx>,
switch_ty: Ty<'tcx>,
options: &mut Vec<u128>,
- indices: &mut FxHashMap<&'tcx ty::Const<'tcx>, usize>)
+ indices: &mut FxHashMap<ty::Const<'tcx>, usize>)
-> bool
{
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
pub fn literal_operand(&mut self,
span: Span,
ty: Ty<'tcx>,
- literal: &'tcx ty::Const<'tcx>)
+ literal: ty::Const<'tcx>)
-> Operand<'tcx> {
let constant = box Constant {
span,
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
op: OpTy<'tcx>,
may_normalize: bool,
-) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
+) -> EvalResult<'tcx, ty::Const<'tcx>> {
// We do not normalize just any data. Only scalar layout and fat pointers.
let normalize = may_normalize
&& match op.layout.abi {
Ok(Immediate::ScalarPair(a, b)) =>
ConstValue::ScalarPair(a.not_undef()?, b.not_undef()?),
};
- Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty))
+ Ok(ty::Const { val, ty: op.layout.ty })
}
pub fn lazy_const_to_op<'tcx>(
instance: ty::Instance<'tcx>,
variant: Option<VariantIdx>,
field: mir::Field,
- value: &'tcx ty::Const<'tcx>,
+ value: ty::Const<'tcx>,
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
trace!("const_field: {:?}, {:?}, {:?}", instance, field, value);
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
instance: ty::Instance<'tcx>,
- val: &'tcx ty::Const<'tcx>,
+ val: ty::Const<'tcx>,
) -> EvalResult<'tcx, VariantIdx> {
trace!("const_variant_index: {:?}, {:?}", instance, val);
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty: Ty<'tcx>,
neg: bool,
-) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
+) -> Result<ty::Const<'tcx>, LitToConstError> {
use syntax::ast::*;
let trunc = |n| {
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
};
- Ok(ty::Const::from_const_value(tcx, lit, ty))
+ Ok(ty::Const { val: lit, ty })
}
fn parse_float<'tcx>(
span,
kind: ExprKind::Literal {
literal: cx.tcx().intern_lazy_const(ty::LazyConst::Evaluated(
- ty::Const::zero_sized(cx.tcx(), ty)
+ ty::Const::zero_sized(ty)
)),
user_ty,
},
debug!("convert_path_expr: user_ty={:?}", user_ty);
ExprKind::Literal {
literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized(
- cx.tcx,
cx.tables().node_id_to_type(expr.hir_id),
))),
user_ty,
ty: Ty<'tcx>,
sp: Span,
neg: bool,
- ) -> &'tcx ty::Const<'tcx> {
+ ) -> ty::Const<'tcx> {
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
match lit_to_const(lit, self.tcx, ty, neg) {
method_name: &str,
self_ty: Ty<'tcx>,
params: &[Kind<'tcx>])
- -> (Ty<'tcx>, &'tcx ty::Const<'tcx>) {
+ -> (Ty<'tcx>, ty::Const<'tcx>) {
let method_name = Symbol::intern(method_name);
let substs = self.tcx.mk_substs_trait(self_ty, params);
for item in self.tcx.associated_items(trait_def_id) {
if item.kind == ty::AssociatedKind::Method && item.ident.name == method_name {
let method_ty = self.tcx.type_of(item.def_id);
let method_ty = method_ty.subst(self.tcx, substs);
- return (method_ty, ty::Const::zero_sized(self.tcx, method_ty));
+ return (method_ty, ty::Const::zero_sized(method_ty));
}
}
/// Enum variants.
Variant(DefId),
/// Literal values.
- ConstantValue(&'tcx ty::Const<'tcx>),
+ ConstantValue(ty::Const<'tcx>),
/// Ranges of literal values (`2...5` and `2..5`).
ConstantRange(u128, u128, Ty<'tcx>, RangeEnd),
/// Array patterns of length n.
&cx.tcx, ptr, layout.size,
).ok()?;
let scalar = scalar.not_undef().ok()?;
- let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
+ let value = ty::Const::from_scalar(scalar, ty);
let pattern = Pattern {
ty,
span: pat.span,
},
Constant {
- value: &'tcx ty::Const<'tcx>,
+ value: ty::Const<'tcx>,
},
Range(PatternRange<'tcx>),
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PatternRange<'tcx> {
- pub lo: &'tcx ty::Const<'tcx>,
- pub hi: &'tcx ty::Const<'tcx>,
+ pub lo: ty::Const<'tcx>,
+ pub hi: ty::Const<'tcx>,
pub ty: Ty<'tcx>,
pub end: RangeEnd,
}
fn const_to_pat(
&self,
instance: ty::Instance<'tcx>,
- cv: &'tcx ty::Const<'tcx>,
+ cv: ty::Const<'tcx>,
id: hir::HirId,
span: Span,
) -> Pattern<'tcx> {
}
CloneImpls!{ <'tcx>
- Span, Field, Mutability, ast::Name, ast::NodeId, usize, &'tcx ty::Const<'tcx>,
+ Span, Field, Mutability, ast::Name, ast::NodeId, usize, ty::Const<'tcx>,
Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>,
UserTypeProjection<'tcx>, PatternTypeProjection<'tcx>
pub fn compare_const_vals<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
- a: &'tcx ty::Const<'tcx>,
- b: &'tcx ty::Const<'tcx>,
+ a: ty::Const<'tcx>,
+ b: ty::Const<'tcx>,
ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> Option<Ordering> {
trace!("compare_const_vals: {:?}, {:?}", a, b);
fn collect_const<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- constant: &ty::Const<'tcx>,
+ constant: ty::Const<'tcx>,
output: &mut Vec<MonoItem<'tcx>>,
) {
- debug!("visiting const {:?}", *constant);
+ debug!("visiting const {:?}", constant);
match constant.val {
ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => {
ty: func_ty,
user_ty: None,
literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated(
- ty::Const::zero_sized(self.tcx, func_ty),
+ ty::Const::zero_sized(func_ty),
)),
});
ty,
user_ty: None,
literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated(
- ty::Const::zero_sized(tcx, ty)
+ ty::Const::zero_sized(ty)
)),
}),
vec![rcvr])