1
Fork 0

Overhaul Const.

Specifically, rename the `Const` struct as `ConstS` and re-introduce `Const` as
this:
```
pub struct Const<'tcx>(&'tcx Interned<ConstS>);
```
This now matches `Ty` and `Predicate` more closely, including using
pointer-based `eq` and `hash`.

Notable changes:
- `mk_const` now takes a `ConstS`.
- `Const` was copy, despite being 48 bytes. Now `ConstS` is not, so need a
  we need separate arena for it, because we can't use the `Dropless` one any
  more.
- Many `&'tcx Const<'tcx>`/`&Const<'tcx>` to `Const<'tcx>` changes
- Many `ct.ty` to `ct.ty()` and `ct.val` to `ct.val()` changes.
- Lots of tedious sigil fiddling.
This commit is contained in:
Nicholas Nethercote 2022-02-02 14:24:45 +11:00
parent 7eb15509ce
commit a95fb8b150
116 changed files with 654 additions and 619 deletions

View file

@ -89,6 +89,7 @@ macro_rules! arena_types {
// Interned types
[] tys: rustc_middle::ty::TyS<'tcx>,
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
[] consts: rustc_middle::ty::ConstS<'tcx>,
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both the `rustc_hir` arena

View file

@ -328,8 +328,8 @@ impl<'tcx> CanonicalVarValues<'tcx> {
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
}
GenericArgKind::Const(ct) => tcx
.mk_const(ty::Const {
ty: ct.ty,
.mk_const(ty::ConstS {
ty: ct.ty(),
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
})
.into(),

View file

@ -95,14 +95,14 @@ pub enum ConstVariableOriginKind {
#[derive(Copy, Clone, Debug)]
pub enum ConstVariableValue<'tcx> {
Known { value: &'tcx ty::Const<'tcx> },
Known { value: ty::Const<'tcx> },
Unknown { universe: ty::UniverseIndex },
}
impl<'tcx> ConstVariableValue<'tcx> {
/// If this value is known, returns the const it is known to be.
/// Otherwise, `None`.
pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
pub fn known(&self) -> Option<ty::Const<'tcx>> {
match *self {
ConstVariableValue::Unknown { .. } => None,
ConstVariableValue::Known { value } => Some(value),
@ -130,7 +130,7 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
}
impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
type Error = (ty::Const<'tcx>, ty::Const<'tcx>);
fn unify_values(&value1: &Self, &value2: &Self) -> Result<Self, Self::Error> {
Ok(match (value1.val, value2.val) {
@ -162,18 +162,18 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
}
}
impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {}
impl<'tcx> EqUnifyValue for ty::Const<'tcx> {}
pub fn replace_if_possible<'tcx, V, L>(
table: &mut UnificationTable<InPlace<ty::ConstVid<'tcx>, V, L>>,
c: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx>
c: ty::Const<'tcx>,
) -> ty::Const<'tcx>
where
V: snapshot_vec::VecLike<unify::Delegate<ty::ConstVid<'tcx>>>,
L: UndoLogs<snapshot_vec::UndoLog<unify::Delegate<ty::ConstVid<'tcx>>>>,
{
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = c {
match table.probe_value(*vid).val.known() {
if let ty::ConstKind::Infer(InferConst::Var(vid)) = c.val() {
match table.probe_value(vid).val.known() {
Some(c) => c,
None => c,
}

View file

@ -2185,7 +2185,7 @@ pub enum Rvalue<'tcx> {
Use(Operand<'tcx>),
/// [x; 32]
Repeat(Operand<'tcx>, &'tcx ty::Const<'tcx>),
Repeat(Operand<'tcx>, ty::Const<'tcx>),
/// &x or &mut x
Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
@ -2335,7 +2335,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
match *self {
Use(ref place) => write!(fmt, "{:?}", place),
Repeat(ref a, ref b) => {
Repeat(ref a, b) => {
write!(fmt, "[{:?}; ", a)?;
pretty_print_const(b, fmt, false)?;
write!(fmt, "]")
@ -2514,7 +2514,7 @@ pub struct Constant<'tcx> {
#[derive(Lift)]
pub enum ConstantKind<'tcx> {
/// This constant came from the type system
Ty(&'tcx ty::Const<'tcx>),
Ty(ty::Const<'tcx>),
/// This constant cannot go back into the type system, as it represents
/// something the type system cannot handle (e.g. pointers).
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
@ -2522,7 +2522,7 @@ pub enum ConstantKind<'tcx> {
impl<'tcx> Constant<'tcx> {
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
match self.literal.const_for_ty()?.val.try_to_scalar() {
match self.literal.const_for_ty()?.val().try_to_scalar() {
Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
@ -2539,25 +2539,25 @@ impl<'tcx> Constant<'tcx> {
}
}
impl<'tcx> From<&'tcx ty::Const<'tcx>> for ConstantKind<'tcx> {
impl<'tcx> From<ty::Const<'tcx>> for ConstantKind<'tcx> {
#[inline]
fn from(ct: &'tcx ty::Const<'tcx>) -> Self {
fn from(ct: ty::Const<'tcx>) -> Self {
Self::Ty(ct)
}
}
impl<'tcx> ConstantKind<'tcx> {
/// Returns `None` if the constant is not trivially safe for use in the type system.
pub fn const_for_ty(&self) -> Option<&'tcx ty::Const<'tcx>> {
pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> {
match self {
ConstantKind::Ty(c) => Some(c),
ConstantKind::Ty(c) => Some(*c),
ConstantKind::Val(..) => None,
}
}
pub fn ty(&self) -> Ty<'tcx> {
match self {
ConstantKind::Ty(c) => c.ty,
ConstantKind::Ty(c) => c.ty(),
ConstantKind::Val(_, ty) => *ty,
}
}
@ -2565,7 +2565,7 @@ impl<'tcx> ConstantKind<'tcx> {
#[inline]
pub fn try_to_value(self) -> Option<interpret::ConstValue<'tcx>> {
match self {
ConstantKind::Ty(c) => c.val.try_to_value(),
ConstantKind::Ty(c) => c.val().try_to_value(),
ConstantKind::Val(val, _) => Some(val),
}
}
@ -2829,7 +2829,7 @@ impl<'tcx> Display for ConstantKind<'tcx> {
}
fn pretty_print_const<'tcx>(
c: &ty::Const<'tcx>,
c: ty::Const<'tcx>,
fmt: &mut Formatter<'_>,
print_types: bool,
) -> fmt::Result {

View file

@ -462,10 +462,11 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
}
}
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
fn visit_const(&mut self, constant: ty::Const<'tcx>, _: Location) {
self.super_const(constant);
let ty::Const { ty, val, .. } = constant;
if use_verbose(*ty, false) {
let ty = constant.ty();
let val = constant.val();
if use_verbose(ty, false) {
self.push("ty::Const");
self.push(&format!("+ ty: {:?}", ty));
let val = match val {
@ -683,8 +684,8 @@ pub fn write_allocations<'tcx>(
}
struct CollectAllocIds(BTreeSet<AllocId>);
impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds {
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val() {
self.0.extend(alloc_ids_from_const(val));
}
c.super_visit_with(self)

View file

@ -387,7 +387,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
#[derive(Copy, Clone, Debug, HashStable)]
pub struct DestructuredConst<'tcx> {
pub variant: Option<VariantIdx>,
pub fields: &'tcx [&'tcx ty::Const<'tcx>],
pub fields: &'tcx [ty::Const<'tcx>],
}
/// Coverage information summarized from a MIR if instrumented for source code coverage (see

View file

@ -200,7 +200,7 @@ macro_rules! make_mir_visitor {
}
fn visit_const(&mut self,
constant: & $($mutability)? &'tcx ty::Const<'tcx>,
constant: $(& $mutability)? ty::Const<'tcx>,
_: Location) {
self.super_const(constant);
}
@ -864,7 +864,7 @@ macro_rules! make_mir_visitor {
self.visit_span(span);
drop(user_ty); // no visit method for this
match literal {
ConstantKind::Ty(ct) => self.visit_const(ct, location),
ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location),
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
}
}
@ -903,7 +903,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)? ty::Const<'tcx>) {
}
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {

View file

@ -113,7 +113,7 @@ rustc_queries! {
/// Given the def_id of a const-generic parameter, computes the associated default const
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
query const_param_default(param: DefId) -> ty::Const<'tcx> {
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
separate_provide_extern
}
@ -926,7 +926,7 @@ rustc_queries! {
/// Destructure a constant ADT or array into its variant index and its
/// field values.
query destructure_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> mir::DestructuredConst<'tcx> {
desc { "destructure constant" }
remap_env_constness
@ -935,8 +935,8 @@ rustc_queries! {
/// Dereference a constant reference or raw pointer and turn the result into a constant
/// again.
query deref_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
) -> &'tcx ty::Const<'tcx> {
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> ty::Const<'tcx> {
desc { "deref constant" }
remap_env_constness
}
@ -947,7 +947,7 @@ rustc_queries! {
query lit_to_const(
key: LitToConstInput<'tcx>
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
) -> Result<ty::Const<'tcx>, LitToConstError> {
desc { "converting literal to const" }
}

View file

@ -368,12 +368,12 @@ pub enum ExprKind<'tcx> {
},
/// An inline `const` block, e.g. `const {}`.
ConstBlock {
value: &'tcx Const<'tcx>,
value: Const<'tcx>,
},
/// An array literal constructed from one repeated element, e.g. `[1; 5]`.
Repeat {
value: ExprId,
count: &'tcx Const<'tcx>,
count: Const<'tcx>,
},
/// An array, e.g. `[a, b, c, d]`.
Array {
@ -407,7 +407,7 @@ pub enum ExprKind<'tcx> {
},
/// A literal.
Literal {
literal: &'tcx Const<'tcx>,
literal: Const<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
/// The `DefId` of the `const` item this literal
/// was produced from, if this is not a user-written
@ -419,7 +419,7 @@ pub enum ExprKind<'tcx> {
/// This is only distinguished from `Literal` so that we can register some
/// info for diagnostics.
StaticRef {
literal: &'tcx Const<'tcx>,
literal: Const<'tcx>,
def_id: DefId,
},
/// Inline assembly, i.e. `asm!()`.
@ -501,7 +501,7 @@ pub enum InlineAsmOperand<'tcx> {
out_expr: Option<ExprId>,
},
Const {
value: &'tcx Const<'tcx>,
value: Const<'tcx>,
span: Span,
},
SymFn {
@ -640,7 +640,7 @@ pub enum PatKind<'tcx> {
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
/// `PartialEq` and `Eq`.
Constant {
value: &'tcx ty::Const<'tcx>,
value: ty::Const<'tcx>,
},
Range(PatRange<'tcx>),
@ -670,8 +670,8 @@ pub enum PatKind<'tcx> {
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
pub struct PatRange<'tcx> {
pub lo: &'tcx ty::Const<'tcx>,
pub hi: &'tcx ty::Const<'tcx>,
pub lo: ty::Const<'tcx>,
pub hi: ty::Const<'tcx>,
pub end: RangeEnd,
}

View file

@ -22,7 +22,7 @@ pub enum CastKind {
/// A node of an `AbstractConst`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
pub enum Node<'tcx> {
Leaf(&'tcx ty::Const<'tcx>),
Leaf(ty::Const<'tcx>),
Binop(mir::BinOp, NodeId, NodeId),
UnaryOp(mir::UnOp, NodeId),
FunctionCall(NodeId, &'tcx [NodeId]),

View file

@ -26,7 +26,7 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized {
walk_pat(self, pat);
}
fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
fn visit_const(&mut self, _cnst: Const<'tcx>) {}
}
pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
@ -209,7 +209,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
visitor.visit_pat(&subpattern.pattern);
}
}
Constant { value } => visitor.visit_const(value),
Constant { value } => visitor.visit_const(*value),
Range(range) => {
visitor.visit_const(range.lo);
visitor.visit_const(range.hi);

View file

@ -88,21 +88,21 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b {
return Ok(a);
}
match (a.val, b.val) {
match (a.val(), b.val()) {
(_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
return Ok(a);
}
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b)));
}
_ => {}

View file

@ -144,6 +144,12 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
self.0.0.encode(e)
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
e.encode_alloc_id(self)
@ -335,8 +341,8 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> &'tcx Self {
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> Self {
decoder.tcx().mk_const(Decodable::decode(decoder))
}
}

View file

@ -4,10 +4,12 @@ use crate::ty::{
self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty,
TyCtxt, TypeFoldable,
};
use rustc_data_structures::intern::Interned;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::HashStable;
use std::fmt;
mod int;
mod kind;
@ -17,22 +19,42 @@ pub use int::*;
pub use kind::*;
pub use valtree::*;
/// Typed constant value.
#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct Const<'tcx> {
pub ty: Ty<'tcx>,
/// Use this rather than `ConstS`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
pub struct Const<'tcx>(pub Interned<'tcx, ConstS<'tcx>>);
impl<'tcx> fmt::Debug for Const<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// This reflects what `Const` looked liked before `Interned` was
// introduced. We print it like this to avoid having to update expected
// output in a lot of tests.
write!(f, "Const {{ ty: {:?}, val: {:?} }}", self.ty(), self.val())
}
}
/// Typed constant value.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
pub struct ConstS<'tcx> {
pub ty: Ty<'tcx>,
pub val: ConstKind<'tcx>,
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Const<'_>, 48);
static_assert_size!(ConstS<'_>, 48);
impl<'tcx> Const<'tcx> {
pub fn ty(self) -> Ty<'tcx> {
self.0.ty
}
pub fn val(self) -> ConstKind<'tcx> {
self.0.val
}
/// Literals and const generic parameters are eagerly converted to a constant, everything else
/// becomes `Unevaluated`.
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
}
@ -40,7 +62,7 @@ impl<'tcx> Const<'tcx> {
pub fn from_opt_const_arg_anon_const(
tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
) -> &'tcx Self {
) -> Self {
debug!("Const::from_anon_const(def={:?})", def);
let body_id = match tcx.hir().get_by_def_id(def.did) {
@ -58,7 +80,7 @@ impl<'tcx> Const<'tcx> {
match Self::try_eval_lit_or_param(tcx, ty, expr) {
Some(v) => v,
None => tcx.mk_const(ty::Const {
None => tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
@ -74,7 +96,7 @@ impl<'tcx> Const<'tcx> {
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Option<&'tcx Self> {
) -> Option<Self> {
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = match &expr.kind {
@ -120,7 +142,7 @@ impl<'tcx> Const<'tcx> {
let generics = tcx.generics_of(item_def_id.to_def_id());
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.hir().name(hir_id);
Some(tcx.mk_const(ty::Const {
Some(tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
ty,
}))
@ -129,7 +151,7 @@ impl<'tcx> Const<'tcx> {
}
}
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
debug!("Const::from_inline_const(def_id={:?})", def_id);
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
@ -155,7 +177,7 @@ impl<'tcx> Const<'tcx> {
let substs =
InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
.substs;
tcx.mk_const(ty::Const {
tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id).to_global(),
substs,
@ -171,19 +193,19 @@ impl<'tcx> Const<'tcx> {
/// Interns the given value as a constant.
#[inline]
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
tcx.mk_const(Self { val: ConstKind::Value(val), ty })
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> Self {
tcx.mk_const(ConstS { val: ConstKind::Value(val), ty })
}
#[inline]
/// Interns the given scalar as a constant.
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> Self {
Self::from_value(tcx, ConstValue::Scalar(val), ty)
}
#[inline]
/// Creates a constant with the given integer value and interns it.
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx Self {
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self {
let size = tcx
.layout_of(ty)
.unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
@ -193,19 +215,19 @@ impl<'tcx> Const<'tcx> {
#[inline]
/// Creates an interned zst constant.
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
Self::from_scalar(tcx, Scalar::ZST, ty)
}
#[inline]
/// Creates an interned bool constant.
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]
/// Creates an interned usize constant.
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))
}
@ -214,35 +236,35 @@ impl<'tcx> Const<'tcx> {
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
/// contains const generic parameters or pointers).
pub fn try_eval_bits(
&self,
self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<u128> {
assert_eq!(self.ty, ty);
assert_eq!(self.ty(), ty);
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
// if `ty` does not depend on generic parameters, use an empty param_env
self.val.eval(tcx, param_env).try_to_bits(size)
self.val().eval(tcx, param_env).try_to_bits(size)
}
#[inline]
pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
self.val.eval(tcx, param_env).try_to_bool()
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
self.val().eval(tcx, param_env).try_to_bool()
}
#[inline]
pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
self.val.eval(tcx, param_env).try_to_machine_usize(tcx)
pub fn try_eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
self.val().eval(tcx, param_env).try_to_machine_usize(tcx)
}
#[inline]
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
/// unevaluated constant.
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
if let Some(val) = self.val.try_eval(tcx, param_env) {
pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Const<'tcx> {
if let Some(val) = self.val().try_eval(tcx, param_env) {
match val {
Ok(val) => Const::from_value(tcx, val, self.ty),
Err(ErrorReported) => tcx.const_error(self.ty),
Ok(val) => Const::from_value(tcx, val, self.ty()),
Err(ErrorReported) => tcx.const_error(self.ty()),
}
} else {
self
@ -251,20 +273,20 @@ impl<'tcx> Const<'tcx> {
#[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
self.try_eval_bits(tcx, param_env, ty)
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
}
#[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
pub fn eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
self.try_eval_usize(tcx, param_env)
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
}
}
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Const<'tcx> {
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Const<'tcx> {
let default_def_id = match tcx.hir().get_by_def_id(def_id.expect_local()) {
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },

View file

@ -18,10 +18,10 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs
use crate::ty::TyKind::*;
use crate::ty::{
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind,
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
};
use rustc_ast as ast;
use rustc_attr as attr;
@ -111,7 +111,7 @@ pub struct CtxtInterners<'tcx> {
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>,
const_: InternedSet<'tcx, ConstS<'tcx>>,
const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, Layout>,
@ -229,7 +229,7 @@ pub struct CommonLifetimes<'tcx> {
}
pub struct CommonConsts<'tcx> {
pub unit: &'tcx Const<'tcx>,
pub unit: Const<'tcx>,
}
pub struct LocalTableInContext<'a, V> {
@ -869,7 +869,7 @@ impl<'tcx> CanonicalUserType<'tcx> {
_ => false,
},
GenericArgKind::Const(ct) => match ct.val {
GenericArgKind::Const(ct) => match ct.val() {
ty::ConstKind::Bound(debruijn, b) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(debruijn, ty::INNERMOST);
@ -946,11 +946,14 @@ impl<'tcx> CommonLifetimes<'tcx> {
impl<'tcx> CommonConsts<'tcx> {
fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
let mk_const =
|c| interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0;
let mk_const = |c| {
Const(Interned::new_unchecked(
interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
))
};
CommonConsts {
unit: mk_const(ty::Const {
unit: mk_const(ty::ConstS {
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::ZST)),
ty: types.unit,
}),
@ -1222,7 +1225,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Like [TyCtxt::ty_error] but for constants.
#[track_caller]
pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
self.const_error_with_message(
ty,
DUMMY_SP,
@ -1237,9 +1240,9 @@ impl<'tcx> TyCtxt<'tcx> {
ty: Ty<'tcx>,
span: S,
msg: &str,
) -> &'tcx Const<'tcx> {
) -> Const<'tcx> {
self.sess.delay_span_bug(span, msg);
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
self.mk_const(ty::ConstS { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
}
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
@ -1685,7 +1688,7 @@ macro_rules! nop_list_lift {
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
nop_lift! {const_; Const<'a> => Const<'tcx>}
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
@ -2127,6 +2130,7 @@ macro_rules! direct_interners {
direct_interners! {
region: mk_region(RegionKind): Region -> Region<'tcx>,
const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
}
macro_rules! direct_interners_old {
@ -2167,7 +2171,6 @@ macro_rules! direct_interners_old {
// FIXME: eventually these should all be converted to `direct_interners`.
direct_interners_old! {
const_: mk_const(Const<'tcx>),
const_allocation: intern_const_alloc(Allocation),
layout: intern_layout(Layout),
adt_def: intern_adt_def(AdtDef),
@ -2491,8 +2494,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
}
#[inline]
@ -2511,8 +2514,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(ic), ty })
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(ic), ty })
}
#[inline]
@ -2521,8 +2524,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
}
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {

View file

@ -71,7 +71,7 @@ impl<'tcx> Ty<'tcx> {
fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
match arg.unpack() {
GenericArgKind::Type(ty) => ty.is_suggestable(),
GenericArgKind::Const(c) => const_is_suggestable(c.val),
GenericArgKind::Const(c) => const_is_suggestable(c.val()),
_ => true,
}
}
@ -110,7 +110,7 @@ impl<'tcx> Ty<'tcx> {
}) => {
let term_is_suggestable = match term {
Term::Ty(ty) => ty.is_suggestable(),
Term::Const(c) => const_is_suggestable(c.val),
Term::Const(c) => const_is_suggestable(c.val()),
};
term_is_suggestable && substs.iter().all(generic_arg_is_suggestible)
}
@ -120,7 +120,7 @@ impl<'tcx> Ty<'tcx> {
args.iter().all(generic_arg_is_suggestible)
}
Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(),
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val),
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val()),
_ => true,
}
}

View file

@ -60,13 +60,13 @@ pub enum TypeError<'tcx> {
/// created a cycle (because it appears somewhere within that
/// type).
CyclicTy(Ty<'tcx>),
CyclicConst(&'tcx ty::Const<'tcx>),
CyclicConst(ty::Const<'tcx>),
ProjectionMismatched(ExpectedFound<DefId>),
ExistentialMismatch(
ExpectedFound<&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>>,
),
ObjectUnsafeCoercion(DefId),
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
ConstMismatch(ExpectedFound<ty::Const<'tcx>>),
IntrinsicCast,
/// Safe `#[target_feature]` functions are not assignable to safe function pointers.
@ -255,7 +255,7 @@ impl<'tcx> Ty<'tcx> {
}
let n = tcx.lift(n).unwrap();
if let ty::ConstKind::Value(v) = n.val {
if let ty::ConstKind::Value(v) = n.val() {
if let Some(n) = v.try_to_machine_usize(tcx) {
return format!("array of {} element{}", n, pluralize!(n)).into();
}

View file

@ -28,7 +28,7 @@ impl FlagComputation {
result
}
pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
pub fn for_const(c: ty::Const<'_>) -> TypeFlags {
let mut result = FlagComputation::new();
result.add_const(c);
result.flags
@ -286,9 +286,9 @@ impl FlagComputation {
}
}
fn add_const(&mut self, c: &ty::Const<'_>) {
self.add_ty(c.ty);
match c.val {
fn add_const(&mut self, c: ty::Const<'_>) {
self.add_ty(c.ty());
match c.val() {
ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);

View file

@ -216,7 +216,7 @@ pub trait TypeFolder<'tcx>: Sized {
r.super_fold_with(self)
}
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx>
where
Self: TypeFolder<'tcx, Error = !>,
{
@ -263,10 +263,7 @@ pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> {
r.try_super_fold_with(self)
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
c.try_super_fold_with(self)
}
@ -306,10 +303,7 @@ where
Ok(self.fold_region(r))
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
Ok(self.fold_const(c))
}
@ -346,7 +340,7 @@ pub trait TypeVisitor<'tcx>: Sized {
r.super_visit_with(self)
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
c.super_visit_with(self)
}
@ -366,7 +360,7 @@ pub struct BottomUpFolder<'tcx, F, G, H>
where
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::Const<'tcx>) -> ty::Const<'tcx>,
{
pub tcx: TyCtxt<'tcx>,
pub ty_op: F,
@ -378,7 +372,7 @@ impl<'tcx, F, G, H> TypeFolder<'tcx> for BottomUpFolder<'tcx, F, G, H>
where
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::Const<'tcx>) -> ty::Const<'tcx>,
{
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx
@ -394,7 +388,7 @@ where
(self.lt_op)(r)
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
let ct = ct.super_fold_with(self);
(self.ct_op)(ct)
}
@ -593,7 +587,7 @@ struct BoundVarReplacer<'a, 'tcx> {
fld_r: Option<&'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a)>,
fld_t: Option<&'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a)>,
}
impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
@ -601,7 +595,7 @@ impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
fld_r: Option<&'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a)>,
fld_t: Option<&'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a)>,
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a)>,
) -> Self {
BoundVarReplacer { tcx, current_index: ty::INNERMOST, fld_r, fld_t, fld_c }
}
@ -660,14 +654,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
r
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match *ct {
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
if debruijn == self.current_index =>
{
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
if let Some(fld_c) = self.fld_c.as_mut() {
let ct = fld_c(bound_const, ty);
return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32());
let ct = fld_c(bound_const, ct.ty());
return ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32());
}
}
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
@ -726,7 +718,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx>,
T: TypeFoldable<'tcx>,
{
if !value.has_escaping_bound_vars() {
@ -751,7 +743,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
H: FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx>,
T: TypeFoldable<'tcx>,
{
let mut region_map = BTreeMap::new();
@ -804,7 +796,7 @@ impl<'tcx> TyCtxt<'tcx> {
))
},
|c, ty| {
self.mk_const(ty::Const {
self.mk_const(ty::ConstS {
val: ty::ConstKind::Bound(
ty::INNERMOST,
ty::BoundVar::from_usize(c.as_usize() + bound_vars),
@ -1057,13 +1049,16 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.val() {
if self.amount == 0 || debruijn < self.current_index {
ct
} else {
let debruijn = debruijn.shifted_in(self.amount);
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
self.tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Bound(debruijn, bound_ct),
ty: ct.ty(),
})
}
} else {
ct.super_fold_with(self)
@ -1165,13 +1160,13 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
}
}
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// we don't have a `visit_infer_const` callback, so we have to
// hook in here to catch this case (annoying...), but
// otherwise we do want to remember to visit the rest of the
// const, as it has types/regions embedded in a lot of other
// places.
match ct.val {
match ct.val() {
ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => {
ControlFlow::Break(FoundEscapingVars)
}
@ -1236,7 +1231,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
#[inline]
#[instrument(level = "trace")]
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = FlagComputation::for_const(c);
trace!(r.flags=?flags);
if flags.intersects(self.flags) {
@ -1325,12 +1320,12 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
t.super_visit_with(self)
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// if we are only looking for "constrained" region, we have to
// ignore the inputs of an unevaluated const, as they may not appear
// in the normalized form
if self.just_constrained {
if let ty::ConstKind::Unevaluated(..) = c.val {
if let ty::ConstKind::Unevaluated(..) = c.val() {
return ControlFlow::CONTINUE;
}
}

View file

@ -59,7 +59,9 @@ pub use self::closure::{
RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath,
CAPTURE_STRUCT_LOCAL,
};
pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Unevaluated, ValTree};
pub use self::consts::{
Const, ConstInt, ConstKind, ConstS, InferConst, ScalarInt, Unevaluated, ValTree,
};
pub use self::context::{
tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt,
@ -592,7 +594,7 @@ pub enum PredicateKind<'tcx> {
ConstEvaluatable(ty::Unevaluated<'tcx, ()>),
/// Constants must be equal. The first component is the const that is expected.
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
ConstEquate(Const<'tcx>, Const<'tcx>),
/// Represents a type found in the environment that we can use for implied bounds.
///
@ -818,7 +820,7 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
#[derive(HashStable, TypeFoldable)]
pub enum Term<'tcx> {
Ty(Ty<'tcx>),
Const(&'tcx Const<'tcx>),
Const(Const<'tcx>),
}
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
@ -827,8 +829,8 @@ impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
}
}
impl<'tcx> From<&'tcx Const<'tcx>> for Term<'tcx> {
fn from(c: &'tcx Const<'tcx>) -> Self {
impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
fn from(c: Const<'tcx>) -> Self {
Term::Const(c)
}
}
@ -837,8 +839,8 @@ impl<'tcx> Term<'tcx> {
pub fn ty(&self) -> Option<Ty<'tcx>> {
if let Term::Ty(ty) = self { Some(*ty) } else { None }
}
pub fn ct(&self) -> Option<&'tcx Const<'tcx>> {
if let Term::Const(c) = self { Some(c) } else { None }
pub fn ct(&self) -> Option<Const<'tcx>> {
if let Term::Const(c) = self { Some(*c) } else { None }
}
}

View file

@ -192,7 +192,7 @@ impl<'tcx> TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()
}
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()
}
@ -244,13 +244,10 @@ impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'t
}
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
match self.try_normalize_generic_arg_after_erasing_regions(c.into()) {
Ok(t) => Ok(t.expect_const()),
Err(_) => Err(NormalizationError::Const(*c)),
Err(_) => Err(NormalizationError::Const(c)),
}
}

View file

@ -66,7 +66,7 @@ pub trait Printer<'tcx>: Sized {
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
) -> Result<Self::DynExistential, Self::Error>;
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error>;
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error>;
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error>;
@ -352,10 +352,10 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P>
}
}
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::Const<'tcx> {
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
type Output = P::Const;
type Error = P::Error;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_const(self)
cx.print_const(*self)
}
}

View file

@ -754,14 +754,14 @@ pub trait PrettyPrinter<'tcx>:
p!("[", print(ty), "; ");
if self.tcx().sess.verbose() {
p!(write("{:?}", sz));
} else if let ty::ConstKind::Unevaluated(..) = sz.val {
} else if let ty::ConstKind::Unevaluated(..) = sz.val() {
// Do not try to evaluate unevaluated constants. If we are const evaluating an
// array length anon const, rustc will (with debug assertions) print the
// constant's path. Which will end up here again.
p!("_");
} else if let Some(n) = sz.val.try_to_bits(self.tcx().data_layout.pointer_size) {
} else if let Some(n) = sz.val().try_to_bits(self.tcx().data_layout.pointer_size) {
p!(write("{}", n));
} else if let ty::ConstKind::Param(param) = sz.val {
} else if let ty::ConstKind::Param(param) = sz.val() {
p!(write("{}", param));
} else {
p!("_");
@ -1148,13 +1148,13 @@ pub trait PrettyPrinter<'tcx>:
fn pretty_print_const(
mut self,
ct: &'tcx ty::Const<'tcx>,
ct: ty::Const<'tcx>,
print_ty: bool,
) -> Result<Self::Const, Self::Error> {
define_scoped_cx!(self);
if self.tcx().sess.verbose() {
p!(write("Const({:?}: {:?})", ct.val, ct.ty));
p!(write("Const({:?}: {:?})", ct.val(), ct.ty()));
return Ok(self);
}
@ -1166,7 +1166,7 @@ pub trait PrettyPrinter<'tcx>:
write!(this, "_")?;
Ok(this)
},
|this| this.print_type(ct.ty),
|this| this.print_type(ct.ty()),
": ",
)?;
} else {
@ -1175,7 +1175,7 @@ pub trait PrettyPrinter<'tcx>:
}};
}
match ct.val {
match ct.val() {
ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs,
@ -1206,7 +1206,7 @@ pub trait PrettyPrinter<'tcx>:
ty::ConstKind::Infer(..) => print_underscore!(),
ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
ty::ConstKind::Value(value) => {
return self.pretty_print_const_value(value, ct.ty, print_ty);
return self.pretty_print_const_value(value, ct.ty(), print_ty);
}
ty::ConstKind::Bound(debruijn, bound_var) => {
@ -1248,10 +1248,13 @@ pub trait PrettyPrinter<'tcx>:
kind:
ty::Array(
Ty(Interned(ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, _)),
ty::Const {
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
..
},
ty::Const(Interned(
ty::ConstS {
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
..
},
_,
)),
),
..
},
@ -1435,7 +1438,7 @@ pub trait PrettyPrinter<'tcx>:
Ok(self)
}
(ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {
let n = n.val.try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
let n = n.val().try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
// cast is ok because we already checked for pointer size (32 or 64 bit) above
let range = AllocRange { start: offset, size: Size::from_bytes(n) };
@ -1456,10 +1459,10 @@ pub trait PrettyPrinter<'tcx>:
// FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
// correct `ty::ParamEnv` to allow printing *all* constant values.
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
let contents = self.tcx().destructure_const(
ty::ParamEnv::reveal_all()
.and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })),
);
let contents =
self.tcx().destructure_const(ty::ParamEnv::reveal_all().and(
self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty }),
));
let fields = contents.fields.iter().copied();
match *ty.kind() {
@ -1717,7 +1720,7 @@ impl<'tcx, F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
self.pretty_print_dyn_existential(predicates)
}
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
self.pretty_print_const(ct, true)
}
@ -2454,7 +2457,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
forward_display_to_print! {
Ty<'tcx>,
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
&'tcx ty::Const<'tcx>,
ty::Const<'tcx>,
// HACK(eddyb) these are exhaustive instead of generic,
// because `for<'tcx>` isn't possible yet.

View file

@ -89,9 +89,9 @@ pub trait TypeRelation<'tcx>: Sized {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>>;
fn binders<T>(
&mut self,
@ -545,16 +545,16 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
/// it.
pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
let tcx = relation.tcx();
// FIXME(oli-obk): once const generics can have generic types, this assertion
// will likely get triggered. Move to `normalize_erasing_regions` at that point.
let a_ty = tcx.erase_regions(a.ty);
let b_ty = tcx.erase_regions(b.ty);
let a_ty = tcx.erase_regions(a.ty());
let b_ty = tcx.erase_regions(b.ty());
if a_ty != b_ty {
relation.tcx().sess.delay_span_bug(
DUMMY_SP,
@ -562,14 +562,14 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
);
}
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| x.eval(tcx, relation.param_env());
let eagerly_eval = |x: ty::Const<'tcx>| x.eval(tcx, relation.param_env());
let a = eagerly_eval(a);
let b = eagerly_eval(b);
// Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding
// to structural-match types.
let is_match = match (a.val, b.val) {
let is_match = match (a.val(), b.val()) {
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
// The caller should handle these cases!
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
@ -602,13 +602,13 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
au.substs,
bu.substs,
)?;
return Ok(tcx.mk_const(ty::Const {
return Ok(tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: au.def,
substs,
promoted: au.promoted,
}),
ty: a.ty,
ty: a.ty(),
}));
}
_ => false,
@ -621,8 +621,8 @@ fn check_const_value_eq<'tcx, R: TypeRelation<'tcx>>(
a_val: ConstValue<'tcx>,
b_val: ConstValue<'tcx>,
// FIXME(oli-obk): these arguments should go away with valtrees
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
// FIXME(oli-obk): this should just be `bool` with valtrees
) -> RelateResult<'tcx, bool> {
let tcx = relation.tcx();
@ -648,9 +648,9 @@ fn check_const_value_eq<'tcx, R: TypeRelation<'tcx>>(
}
(ConstValue::ByRef { alloc: alloc_a, .. }, ConstValue::ByRef { alloc: alloc_b, .. })
if a.ty.is_ref() || b.ty.is_ref() =>
if a.ty().is_ref() || b.ty().is_ref() =>
{
if a.ty.is_ref() && b.ty.is_ref() {
if a.ty().is_ref() && b.ty().is_ref() {
alloc_a == alloc_b
} else {
false
@ -663,7 +663,7 @@ fn check_const_value_eq<'tcx, R: TypeRelation<'tcx>>(
// Both the variant and each field have to be equal.
if a_destructured.variant == b_destructured.variant {
for (a_field, b_field) in iter::zip(a_destructured.fields, b_destructured.fields) {
relation.consts(a_field, b_field)?;
relation.consts(*a_field, *b_field)?;
}
true
@ -756,12 +756,12 @@ impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
}
}
impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
impl<'tcx> Relate<'tcx> for ty::Const<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
relation.consts(a, b)
}
}

View file

@ -1159,15 +1159,15 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
let ty = self.ty.try_fold_with(folder)?;
let val = self.val.try_fold_with(folder)?;
if ty != self.ty || val != self.val {
Ok(folder.tcx().mk_const(ty::Const { ty, val }))
let ty = self.ty().try_fold_with(folder)?;
let val = self.val().try_fold_with(folder)?;
if ty != self.ty() || val != self.val() {
Ok(folder.tcx().mk_const(ty::ConstS { ty, val }))
} else {
Ok(self)
}
@ -1178,12 +1178,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.ty.visit_with(visitor)?;
self.val.visit_with(visitor)
self.ty().visit_with(visitor)?;
self.val().visit_with(visitor)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_const(self)
visitor.visit_const(*self)
}
}

View file

@ -116,7 +116,7 @@ pub enum TyKind<'tcx> {
Str,
/// An array with the given length. Written as `[T; N]`.
Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
Array(Ty<'tcx>, ty::Const<'tcx>),
/// The pointee of an array slice. Written as `[T]`.
Slice(Ty<'tcx>),

View file

@ -32,7 +32,7 @@ use std::ops::ControlFlow;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct GenericArg<'tcx> {
ptr: NonZeroUsize,
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>,
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
}
const TAG_MASK: usize = 0b11;
@ -44,7 +44,7 @@ const CONST_TAG: usize = 0b10;
pub enum GenericArgKind<'tcx> {
Lifetime(ty::Region<'tcx>),
Type(Ty<'tcx>),
Const(&'tcx ty::Const<'tcx>),
Const(ty::Const<'tcx>),
}
impl<'tcx> GenericArgKind<'tcx> {
@ -62,8 +62,8 @@ impl<'tcx> GenericArgKind<'tcx> {
}
GenericArgKind::Const(ct) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(ct) & TAG_MASK, 0);
(CONST_TAG, ct as *const ty::Const<'tcx> as usize)
assert_eq!(mem::align_of_val(ct.0.0) & TAG_MASK, 0);
(CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize)
}
};
@ -105,8 +105,8 @@ impl<'tcx> From<Ty<'tcx>> for GenericArg<'tcx> {
}
}
impl<'tcx> From<&'tcx ty::Const<'tcx>> for GenericArg<'tcx> {
fn from(c: &'tcx ty::Const<'tcx>) -> GenericArg<'tcx> {
impl<'tcx> From<ty::Const<'tcx>> for GenericArg<'tcx> {
fn from(c: ty::Const<'tcx>) -> GenericArg<'tcx> {
GenericArgKind::Const(c).pack()
}
}
@ -126,7 +126,9 @@ impl<'tcx> GenericArg<'tcx> {
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::TyS<'tcx>),
))),
CONST_TAG => GenericArgKind::Const(&*((ptr & !TAG_MASK) as *const ty::Const<'tcx>)),
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
))),
_ => intrinsics::unreachable(),
}
}
@ -143,7 +145,7 @@ impl<'tcx> GenericArg<'tcx> {
}
/// Unpack the `GenericArg` as a const when it is known certainly to be a const.
pub fn expect_const(self) -> &'tcx ty::Const<'tcx> {
pub fn expect_const(self) -> ty::Const<'tcx> {
match self.unpack() {
GenericArgKind::Const(c) => c,
_ => bug!("expected a const, but found another kind"),
@ -300,7 +302,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
}
#[inline]
pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::Const<'tcx>> + 'a {
pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None }
})
@ -335,7 +337,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
}
#[inline]
pub fn const_at(&self, i: usize) -> &'tcx ty::Const<'tcx> {
pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
if let GenericArgKind::Const(ct) = self[i].unpack() {
ct
} else {
@ -514,8 +516,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
}
}
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::ConstKind::Param(p) = c.val {
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Param(p) = c.val() {
self.const_for_param(p, c)
} else {
c.super_fold_with(self)
@ -564,11 +566,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
self.shift_vars_through_binders(ty)
}
fn const_for_param(
&self,
p: ParamConst,
source_ct: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
// Look up the const in the substitutions. It really should be in there.
let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack());
let ct = match opt_ct {

View file

@ -6,7 +6,8 @@ use crate::ty::layout::IntegerExt;
use crate::ty::query::TyCtxtAt;
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
use crate::ty::{
self, DebruijnIndex, DefIdTree, List, ReEarlyBound, Region, Ty, TyCtxt, TyKind::*, TypeFoldable,
self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Region, Ty, TyCtxt, TyKind::*,
TypeFoldable,
};
use rustc_apfloat::Float as _;
use rustc_ast as ast;
@ -398,9 +399,10 @@ impl<'tcx> TyCtxt<'tcx> {
ty::TyS { kind: ty::Param(ref pt), .. },
_,
))) => !impl_generics.type_param(pt, self).pure_wrt_drop,
GenericArgKind::Const(&ty::Const {
val: ty::ConstKind::Param(ref pc), ..
}) => !impl_generics.const_param(pc, self).pure_wrt_drop,
GenericArgKind::Const(Const(Interned(
ty::ConstS { val: ty::ConstKind::Param(ref pc), .. },
_,
))) => !impl_generics.const_param(pc, self).pure_wrt_drop,
GenericArgKind::Lifetime(_)
| GenericArgKind::Type(_)
| GenericArgKind::Const(_) => {
@ -622,7 +624,7 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
impl<'tcx> Ty<'tcx> {
/// Returns the maximum value for the given numeric type (including `char`s)
/// or returns `None` if the type is not numeric.
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<Const<'tcx>> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
let (size, signed) = int_size_and_signed(tcx, self);
@ -637,12 +639,12 @@ impl<'tcx> Ty<'tcx> {
}),
_ => None,
};
val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
}
/// Returns the minimum value for the given numeric type (including `char`s)
/// or returns `None` if the type is not numeric.
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<Const<'tcx>> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
let (size, signed) = int_size_and_signed(tcx, self);
@ -656,7 +658,7 @@ impl<'tcx> Ty<'tcx> {
}),
_ => None,
};
val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
val.map(|v| Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
}
/// Checks whether values of this type `T` are *moved* or *copied*
@ -996,7 +998,7 @@ pub fn needs_drop_components<'tcx>(
ty::Array(elem_ty, size) => {
match needs_drop_components(*elem_ty, target_layout) {
Ok(v) if v.is_empty() => Ok(v),
res => match size.val.try_to_bits(target_layout.pointer_size) {
res => match size.val().try_to_bits(target_layout.pointer_size) {
// Arrays of size zero don't need drop, even if their element
// type does.
Some(0) => Ok(SmallVec::new()),

View file

@ -189,8 +189,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
},
GenericArgKind::Lifetime(_) => {}
GenericArgKind::Const(parent_ct) => {
stack.push(parent_ct.ty.into());
match parent_ct.val {
stack.push(parent_ct.ty().into());
match parent_ct.val() {
ty::ConstKind::Infer(_)
| ty::ConstKind::Param(_)
| ty::ConstKind::Placeholder(_)