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:
parent
7eb15509ce
commit
a95fb8b150
116 changed files with 654 additions and 619 deletions
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>) {
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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]),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) },
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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(_)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue