Overhaul TyS
and Ty
.
Specifically, change `Ty` from this: ``` pub type Ty<'tcx> = &'tcx TyS<'tcx>; ``` to this ``` pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>); ``` There are two benefits to this. - It's now a first class type, so we can define methods on it. This means we can move a lot of methods away from `TyS`, leaving `TyS` as a barely-used type, which is appropriate given that it's not meant to be used directly. - The uniqueness requirement is now explicit, via the `Interned` type. E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather than via `TyS`, which wasn't obvious at all. Much of this commit is boring churn. The interesting changes are in these files: - compiler/rustc_middle/src/arena.rs - compiler/rustc_middle/src/mir/visit.rs - compiler/rustc_middle/src/ty/context.rs - compiler/rustc_middle/src/ty/mod.rs Specifically: - Most mentions of `TyS` are removed. It's very much a dumb struct now; `Ty` has all the smarts. - `TyS` now has `crate` visibility instead of `pub`. - `TyS::make_for_test` is removed in favour of the static `BOOL_TY`, which just works better with the new structure. - The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned` (pointer-based, for the `Equal` case) and partly on `TyS` (contents-based, for the other cases). - There are many tedious sigil adjustments, i.e. adding or removing `*` or `&`. They seem to be unavoidable.
This commit is contained in:
parent
0c2ebbd412
commit
e9a0c429c5
145 changed files with 519 additions and 531 deletions
|
@ -2558,7 +2558,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
|||
pub fn ty(&self) -> Ty<'tcx> {
|
||||
match self {
|
||||
ConstantKind::Ty(c) => c.ty,
|
||||
ConstantKind::Val(_, ty) => ty,
|
||||
ConstantKind::Val(_, ty) => *ty,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_middle::mir::interpret::{
|
|||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::MirSource;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, TyCtxt, TyS, TypeFoldable, TypeVisitor};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor};
|
||||
use rustc_target::abi::Size;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
|
@ -427,12 +427,12 @@ impl<'tcx> ExtraComments<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn use_verbose<'tcx>(ty: &&TyS<'tcx>, fn_def: bool) -> bool {
|
||||
match ty.kind() {
|
||||
fn use_verbose<'tcx>(ty: Ty<'tcx>, fn_def: bool) -> bool {
|
||||
match *ty.kind() {
|
||||
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) => false,
|
||||
// Unit type
|
||||
ty::Tuple(g_args) if g_args.is_empty() => false,
|
||||
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(&g_arg.expect_ty(), fn_def)),
|
||||
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(g_arg.expect_ty(), fn_def)),
|
||||
ty::Array(ty, _) => use_verbose(ty, fn_def),
|
||||
ty::FnDef(..) => fn_def,
|
||||
_ => true,
|
||||
|
@ -443,7 +443,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
|||
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
|
||||
self.super_constant(constant, location);
|
||||
let Constant { span, user_ty, literal } = constant;
|
||||
if use_verbose(&literal.ty(), true) {
|
||||
if use_verbose(literal.ty(), true) {
|
||||
self.push("mir::Constant");
|
||||
self.push(&format!(
|
||||
"+ span: {}",
|
||||
|
@ -465,7 +465,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
|||
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
|
||||
self.super_const(constant);
|
||||
let ty::Const { ty, val, .. } = constant;
|
||||
if use_verbose(ty, false) {
|
||||
if use_verbose(*ty, false) {
|
||||
self.push("ty::Const");
|
||||
self.push(&format!("+ ty: {:?}", ty));
|
||||
let val = match val {
|
||||
|
|
|
@ -57,7 +57,7 @@ impl<'tcx> PlaceTy<'tcx> {
|
|||
/// `PlaceElem`, where we can just use the `Ty` that is already
|
||||
/// stored inline on field projection elems.
|
||||
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
|
||||
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, ty| ty)
|
||||
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, &ty| ty)
|
||||
}
|
||||
|
||||
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
|
||||
|
@ -93,11 +93,11 @@ impl<'tcx> PlaceTy<'tcx> {
|
|||
ProjectionElem::Subslice { from, to, from_end } => {
|
||||
PlaceTy::from_ty(match self.ty.kind() {
|
||||
ty::Slice(..) => self.ty,
|
||||
ty::Array(inner, _) if !from_end => tcx.mk_array(inner, (to - from) as u64),
|
||||
ty::Array(inner, _) if !from_end => tcx.mk_array(*inner, (to - from) as u64),
|
||||
ty::Array(inner, size) if from_end => {
|
||||
let size = size.eval_usize(tcx, param_env);
|
||||
let len = size - (from as u64) - (to as u64);
|
||||
tcx.mk_array(inner, len)
|
||||
tcx.mk_array(*inner, len)
|
||||
}
|
||||
_ => bug!("cannot subslice non-array type: `{:?}`", self),
|
||||
})
|
||||
|
|
|
@ -430,7 +430,7 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
pub fn as_switch(&self) -> Option<(&Operand<'tcx>, Ty<'tcx>, &SwitchTargets)> {
|
||||
match self {
|
||||
TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
|
||||
Some((discr, switch_ty, targets))
|
||||
Some((discr, *switch_ty, targets))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -242,7 +242,7 @@ macro_rules! make_mir_visitor {
|
|||
) {
|
||||
let span = body.span;
|
||||
if let Some(gen) = &$($mutability)? body.generator {
|
||||
if let Some(yield_ty) = &$($mutability)? gen.yield_ty {
|
||||
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
|
||||
self.visit_ty(
|
||||
yield_ty,
|
||||
TyContext::YieldTy(SourceInfo::outermost(span))
|
||||
|
@ -266,7 +266,7 @@ macro_rules! make_mir_visitor {
|
|||
}
|
||||
|
||||
self.visit_ty(
|
||||
&$($mutability)? body.return_ty(),
|
||||
$(& $mutability)? body.return_ty(),
|
||||
TyContext::ReturnTy(SourceInfo::outermost(body.span))
|
||||
);
|
||||
|
||||
|
@ -355,7 +355,7 @@ macro_rules! make_mir_visitor {
|
|||
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
|
||||
ty::InstanceDef::CloneShim(_def_id, ty) => {
|
||||
// FIXME(eddyb) use a better `TyContext` here.
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
self.visit_substs(callee_substs, location);
|
||||
|
@ -487,7 +487,7 @@ macro_rules! make_mir_visitor {
|
|||
targets: _
|
||||
} => {
|
||||
self.visit_operand(discr, location);
|
||||
self.visit_ty(switch_ty, TyContext::Location(location));
|
||||
self.visit_ty($(& $mutability)? *switch_ty, TyContext::Location(location));
|
||||
}
|
||||
|
||||
TerminatorKind::Drop {
|
||||
|
@ -680,7 +680,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
Rvalue::Cast(_cast_kind, operand, ty) => {
|
||||
self.visit_operand(operand, location);
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
|
||||
|
@ -702,14 +702,14 @@ macro_rules! make_mir_visitor {
|
|||
}
|
||||
|
||||
Rvalue::NullaryOp(_op, ty) => {
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
|
||||
Rvalue::Aggregate(kind, operands) => {
|
||||
let kind = &$($mutability)? **kind;
|
||||
match kind {
|
||||
AggregateKind::Array(ty) => {
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
AggregateKind::Tuple => {
|
||||
}
|
||||
|
@ -744,7 +744,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
Rvalue::ShallowInitBox(operand, ty) => {
|
||||
self.visit_operand(operand, location);
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -815,7 +815,7 @@ macro_rules! make_mir_visitor {
|
|||
is_block_tail: _,
|
||||
} = local_decl;
|
||||
|
||||
self.visit_ty(ty, TyContext::LocalDecl {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::LocalDecl {
|
||||
local,
|
||||
source_info: *source_info,
|
||||
});
|
||||
|
@ -865,7 +865,7 @@ macro_rules! make_mir_visitor {
|
|||
drop(user_ty); // no visit method for this
|
||||
match literal {
|
||||
ConstantKind::Ty(ct) => self.visit_const(ct, location),
|
||||
ConstantKind::Val(_, t) => self.visit_ty(t, TyContext::Location(location)),
|
||||
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,7 +894,7 @@ macro_rules! make_mir_visitor {
|
|||
ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
|
||||
) {
|
||||
self.visit_span(& $($mutability)? ty.span);
|
||||
self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
|
||||
self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
|
||||
}
|
||||
|
||||
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
|
||||
|
|
|
@ -1146,33 +1146,33 @@ rustc_queries! {
|
|||
desc { "computing whether `{}` is `Copy`", env.value }
|
||||
remap_env_constness
|
||||
}
|
||||
/// Query backing `TyS::is_sized`.
|
||||
/// Query backing `Ty::is_sized`.
|
||||
query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` is `Sized`", env.value }
|
||||
remap_env_constness
|
||||
}
|
||||
/// Query backing `TyS::is_freeze`.
|
||||
/// Query backing `Ty::is_freeze`.
|
||||
query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` is freeze", env.value }
|
||||
remap_env_constness
|
||||
}
|
||||
/// Query backing `TyS::is_unpin`.
|
||||
/// Query backing `Ty::is_unpin`.
|
||||
query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` is `Unpin`", env.value }
|
||||
remap_env_constness
|
||||
}
|
||||
/// Query backing `TyS::needs_drop`.
|
||||
/// Query backing `Ty::needs_drop`.
|
||||
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` needs drop", env.value }
|
||||
remap_env_constness
|
||||
}
|
||||
/// Query backing `TyS::has_significant_drop_raw`.
|
||||
/// Query backing `Ty::has_significant_drop_raw`.
|
||||
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` has a significant drop", env.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
/// Query backing `TyS::is_structural_eq_shallow`.
|
||||
/// Query backing `Ty::is_structural_eq_shallow`.
|
||||
///
|
||||
/// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types
|
||||
/// correctly.
|
||||
|
|
|
@ -77,7 +77,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
|
|||
) => Ok(a),
|
||||
|
||||
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
||||
Err(TypeError::Sorts(relate::expected_found(self, &a, &b)))
|
||||
Err(TypeError::Sorts(relate::expected_found(self, a, b)))
|
||||
}
|
||||
|
||||
(&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()),
|
||||
|
|
|
@ -116,7 +116,7 @@ impl<'tcx> ClosureKind {
|
|||
}
|
||||
|
||||
/// Returns the representative scalar type for this closure kind.
|
||||
/// See `TyS::to_opt_closure_kind` for more details.
|
||||
/// See `Ty::to_opt_closure_kind` for more details.
|
||||
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
match self {
|
||||
ty::ClosureKind::Fn => tcx.types.i8,
|
||||
|
|
|
@ -26,6 +26,7 @@ use crate::ty::{
|
|||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
||||
|
@ -151,19 +152,21 @@ impl<'tcx> CtxtInterners<'tcx> {
|
|||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
#[inline(never)]
|
||||
fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
|
||||
self.type_
|
||||
.intern(kind, |kind| {
|
||||
let flags = super::flags::FlagComputation::for_kind(&kind);
|
||||
Ty(Interned::new_unchecked(
|
||||
self.type_
|
||||
.intern(kind, |kind| {
|
||||
let flags = super::flags::FlagComputation::for_kind(&kind);
|
||||
|
||||
let ty_struct = TyS {
|
||||
kind,
|
||||
flags: flags.flags,
|
||||
outer_exclusive_binder: flags.outer_exclusive_binder,
|
||||
};
|
||||
let ty_struct = TyS {
|
||||
kind,
|
||||
flags: flags.flags,
|
||||
outer_exclusive_binder: flags.outer_exclusive_binder,
|
||||
};
|
||||
|
||||
InternedInSet(self.arena.alloc(ty_struct))
|
||||
})
|
||||
.0
|
||||
InternedInSet(self.arena.alloc(ty_struct))
|
||||
})
|
||||
.0,
|
||||
))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
@ -1628,7 +1631,8 @@ pub trait Lift<'tcx>: fmt::Debug {
|
|||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
|
||||
}
|
||||
|
||||
macro_rules! nop_lift {
|
||||
// Deprecated: we are in the process of converting all uses to `nop_lift`.
|
||||
macro_rules! nop_lift_old {
|
||||
($set:ident; $ty:ty => $lifted:ty) => {
|
||||
impl<'a, 'tcx> Lift<'tcx> for $ty {
|
||||
type Lifted = $lifted;
|
||||
|
@ -1643,6 +1647,21 @@ macro_rules! nop_lift {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! nop_lift {
|
||||
($set:ident; $ty:ty => $lifted:ty) => {
|
||||
impl<'a, 'tcx> Lift<'tcx> for $ty {
|
||||
type Lifted = $lifted;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
if tcx.interners.$set.contains_pointer_to(&InternedInSet(self.0.0)) {
|
||||
Some(unsafe { mem::transmute(self) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! nop_list_lift {
|
||||
($set:ident; $ty:ty => $lifted:ty) => {
|
||||
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
|
||||
|
@ -1662,10 +1681,10 @@ macro_rules! nop_list_lift {
|
|||
}
|
||||
|
||||
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
|
||||
nop_lift! {region; Region<'a> => Region<'tcx>}
|
||||
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
|
||||
nop_lift! {const_allocation; &'a Allocation => &'tcx Allocation}
|
||||
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
|
||||
nop_lift_old! {region; Region<'a> => Region<'tcx>}
|
||||
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
|
||||
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
|
||||
nop_lift_old! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
|
||||
|
||||
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
|
||||
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
|
||||
|
@ -1882,15 +1901,15 @@ macro_rules! sty_debug_print {
|
|||
let shards = tcx.interners.type_.lock_shards();
|
||||
let types = shards.iter().flat_map(|shard| shard.keys());
|
||||
for &InternedInSet(t) in types {
|
||||
let variant = match t.kind() {
|
||||
let variant = match t.kind {
|
||||
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
|
||||
ty::Float(..) | ty::Str | ty::Never => continue,
|
||||
ty::Error(_) => /* unimportant */ continue,
|
||||
$(ty::$variant(..) => &mut $variant,)*
|
||||
};
|
||||
let lt = t.flags().intersects(ty::TypeFlags::HAS_RE_INFER);
|
||||
let ty = t.flags().intersects(ty::TypeFlags::HAS_TY_INFER);
|
||||
let ct = t.flags().intersects(ty::TypeFlags::HAS_CT_INFER);
|
||||
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
|
||||
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
|
||||
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
|
||||
|
||||
variant.total += 1;
|
||||
total.total += 1;
|
||||
|
@ -2000,7 +2019,7 @@ impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
|
|||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, TyS<'tcx>> {
|
||||
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
|
||||
&self.0.kind()
|
||||
&self.0.kind
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2008,7 +2027,7 @@ impl<'tcx> PartialEq for InternedInSet<'tcx, TyS<'tcx>> {
|
|||
fn eq(&self, other: &InternedInSet<'tcx, TyS<'tcx>>) -> bool {
|
||||
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
|
||||
// `x == y`.
|
||||
self.0.kind() == other.0.kind()
|
||||
self.0.kind == other.0.kind
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2017,7 +2036,7 @@ impl<'tcx> Eq for InternedInSet<'tcx, TyS<'tcx>> {}
|
|||
impl<'tcx> Hash for InternedInSet<'tcx, TyS<'tcx>> {
|
||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
|
||||
self.0.kind().hash(s)
|
||||
self.0.kind.hash(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! Diagnostics related methods for `TyS`.
|
||||
//! Diagnostics related methods for `Ty`.
|
||||
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind};
|
||||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{
|
||||
ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
|
||||
ProjectionTy, Term, TyCtxt, TyS, TypeAndMut,
|
||||
ProjectionTy, Term, Ty, TyCtxt, TypeAndMut,
|
||||
};
|
||||
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
|
@ -13,9 +13,9 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate};
|
||||
use rustc_span::Span;
|
||||
|
||||
impl<'tcx> TyS<'tcx> {
|
||||
/// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive.
|
||||
pub fn is_primitive_ty(&self) -> bool {
|
||||
impl<'tcx> Ty<'tcx> {
|
||||
/// Similar to `Ty::is_primitive`, but also considers inferred numeric values to be primitive.
|
||||
pub fn is_primitive_ty(self) -> bool {
|
||||
matches!(
|
||||
self.kind(),
|
||||
Bool | Char
|
||||
|
@ -34,7 +34,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
/// Whether the type is succinctly representable as a type instead of just referred to with a
|
||||
/// description in error messages. This is used in the main error message.
|
||||
pub fn is_simple_ty(&self) -> bool {
|
||||
pub fn is_simple_ty(self) -> bool {
|
||||
match self.kind() {
|
||||
Bool
|
||||
| Char
|
||||
|
@ -58,7 +58,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
/// description in error messages. This is used in the primary span label. Beyond what
|
||||
/// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
|
||||
/// ADTs with no type arguments.
|
||||
pub fn is_simple_text(&self) -> bool {
|
||||
pub fn is_simple_text(self) -> bool {
|
||||
match self.kind() {
|
||||
Adt(_, substs) => substs.non_erasable_generics().next().is_none(),
|
||||
Ref(_, ty, _) => ty.is_simple_text(),
|
||||
|
@ -67,7 +67,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
/// Whether the type can be safely suggested during error recovery.
|
||||
pub fn is_suggestable(&self) -> bool {
|
||||
pub fn is_suggestable(self) -> bool {
|
||||
fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
|
||||
match arg.unpack() {
|
||||
GenericArgKind::Type(ty) => ty.is_suggestable(),
|
||||
|
|
|
@ -239,8 +239,8 @@ impl<'tcx> TypeError<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::TyS<'tcx> {
|
||||
pub fn sort_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
|
||||
impl<'tcx> Ty<'tcx> {
|
||||
pub fn sort_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
|
||||
match *self.kind() {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => {
|
||||
format!("`{}`", self).into()
|
||||
|
@ -306,7 +306,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn prefix_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
|
||||
pub fn prefix_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
|
||||
match *self.kind() {
|
||||
ty::Infer(_)
|
||||
| ty::Error(_)
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::slice;
|
|||
pub struct FlagComputation {
|
||||
pub flags: TypeFlags,
|
||||
|
||||
// see `TyS::outer_exclusive_binder` for details
|
||||
// see `Ty::outer_exclusive_binder` for details
|
||||
pub outer_exclusive_binder: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ impl FlagComputation {
|
|||
|
||||
fn add_ty(&mut self, ty: Ty<'_>) {
|
||||
self.add_flags(ty.flags());
|
||||
self.add_exclusive_binder(ty.outer_exclusive_binder);
|
||||
self.add_exclusive_binder(ty.outer_exclusive_binder());
|
||||
}
|
||||
|
||||
fn add_tys(&mut self, tys: &[Ty<'_>]) {
|
||||
|
|
|
@ -627,7 +627,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
|||
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
||||
if let Some(fld_t) = self.fld_t.as_mut() {
|
||||
let ty = fld_t(bound_ty);
|
||||
return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32());
|
||||
return ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32());
|
||||
}
|
||||
}
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) => {
|
||||
|
@ -926,7 +926,7 @@ impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if t.outer_exclusive_binder < self.binder_index
|
||||
if t.outer_exclusive_binder() < self.binder_index
|
||||
|| !self.visited.insert((self.binder_index, t))
|
||||
{
|
||||
return ControlFlow::BREAK;
|
||||
|
@ -1146,7 +1146,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
|
|||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
if t.outer_exclusive_binder > self.outer_index {
|
||||
if t.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
|
|
|
@ -3,7 +3,7 @@ pub use self::def_id_forest::DefIdForest;
|
|||
use crate::ty;
|
||||
use crate::ty::context::TyCtxt;
|
||||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{AdtDef, FieldDef, Ty, TyS, VariantDef};
|
||||
use crate::ty::{AdtDef, FieldDef, Ty, VariantDef};
|
||||
use crate::ty::{AdtKind, Visibility};
|
||||
use crate::ty::{DefId, SubstsRef};
|
||||
|
||||
|
@ -184,10 +184,10 @@ impl<'tcx> FieldDef {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TyS<'tcx> {
|
||||
impl<'tcx> Ty<'tcx> {
|
||||
/// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
|
||||
fn uninhabited_from(
|
||||
&'tcx self,
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> DefIdForest<'tcx> {
|
||||
|
|
|
@ -101,7 +101,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
|
||||
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
|
||||
let ty = tcx.type_of(self.def.def_id());
|
||||
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty)
|
||||
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty)
|
||||
}
|
||||
|
||||
/// Finds a crate that contains a monomorphization of this instance that
|
||||
|
@ -642,7 +642,7 @@ fn polymorphize<'tcx>(
|
|||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
debug!("fold_ty: ty={:?}", ty);
|
||||
match ty.kind {
|
||||
match *ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
let polymorphized_substs = polymorphize(
|
||||
self.tcx,
|
||||
|
|
|
@ -29,6 +29,7 @@ use crate::ty::util::Discr;
|
|||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||
use rustc_hir as hir;
|
||||
|
@ -42,7 +43,6 @@ use rustc_span::symbol::{kw, Ident, Symbol};
|
|||
use rustc_span::{sym, Span};
|
||||
use rustc_target::abi::Align;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::ControlFlow;
|
||||
use std::{fmt, ptr, str};
|
||||
|
@ -380,21 +380,25 @@ pub struct CReaderCacheKey {
|
|||
|
||||
/// Represents a type.
|
||||
///
|
||||
/// IMPORTANT: Every `TyS` is *required* to have unique contents. The type's
|
||||
/// correctness relies on this, *but it does not enforce it*. Therefore, any
|
||||
/// code that creates a `TyS` must ensure uniqueness itself. In practice this
|
||||
/// is achieved by interning.
|
||||
/// IMPORTANT:
|
||||
/// - This is a very "dumb" struct (with no derives and no `impls`).
|
||||
/// - Values of this type are always interned and thus unique, and are stored
|
||||
/// as an `Interned<TyS>`.
|
||||
/// - `Ty` (which contains a reference to a `Interned<TyS>`) or `Interned<TyS>`
|
||||
/// should be used everywhere instead of `TyS`. In particular, `Ty` has most
|
||||
/// of the relevant methods.
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
pub struct TyS<'tcx> {
|
||||
crate struct TyS<'tcx> {
|
||||
/// This field shouldn't be used directly and may be removed in the future.
|
||||
/// Use `TyS::kind()` instead.
|
||||
/// Use `Ty::kind()` instead.
|
||||
kind: TyKind<'tcx>,
|
||||
|
||||
/// This field provides fast access to information that is also contained
|
||||
/// in `kind`.
|
||||
///
|
||||
/// This field shouldn't be used directly and may be removed in the future.
|
||||
/// Use `TyS::flags()` instead.
|
||||
/// Use `Ty::flags()` instead.
|
||||
flags: TypeFlags,
|
||||
|
||||
/// This field provides fast access to information that is also contained
|
||||
|
@ -420,55 +424,27 @@ pub struct TyS<'tcx> {
|
|||
outer_exclusive_binder: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<'tcx> TyS<'tcx> {
|
||||
/// A constructor used only for internal testing.
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
pub fn make_for_test(
|
||||
kind: TyKind<'tcx>,
|
||||
flags: TypeFlags,
|
||||
outer_exclusive_binder: ty::DebruijnIndex,
|
||||
) -> TyS<'tcx> {
|
||||
TyS { kind, flags, outer_exclusive_binder }
|
||||
}
|
||||
}
|
||||
|
||||
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(TyS<'_>, 40);
|
||||
|
||||
impl<'tcx> Ord for TyS<'tcx> {
|
||||
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
|
||||
self.kind().cmp(other.kind())
|
||||
}
|
||||
}
|
||||
/// Use this rather than `TyS`, whenever possible.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[rustc_diagnostic_item = "Ty"]
|
||||
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
|
||||
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
|
||||
|
||||
impl<'tcx> PartialOrd for TyS<'tcx> {
|
||||
fn partial_cmp(&self, other: &TyS<'tcx>) -> Option<Ordering> {
|
||||
Some(self.kind().cmp(other.kind()))
|
||||
}
|
||||
}
|
||||
// Statics only used for internal testing.
|
||||
pub static BOOL_TY: Ty<'static> = Ty(Interned::new_unchecked(&BOOL_TYS));
|
||||
static BOOL_TYS: TyS<'static> = TyS {
|
||||
kind: ty::Bool,
|
||||
flags: TypeFlags::empty(),
|
||||
outer_exclusive_binder: DebruijnIndex::from_usize(0),
|
||||
};
|
||||
|
||||
impl<'tcx> PartialEq for TyS<'tcx> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &TyS<'tcx>) -> bool {
|
||||
// Pointer equality implies equality (due to the unique contents
|
||||
// assumption).
|
||||
ptr::eq(self, other)
|
||||
}
|
||||
}
|
||||
impl<'tcx> Eq for TyS<'tcx> {}
|
||||
|
||||
impl<'tcx> Hash for TyS<'tcx> {
|
||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||
// Pointer hashing is sufficient (due to the unique contents
|
||||
// assumption).
|
||||
(self as *const TyS<'_>).hash(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Ty<'tcx> {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
let ty::TyS {
|
||||
let TyS {
|
||||
ref kind,
|
||||
|
||||
// The other fields just provide fast access to information that is
|
||||
|
@ -476,16 +452,12 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
|
|||
flags: _,
|
||||
|
||||
outer_exclusive_binder: _,
|
||||
} = *self;
|
||||
} = self.0.0;
|
||||
|
||||
kind.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_diagnostic_item = "Ty"]
|
||||
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
|
||||
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
|
||||
|
||||
impl ty::EarlyBoundRegion {
|
||||
/// Does this early bound region have a name? Early bound regions normally
|
||||
/// always have names except when using anonymous lifetimes (`'_`).
|
||||
|
@ -864,7 +836,7 @@ impl<'tcx> From<&'tcx Const<'tcx>> for Term<'tcx> {
|
|||
|
||||
impl<'tcx> Term<'tcx> {
|
||||
pub fn ty(&self) -> Option<Ty<'tcx>> {
|
||||
if let Term::Ty(ty) = self { Some(ty) } else { None }
|
||||
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 }
|
||||
|
|
|
@ -346,7 +346,7 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
|
|||
type Output = P::Type;
|
||||
type Error = P::Error;
|
||||
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
|
||||
cx.print_type(self)
|
||||
cx.print_type(*self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
|
|||
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_apfloat::ieee::{Double, Single};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
|
||||
|
@ -1232,16 +1233,20 @@ pub trait PrettyPrinter<'tcx>:
|
|||
// Byte strings (&[u8; N])
|
||||
ty::Ref(
|
||||
_,
|
||||
ty::TyS {
|
||||
kind:
|
||||
ty::Array(
|
||||
ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. },
|
||||
ty::Const {
|
||||
val: ty::ConstKind::Value(ConstValue::Scalar(int)), ..
|
||||
},
|
||||
),
|
||||
..
|
||||
},
|
||||
Ty(Interned(
|
||||
ty::TyS {
|
||||
kind:
|
||||
ty::Array(
|
||||
Ty(Interned(ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, _)),
|
||||
ty::Const {
|
||||
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
|
||||
..
|
||||
},
|
||||
),
|
||||
..
|
||||
},
|
||||
_,
|
||||
)),
|
||||
_,
|
||||
) => match self.tcx().get_global_alloc(alloc_id) {
|
||||
Some(GlobalAlloc::Memory(alloc)) => {
|
||||
|
@ -1399,7 +1404,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
// Byte/string slices, printed as (byte) string literals.
|
||||
(
|
||||
ConstValue::Slice { data, start, end },
|
||||
ty::Ref(_, ty::TyS { kind: ty::Slice(t), .. }, _),
|
||||
ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Slice(t), .. }, _)), _),
|
||||
) if *t == u8_type => {
|
||||
// The `inspect` here is okay since we checked the bounds, and there are
|
||||
// no relocations (we have an active slice reference here). We don't use
|
||||
|
@ -1409,7 +1414,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
}
|
||||
(
|
||||
ConstValue::Slice { data, start, end },
|
||||
ty::Ref(_, ty::TyS { kind: ty::Str, .. }, _),
|
||||
ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Str, .. }, _)), _),
|
||||
) => {
|
||||
// The `inspect` here is okay since we checked the bounds, and there are no
|
||||
// relocations (we have an active `str` reference here). We don't use this
|
||||
|
|
|
@ -149,8 +149,8 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
|
|||
Some((ty_def_id, variances)) => {
|
||||
let variance = variances[i];
|
||||
let variance_info = if variance == ty::Invariant {
|
||||
let ty =
|
||||
cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
|
||||
let ty = *cached_ty
|
||||
.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
|
||||
ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
|
||||
} else {
|
||||
ty::VarianceDiagInfo::default()
|
||||
|
|
|
@ -1078,7 +1078,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
visitor.visit_ty(self)
|
||||
visitor.visit_ty(*self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::ty::fold::ValidateBoundVars;
|
|||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::InferTy::{self, *};
|
||||
use crate::ty::{self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable};
|
||||
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
|
||||
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv};
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_hir as hir;
|
||||
|
@ -196,7 +196,7 @@ pub enum TyKind<'tcx> {
|
|||
Never,
|
||||
|
||||
/// A tuple type. For example, `(i32, bool)`.
|
||||
/// Use `TyS::tuple_fields` to iterate over the field types.
|
||||
/// Use `Ty::tuple_fields` to iterate over the field types.
|
||||
Tuple(SubstsRef<'tcx>),
|
||||
|
||||
/// The projection of an associated type. For example,
|
||||
|
@ -282,7 +282,7 @@ static_assert_size!(TyKind<'_>, 32);
|
|||
/// in scope on the function that defined the closure,
|
||||
/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
|
||||
/// is rather hackily encoded via a scalar type. See
|
||||
/// `TyS::to_opt_closure_kind` for details.
|
||||
/// `Ty::to_opt_closure_kind` for details.
|
||||
/// - CS represents the *closure signature*, representing as a `fn()`
|
||||
/// type. For example, `fn(u32, u32) -> u32` would mean that the closure
|
||||
/// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
|
||||
|
@ -1756,19 +1756,19 @@ impl RegionKind {
|
|||
}
|
||||
|
||||
/// Type utilities
|
||||
impl<'tcx> TyS<'tcx> {
|
||||
impl<'tcx> Ty<'tcx> {
|
||||
#[inline(always)]
|
||||
pub fn kind(&self) -> &TyKind<'tcx> {
|
||||
&self.kind
|
||||
pub fn kind(self) -> &'tcx TyKind<'tcx> {
|
||||
&self.0.0.kind
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn flags(&self) -> TypeFlags {
|
||||
self.flags
|
||||
pub fn flags(self) -> TypeFlags {
|
||||
self.0.0.flags
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_unit(&self) -> bool {
|
||||
pub fn is_unit(self) -> bool {
|
||||
match self.kind() {
|
||||
Tuple(ref tys) => tys.is_empty(),
|
||||
_ => false,
|
||||
|
@ -1776,32 +1776,32 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_never(&self) -> bool {
|
||||
pub fn is_never(self) -> bool {
|
||||
matches!(self.kind(), Never)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_primitive(&self) -> bool {
|
||||
pub fn is_primitive(self) -> bool {
|
||||
self.kind().is_primitive()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_adt(&self) -> bool {
|
||||
pub fn is_adt(self) -> bool {
|
||||
matches!(self.kind(), Adt(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ref(&self) -> bool {
|
||||
pub fn is_ref(self) -> bool {
|
||||
matches!(self.kind(), Ref(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ty_var(&self) -> bool {
|
||||
pub fn is_ty_var(self) -> bool {
|
||||
matches!(self.kind(), Infer(TyVar(_)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ty_vid(&self) -> Option<ty::TyVid> {
|
||||
pub fn ty_vid(self) -> Option<ty::TyVid> {
|
||||
match self.kind() {
|
||||
&Infer(TyVar(vid)) => Some(vid),
|
||||
_ => None,
|
||||
|
@ -1809,28 +1809,28 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ty_infer(&self) -> bool {
|
||||
pub fn is_ty_infer(self) -> bool {
|
||||
matches!(self.kind(), Infer(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_phantom_data(&self) -> bool {
|
||||
pub fn is_phantom_data(self) -> bool {
|
||||
if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_bool(&self) -> bool {
|
||||
pub fn is_bool(self) -> bool {
|
||||
*self.kind() == Bool
|
||||
}
|
||||
|
||||
/// Returns `true` if this type is a `str`.
|
||||
#[inline]
|
||||
pub fn is_str(&self) -> bool {
|
||||
pub fn is_str(self) -> bool {
|
||||
*self.kind() == Str
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_param(&self, index: u32) -> bool {
|
||||
pub fn is_param(self, index: u32) -> bool {
|
||||
match self.kind() {
|
||||
ty::Param(ref data) => data.index == index,
|
||||
_ => false,
|
||||
|
@ -1838,7 +1838,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_slice(&self) -> bool {
|
||||
pub fn is_slice(self) -> bool {
|
||||
match self.kind() {
|
||||
RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => matches!(ty.kind(), Slice(_) | Str),
|
||||
_ => false,
|
||||
|
@ -1846,27 +1846,27 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_array(&self) -> bool {
|
||||
pub fn is_array(self) -> bool {
|
||||
matches!(self.kind(), Array(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_simd(&self) -> bool {
|
||||
pub fn is_simd(self) -> bool {
|
||||
match self.kind() {
|
||||
Adt(def, _) => def.repr.simd(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
match self.kind() {
|
||||
Array(ty, _) | Slice(ty) => ty,
|
||||
Array(ty, _) | Slice(ty) => *ty,
|
||||
Str => tcx.types.u8,
|
||||
_ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
|
||||
pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
|
||||
match self.kind() {
|
||||
Adt(def, substs) => {
|
||||
assert!(def.repr.simd(), "`simd_size_and_type` called on non-SIMD type");
|
||||
|
@ -1881,7 +1881,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
// The way we evaluate the `N` in `[T; N]` here only works since we use
|
||||
// `simd_size_and_type` post-monomorphization. It will probably start to ICE
|
||||
// if we use it in generic code. See the `simd-array-trait` ui test.
|
||||
(f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, f0_elem_ty)
|
||||
(f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, *f0_elem_ty)
|
||||
}
|
||||
// Otherwise, the fields of this Adt are the SIMD components (and we assume they
|
||||
// all have the same type).
|
||||
|
@ -1893,12 +1893,12 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_region_ptr(&self) -> bool {
|
||||
pub fn is_region_ptr(self) -> bool {
|
||||
matches!(self.kind(), Ref(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_mutable_ptr(&self) -> bool {
|
||||
pub fn is_mutable_ptr(self) -> bool {
|
||||
matches!(
|
||||
self.kind(),
|
||||
RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. })
|
||||
|
@ -1908,7 +1908,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
/// Get the mutability of the reference or `None` when not a reference
|
||||
#[inline]
|
||||
pub fn ref_mutability(&self) -> Option<hir::Mutability> {
|
||||
pub fn ref_mutability(self) -> Option<hir::Mutability> {
|
||||
match self.kind() {
|
||||
Ref(_, _, mutability) => Some(*mutability),
|
||||
_ => None,
|
||||
|
@ -1916,18 +1916,18 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_unsafe_ptr(&self) -> bool {
|
||||
pub fn is_unsafe_ptr(self) -> bool {
|
||||
matches!(self.kind(), RawPtr(_))
|
||||
}
|
||||
|
||||
/// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
|
||||
#[inline]
|
||||
pub fn is_any_ptr(&self) -> bool {
|
||||
pub fn is_any_ptr(self) -> bool {
|
||||
self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_box(&self) -> bool {
|
||||
pub fn is_box(self) -> bool {
|
||||
match self.kind() {
|
||||
Adt(def, _) => def.is_box(),
|
||||
_ => false,
|
||||
|
@ -1935,7 +1935,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
/// Panics if called on any type other than `Box<T>`.
|
||||
pub fn boxed_ty(&self) -> Ty<'tcx> {
|
||||
pub fn boxed_ty(self) -> Ty<'tcx> {
|
||||
match self.kind() {
|
||||
Adt(def, substs) if def.is_box() => substs.type_at(0),
|
||||
_ => bug!("`boxed_ty` is called on non-box type {:?}", self),
|
||||
|
@ -1946,7 +1946,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
/// (A RawPtr is scalar because it represents a non-managed pointer, so its
|
||||
/// contents are abstract to rustc.)
|
||||
#[inline]
|
||||
pub fn is_scalar(&self) -> bool {
|
||||
pub fn is_scalar(self) -> bool {
|
||||
matches!(
|
||||
self.kind(),
|
||||
Bool | Char
|
||||
|
@ -1962,72 +1962,72 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
/// Returns `true` if this type is a floating point type.
|
||||
#[inline]
|
||||
pub fn is_floating_point(&self) -> bool {
|
||||
pub fn is_floating_point(self) -> bool {
|
||||
matches!(self.kind(), Float(_) | Infer(FloatVar(_)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_trait(&self) -> bool {
|
||||
pub fn is_trait(self) -> bool {
|
||||
matches!(self.kind(), Dynamic(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_enum(&self) -> bool {
|
||||
pub fn is_enum(self) -> bool {
|
||||
matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_union(&self) -> bool {
|
||||
pub fn is_union(self) -> bool {
|
||||
matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_closure(&self) -> bool {
|
||||
pub fn is_closure(self) -> bool {
|
||||
matches!(self.kind(), Closure(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_generator(&self) -> bool {
|
||||
pub fn is_generator(self) -> bool {
|
||||
matches!(self.kind(), Generator(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_integral(&self) -> bool {
|
||||
pub fn is_integral(self) -> bool {
|
||||
matches!(self.kind(), Infer(IntVar(_)) | Int(_) | Uint(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_fresh_ty(&self) -> bool {
|
||||
pub fn is_fresh_ty(self) -> bool {
|
||||
matches!(self.kind(), Infer(FreshTy(_)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_fresh(&self) -> bool {
|
||||
pub fn is_fresh(self) -> bool {
|
||||
matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_char(&self) -> bool {
|
||||
pub fn is_char(self) -> bool {
|
||||
matches!(self.kind(), Char)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_numeric(&self) -> bool {
|
||||
pub fn is_numeric(self) -> bool {
|
||||
self.is_integral() || self.is_floating_point()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_signed(&self) -> bool {
|
||||
pub fn is_signed(self) -> bool {
|
||||
matches!(self.kind(), Int(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ptr_sized_integral(&self) -> bool {
|
||||
pub fn is_ptr_sized_integral(self) -> bool {
|
||||
matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_concrete_skeleton(&self) -> bool {
|
||||
pub fn has_concrete_skeleton(self) -> bool {
|
||||
!matches!(self.kind(), Param(_) | Infer(_) | Error(_))
|
||||
}
|
||||
|
||||
|
@ -2035,26 +2035,26 @@ impl<'tcx> TyS<'tcx> {
|
|||
///
|
||||
/// The parameter `explicit` indicates if this is an *explicit* dereference.
|
||||
/// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
|
||||
pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
|
||||
pub fn builtin_deref(self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
|
||||
match self.kind() {
|
||||
Adt(def, _) if def.is_box() => {
|
||||
Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not })
|
||||
}
|
||||
Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl: *mutbl }),
|
||||
Ref(_, ty, mutbl) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }),
|
||||
RawPtr(mt) if explicit => Some(*mt),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the type of `ty[i]`.
|
||||
pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
|
||||
pub fn builtin_index(self) -> Option<Ty<'tcx>> {
|
||||
match self.kind() {
|
||||
Array(ty, _) | Slice(ty) => Some(ty),
|
||||
Array(ty, _) | Slice(ty) => Some(*ty),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
|
||||
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
|
||||
match self.kind() {
|
||||
FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs),
|
||||
FnPtr(f) => *f,
|
||||
|
@ -2070,22 +2070,22 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_fn(&self) -> bool {
|
||||
pub fn is_fn(self) -> bool {
|
||||
matches!(self.kind(), FnDef(..) | FnPtr(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_fn_ptr(&self) -> bool {
|
||||
pub fn is_fn_ptr(self) -> bool {
|
||||
matches!(self.kind(), FnPtr(_))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_impl_trait(&self) -> bool {
|
||||
pub fn is_impl_trait(self) -> bool {
|
||||
matches!(self.kind(), Opaque(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
|
||||
pub fn ty_adt_def(self) -> Option<&'tcx AdtDef> {
|
||||
match self.kind() {
|
||||
Adt(adt, _) => Some(adt),
|
||||
_ => None,
|
||||
|
@ -2094,7 +2094,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
/// Iterates over tuple fields.
|
||||
/// Panics when called on anything but a tuple.
|
||||
pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
|
||||
pub fn tuple_fields(self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
|
||||
match self.kind() {
|
||||
Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
|
||||
_ => bug!("tuple_fields called on non-tuple"),
|
||||
|
@ -2103,7 +2103,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
/// Get the `i`-th element of a tuple.
|
||||
/// Panics when called on anything but a tuple.
|
||||
pub fn tuple_element_ty(&self, i: usize) -> Option<Ty<'tcx>> {
|
||||
pub fn tuple_element_ty(self, i: usize) -> Option<Ty<'tcx>> {
|
||||
match self.kind() {
|
||||
Tuple(substs) => substs.iter().nth(i).map(|field| field.expect_ty()),
|
||||
_ => bug!("tuple_fields called on non-tuple"),
|
||||
|
@ -2114,7 +2114,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
//
|
||||
// FIXME: This requires the optimized MIR in the case of generators.
|
||||
#[inline]
|
||||
pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
|
||||
pub fn variant_range(self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
|
||||
match self.kind() {
|
||||
TyKind::Adt(adt, _) => Some(adt.variant_range()),
|
||||
TyKind::Generator(def_id, substs, _) => {
|
||||
|
@ -2130,7 +2130,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
// FIXME: This requires the optimized MIR in the case of generators.
|
||||
#[inline]
|
||||
pub fn discriminant_for_variant(
|
||||
&self,
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
variant_index: VariantIdx,
|
||||
) -> Option<Discr<'tcx>> {
|
||||
|
@ -2151,7 +2151,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
}
|
||||
|
||||
/// Returns the type of the discriminant of this type.
|
||||
pub fn discriminant_ty(&'tcx self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
match self.kind() {
|
||||
ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
|
||||
ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
|
||||
|
@ -2195,7 +2195,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
/// Returns the type of metadata for (potentially fat) pointers to this type.
|
||||
pub fn ptr_metadata_ty(
|
||||
&'tcx self,
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
|
@ -2256,7 +2256,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
/// to represent the closure kind, because it has not yet been
|
||||
/// inferred. Once upvar inference (in `rustc_typeck/src/check/upvar.rs`)
|
||||
/// is complete, that type variable will be unified.
|
||||
pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
|
||||
pub fn to_opt_closure_kind(self) -> Option<ty::ClosureKind> {
|
||||
match self.kind() {
|
||||
Int(int_ty) => match int_ty {
|
||||
ty::IntTy::I8 => Some(ty::ClosureKind::Fn),
|
||||
|
@ -2285,7 +2285,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
/// bound such as `[_]: Copy`. A function with such a bound obviously never
|
||||
/// can be called, but that doesn't mean it shouldn't typecheck. This is why
|
||||
/// this method doesn't return `Option<bool>`.
|
||||
pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
match self.kind() {
|
||||
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||
| ty::Uint(_)
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}
|
|||
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_serialize::{self, Decodable, Encodable};
|
||||
|
@ -49,17 +50,17 @@ impl<'tcx> GenericArgKind<'tcx> {
|
|||
GenericArgKind::Lifetime(lt) => {
|
||||
// Ensure we can use the tag bits.
|
||||
assert_eq!(mem::align_of_val(lt) & TAG_MASK, 0);
|
||||
(REGION_TAG, lt as *const _ as usize)
|
||||
(REGION_TAG, lt as *const ty::RegionKind as usize)
|
||||
}
|
||||
GenericArgKind::Type(ty) => {
|
||||
// Ensure we can use the tag bits.
|
||||
assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0);
|
||||
(TYPE_TAG, ty as *const _ as usize)
|
||||
assert_eq!(mem::align_of_val(ty.0.0) & TAG_MASK, 0);
|
||||
(TYPE_TAG, ty.0.0 as *const ty::TyS<'tcx> as usize)
|
||||
}
|
||||
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 _ as usize)
|
||||
(CONST_TAG, ct as *const ty::Const<'tcx> as usize)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -111,11 +112,18 @@ impl<'tcx> GenericArg<'tcx> {
|
|||
#[inline]
|
||||
pub fn unpack(self) -> GenericArgKind<'tcx> {
|
||||
let ptr = self.ptr.get();
|
||||
// SAFETY: use of `Interned::new_unchecked` here is ok because these
|
||||
// pointers were originally created from `Interned` types in `pack()`,
|
||||
// and this is just going in the other direction.
|
||||
unsafe {
|
||||
match ptr & TAG_MASK {
|
||||
REGION_TAG => GenericArgKind::Lifetime(&*((ptr & !TAG_MASK) as *const _)),
|
||||
TYPE_TAG => GenericArgKind::Type(&*((ptr & !TAG_MASK) as *const _)),
|
||||
CONST_TAG => GenericArgKind::Const(&*((ptr & !TAG_MASK) as *const _)),
|
||||
REGION_TAG => {
|
||||
GenericArgKind::Lifetime(&*((ptr & !TAG_MASK) as *const ty::RegionKind))
|
||||
}
|
||||
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>)),
|
||||
_ => intrinsics::unreachable(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use rustc_apfloat::Float as _;
|
|||
use rustc_ast as ast;
|
||||
use rustc_attr::{self as attr, SignedInt, UnsignedInt};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_hir as hir;
|
||||
|
@ -392,9 +393,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
GenericArgKind::Lifetime(&ty::RegionKind::ReEarlyBound(ref ebr)) => {
|
||||
!impl_generics.region_param(ebr, self).pure_wrt_drop
|
||||
}
|
||||
GenericArgKind::Type(&ty::TyS { kind: ty::Param(ref pt), .. }) => {
|
||||
!impl_generics.type_param(pt, self).pure_wrt_drop
|
||||
}
|
||||
GenericArgKind::Type(Ty(Interned(
|
||||
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,
|
||||
|
@ -577,7 +579,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
|
|||
let substs = substs.fold_with(self);
|
||||
if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
|
||||
let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
|
||||
Some(expanded_ty) => expanded_ty,
|
||||
Some(expanded_ty) => *expanded_ty,
|
||||
None => {
|
||||
let generic_ty = self.tcx.type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx, substs);
|
||||
|
@ -606,7 +608,7 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
|
|||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if let ty::Opaque(def_id, substs) = t.kind {
|
||||
if let ty::Opaque(def_id, substs) = *t.kind() {
|
||||
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
|
||||
} else if t.has_opaque_types() {
|
||||
t.super_fold_with(self)
|
||||
|
@ -616,10 +618,10 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::TyS<'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(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
|
||||
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
|
||||
let val = match self.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => {
|
||||
let (size, signed) = int_size_and_signed(tcx, self);
|
||||
|
@ -639,7 +641,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
|
||||
/// 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(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
|
||||
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
|
||||
let val = match self.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => {
|
||||
let (size, signed) = int_size_and_signed(tcx, self);
|
||||
|
@ -664,7 +666,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
/// full requirements for the `Copy` trait (cc #29149) -- this
|
||||
/// winds up being reported as an error during NLL borrow check.
|
||||
pub fn is_copy_modulo_regions(
|
||||
&'tcx self,
|
||||
self,
|
||||
tcx_at: TyCtxtAt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> bool {
|
||||
|
@ -677,7 +679,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
/// over-approximation in generic contexts, where one can have
|
||||
/// strange rules like `<T as Foo<'static>>::Bar: Sized` that
|
||||
/// actually carry lifetime requirements.
|
||||
pub fn is_sized(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn is_sized(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
self.is_trivially_sized(tcx_at.tcx) || tcx_at.is_sized_raw(param_env.and(self))
|
||||
}
|
||||
|
||||
|
@ -688,7 +690,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
/// optimization as well as the rules around static values. Note
|
||||
/// that the `Freeze` trait is not exposed to end users and is
|
||||
/// effectively an implementation detail.
|
||||
pub fn is_freeze(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn is_freeze(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self))
|
||||
}
|
||||
|
||||
|
@ -696,7 +698,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
///
|
||||
/// Returning true means the type is known to be `Freeze`. Returning
|
||||
/// `false` means nothing -- could be `Freeze`, might not be.
|
||||
fn is_trivially_freeze(&self) -> bool {
|
||||
fn is_trivially_freeze(self) -> bool {
|
||||
match self.kind() {
|
||||
ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
|
@ -710,7 +712,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
| ty::FnDef(..)
|
||||
| ty::Error(_)
|
||||
| ty::FnPtr(_) => true,
|
||||
ty::Tuple(_) => self.tuple_fields().all(Self::is_trivially_freeze),
|
||||
ty::Tuple(_) => self.tuple_fields().all(|f| Self::is_trivially_freeze(f)),
|
||||
ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_freeze(),
|
||||
ty::Adt(..)
|
||||
| ty::Bound(..)
|
||||
|
@ -728,7 +730,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
}
|
||||
|
||||
/// Checks whether values of this type `T` implement the `Unpin` trait.
|
||||
pub fn is_unpin(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn is_unpin(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
self.is_trivially_unpin() || tcx_at.is_unpin_raw(param_env.and(self))
|
||||
}
|
||||
|
||||
|
@ -736,7 +738,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
///
|
||||
/// Returning true means the type is known to be `Unpin`. Returning
|
||||
/// `false` means nothing -- could be `Unpin`, might not be.
|
||||
fn is_trivially_unpin(&self) -> bool {
|
||||
fn is_trivially_unpin(self) -> bool {
|
||||
match self.kind() {
|
||||
ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
|
@ -750,7 +752,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
| ty::FnDef(..)
|
||||
| ty::Error(_)
|
||||
| ty::FnPtr(_) => true,
|
||||
ty::Tuple(_) => self.tuple_fields().all(Self::is_trivially_unpin),
|
||||
ty::Tuple(_) => self.tuple_fields().all(|f| Self::is_trivially_unpin(f)),
|
||||
ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_unpin(),
|
||||
ty::Adt(..)
|
||||
| ty::Bound(..)
|
||||
|
@ -776,7 +778,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
///
|
||||
/// Note that this method is used to check eligible types in unions.
|
||||
#[inline]
|
||||
pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn needs_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
// Avoid querying in simple cases.
|
||||
match needs_drop_components(self, &tcx.data_layout) {
|
||||
Err(AlwaysRequiresDrop) => true,
|
||||
|
@ -809,11 +811,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
/// Note that this method is used to check for change in drop order for
|
||||
/// 2229 drop reorder migration analysis.
|
||||
#[inline]
|
||||
pub fn has_significant_drop(
|
||||
&'tcx self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> bool {
|
||||
pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
// Avoid querying in simple cases.
|
||||
match needs_drop_components(self, &tcx.data_layout) {
|
||||
Err(AlwaysRequiresDrop) => true,
|
||||
|
@ -858,7 +856,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
/// want to know whether a given call to `PartialEq::eq` will proceed structurally all the way
|
||||
/// down, you will need to use a type visitor.
|
||||
#[inline]
|
||||
pub fn is_structural_eq_shallow(&'tcx self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
pub fn is_structural_eq_shallow(self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
match self.kind() {
|
||||
// Look for an impl of both `PartialStructuralEq` and `StructuralEq`.
|
||||
Adt(..) => tcx.has_structural_eq_impls(self),
|
||||
|
@ -903,16 +901,16 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
/// - `&'a mut u8` -> `u8`
|
||||
/// - `&'a &'b u8` -> `u8`
|
||||
/// - `&'a *const &'b u8 -> *const &'b u8`
|
||||
pub fn peel_refs(&'tcx self) -> Ty<'tcx> {
|
||||
pub fn peel_refs(self) -> Ty<'tcx> {
|
||||
let mut ty = self;
|
||||
while let Ref(_, inner_ty, _) = ty.kind() {
|
||||
ty = inner_ty;
|
||||
ty = *inner_ty;
|
||||
}
|
||||
ty
|
||||
}
|
||||
|
||||
pub fn outer_exclusive_binder(&'tcx self) -> DebruijnIndex {
|
||||
self.outer_exclusive_binder
|
||||
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,9 +991,9 @@ pub fn needs_drop_components<'tcx>(
|
|||
|
||||
ty::Dynamic(..) | ty::Error(_) => Err(AlwaysRequiresDrop),
|
||||
|
||||
ty::Slice(ty) => needs_drop_components(ty, target_layout),
|
||||
ty::Slice(ty) => needs_drop_components(*ty, target_layout),
|
||||
ty::Array(elem_ty, size) => {
|
||||
match needs_drop_components(elem_ty, target_layout) {
|
||||
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) {
|
||||
// Arrays of size zero don't need drop, even if their element
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! An iterator over the type substructure.
|
||||
//! WARNING: this does not keep track of the region depth.
|
||||
|
||||
use crate::ty;
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind};
|
||||
use crate::ty::{self, Ty};
|
||||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use smallvec::{self, SmallVec};
|
||||
|
||||
|
@ -96,7 +96,7 @@ impl<'tcx> GenericArg<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> super::TyS<'tcx> {
|
||||
impl<'tcx> Ty<'tcx> {
|
||||
/// Iterator that walks `self` and any types reachable from
|
||||
/// `self`, in depth-first order. Note that just walks the types
|
||||
/// that appear in `self`, it does not descend into the fields of
|
||||
|
@ -107,7 +107,7 @@ impl<'tcx> super::TyS<'tcx> {
|
|||
/// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
|
||||
/// [isize] => { [isize], isize }
|
||||
/// ```
|
||||
pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
|
||||
pub fn walk(self) -> TypeWalker<'tcx> {
|
||||
TypeWalker::new(self.into())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue