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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user