Skip to content

Commit 3fa1e2a

Browse files
authored
Rollup merge of rust-lang#93147 - nnethercote:interner-cleanups, r=lcnr
Interner cleanups Improve some code that I have found confusing. r? `@lcnr`
2 parents 514723f + d46ed5d commit 3fa1e2a

File tree

2 files changed

+69
-44
lines changed

2 files changed

+69
-44
lines changed

compiler/rustc_middle/src/ty/context.rs

+52-44
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ pub struct CtxtInterners<'tcx> {
113113
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
114114
layout: InternedSet<'tcx, Layout>,
115115
adt_def: InternedSet<'tcx, AdtDef>,
116+
117+
/// `#[stable]` and `#[unstable]` attributes
118+
stability: InternedSet<'tcx, attr::Stability>,
119+
120+
/// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
121+
const_stability: InternedSet<'tcx, attr::ConstStability>,
116122
}
117123

118124
impl<'tcx> CtxtInterners<'tcx> {
@@ -134,6 +140,8 @@ impl<'tcx> CtxtInterners<'tcx> {
134140
bound_variable_kinds: Default::default(),
135141
layout: Default::default(),
136142
adt_def: Default::default(),
143+
stability: Default::default(),
144+
const_stability: Default::default(),
137145
}
138146
}
139147

@@ -1035,12 +1043,6 @@ pub struct GlobalCtxt<'tcx> {
10351043
/// Data layout specification for the current target.
10361044
pub data_layout: TargetDataLayout,
10371045

1038-
/// `#[stable]` and `#[unstable]` attributes
1039-
stability_interner: ShardedHashMap<&'tcx attr::Stability, ()>,
1040-
1041-
/// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
1042-
const_stability_interner: ShardedHashMap<&'tcx attr::ConstStability, ()>,
1043-
10441046
/// Stores memory for globals (statics/consts).
10451047
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
10461048

@@ -1092,16 +1094,6 @@ impl<'tcx> TyCtxt<'tcx> {
10921094
self.create_memory_alloc(alloc)
10931095
}
10941096

1095-
// FIXME(eddyb) move to `direct_interners!`.
1096-
pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
1097-
self.stability_interner.intern(stab, |stab| self.arena.alloc(stab))
1098-
}
1099-
1100-
// FIXME(eddyb) move to `direct_interners!`.
1101-
pub fn intern_const_stability(self, stab: attr::ConstStability) -> &'tcx attr::ConstStability {
1102-
self.const_stability_interner.intern(stab, |stab| self.arena.alloc(stab))
1103-
}
1104-
11051097
/// Returns a range of the start/end indices specified with the
11061098
/// `rustc_layout_scalar_valid_range` attribute.
11071099
// FIXME(eddyb) this is an awkward spot for this method, maybe move it?
@@ -1185,8 +1177,6 @@ impl<'tcx> TyCtxt<'tcx> {
11851177
evaluation_cache: Default::default(),
11861178
crate_name: Symbol::intern(crate_name),
11871179
data_layout,
1188-
stability_interner: Default::default(),
1189-
const_stability_interner: Default::default(),
11901180
alloc_map: Lock::new(interpret::AllocMap::new()),
11911181
output_filenames: Arc::new(output_filenames),
11921182
}
@@ -1952,11 +1942,11 @@ impl<'tcx> TyCtxt<'tcx> {
19521942

19531943
writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
19541944
writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
1955-
writeln!(fmt, "Stability interner: #{}", self.0.stability_interner.len())?;
1945+
writeln!(fmt, "Stability interner: #{}", self.0.interners.stability.len())?;
19561946
writeln!(
19571947
fmt,
19581948
"Const Stability interner: #{}",
1959-
self.0.const_stability_interner.len()
1949+
self.0.interners.const_stability.len()
19601950
)?;
19611951
writeln!(
19621952
fmt,
@@ -1973,24 +1963,37 @@ impl<'tcx> TyCtxt<'tcx> {
19731963
}
19741964
}
19751965

1976-
/// An entry in an interner.
1966+
// This type holds a `T` in the interner. The `T` is stored in the arena and
1967+
// this type just holds a pointer to it, but it still effectively owns it. It
1968+
// impls `Borrow` so that it can be looked up using the original
1969+
// (non-arena-memory-owning) types.
19771970
struct Interned<'tcx, T: ?Sized>(&'tcx T);
19781971

19791972
impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> {
19801973
fn clone(&self) -> Self {
19811974
Interned(self.0)
19821975
}
19831976
}
1977+
19841978
impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {}
19851979

19861980
impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> {
19871981
fn into_pointer(&self) -> *const () {
19881982
self.0 as *const _ as *const ()
19891983
}
19901984
}
1991-
// N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
1985+
1986+
#[allow(rustc::usage_of_ty_tykind)]
1987+
impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
1988+
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
1989+
&self.0.kind()
1990+
}
1991+
}
1992+
19921993
impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
19931994
fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
1995+
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1996+
// `x == y`.
19941997
self.0.kind() == other.0.kind()
19951998
}
19961999
}
@@ -1999,19 +2002,21 @@ impl<'tcx> Eq for Interned<'tcx, TyS<'tcx>> {}
19992002

20002003
impl<'tcx> Hash for Interned<'tcx, TyS<'tcx>> {
20012004
fn hash<H: Hasher>(&self, s: &mut H) {
2005+
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
20022006
self.0.kind().hash(s)
20032007
}
20042008
}
20052009

2006-
#[allow(rustc::usage_of_ty_tykind)]
2007-
impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
2008-
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
2009-
&self.0.kind()
2010+
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
2011+
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
2012+
&self.0.kind
20102013
}
20112014
}
2012-
// N.B., an `Interned<PredicateInner>` compares and hashes as a `PredicateKind`.
2015+
20132016
impl<'tcx> PartialEq for Interned<'tcx, PredicateInner<'tcx>> {
20142017
fn eq(&self, other: &Interned<'tcx, PredicateInner<'tcx>>) -> bool {
2018+
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2019+
// `x == y`.
20152020
self.0.kind == other.0.kind
20162021
}
20172022
}
@@ -2020,19 +2025,21 @@ impl<'tcx> Eq for Interned<'tcx, PredicateInner<'tcx>> {}
20202025

20212026
impl<'tcx> Hash for Interned<'tcx, PredicateInner<'tcx>> {
20222027
fn hash<H: Hasher>(&self, s: &mut H) {
2028+
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
20232029
self.0.kind.hash(s)
20242030
}
20252031
}
20262032

2027-
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
2028-
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
2029-
&self.0.kind
2033+
impl<'tcx, T> Borrow<[T]> for Interned<'tcx, List<T>> {
2034+
fn borrow<'a>(&'a self) -> &'a [T] {
2035+
&self.0[..]
20302036
}
20312037
}
20322038

2033-
// N.B., an `Interned<List<T>>` compares and hashes as its elements.
20342039
impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> {
20352040
fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool {
2041+
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2042+
// `x == y`.
20362043
self.0[..] == other.0[..]
20372044
}
20382045
}
@@ -2041,20 +2048,23 @@ impl<'tcx, T: Eq> Eq for Interned<'tcx, List<T>> {}
20412048

20422049
impl<'tcx, T: Hash> Hash for Interned<'tcx, List<T>> {
20432050
fn hash<H: Hasher>(&self, s: &mut H) {
2051+
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
20442052
self.0[..].hash(s)
20452053
}
20462054
}
20472055

2048-
impl<'tcx, T> Borrow<[T]> for Interned<'tcx, List<T>> {
2049-
fn borrow<'a>(&'a self) -> &'a [T] {
2050-
&self.0[..]
2051-
}
2052-
}
2053-
20542056
macro_rules! direct_interners {
20552057
($($name:ident: $method:ident($ty:ty),)+) => {
2056-
$(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
2058+
$(impl<'tcx> Borrow<$ty> for Interned<'tcx, $ty> {
2059+
fn borrow<'a>(&'a self) -> &'a $ty {
2060+
&self.0
2061+
}
2062+
}
2063+
2064+
impl<'tcx> PartialEq for Interned<'tcx, $ty> {
20572065
fn eq(&self, other: &Self) -> bool {
2066+
// The `Borrow` trait requires that `x.borrow() == y.borrow()`
2067+
// equals `x == y`.
20582068
self.0 == other.0
20592069
}
20602070
}
@@ -2063,16 +2073,12 @@ macro_rules! direct_interners {
20632073

20642074
impl<'tcx> Hash for Interned<'tcx, $ty> {
20652075
fn hash<H: Hasher>(&self, s: &mut H) {
2076+
// The `Borrow` trait requires that `x.borrow().hash(s) ==
2077+
// x.hash(s)`.
20662078
self.0.hash(s)
20672079
}
20682080
}
20692081

2070-
impl<'tcx> Borrow<$ty> for Interned<'tcx, $ty> {
2071-
fn borrow<'a>(&'a self) -> &'a $ty {
2072-
&self.0
2073-
}
2074-
}
2075-
20762082
impl<'tcx> TyCtxt<'tcx> {
20772083
pub fn $method(self, v: $ty) -> &'tcx $ty {
20782084
self.interners.$name.intern(v, |v| {
@@ -2089,6 +2095,8 @@ direct_interners! {
20892095
const_allocation: intern_const_alloc(Allocation),
20902096
layout: intern_layout(Layout),
20912097
adt_def: intern_adt_def(AdtDef),
2098+
stability: intern_stability(attr::Stability),
2099+
const_stability: intern_const_stability(attr::ConstStability),
20922100
}
20932101

20942102
macro_rules! slice_interners {

compiler/rustc_middle/src/ty/mod.rs

+17
Original file line numberDiff line numberDiff line change
@@ -376,15 +376,28 @@ pub struct CReaderCacheKey {
376376
pub pos: usize,
377377
}
378378

379+
/// Represents a type.
380+
///
381+
/// IMPORTANT: Every `TyS` is *required* to have unique contents. The type's
382+
/// correctness relies on this, *but it does not enforce it*. Therefore, any
383+
/// code that creates a `TyS` must ensure uniqueness itself. In practice this
384+
/// is achieved by interning.
379385
#[allow(rustc::usage_of_ty_tykind)]
380386
pub struct TyS<'tcx> {
381387
/// This field shouldn't be used directly and may be removed in the future.
382388
/// Use `TyS::kind()` instead.
383389
kind: TyKind<'tcx>,
390+
391+
/// This field provides fast access to information that is also contained
392+
/// in `kind`.
393+
///
384394
/// This field shouldn't be used directly and may be removed in the future.
385395
/// Use `TyS::flags()` instead.
386396
flags: TypeFlags,
387397

398+
/// This field provides fast access to information that is also contained
399+
/// in `kind`.
400+
///
388401
/// This is a kind of confusing thing: it stores the smallest
389402
/// binder such that
390403
///
@@ -436,13 +449,17 @@ impl<'tcx> PartialOrd for TyS<'tcx> {
436449
impl<'tcx> PartialEq for TyS<'tcx> {
437450
#[inline]
438451
fn eq(&self, other: &TyS<'tcx>) -> bool {
452+
// Pointer equality implies equality (due to the unique contents
453+
// assumption).
439454
ptr::eq(self, other)
440455
}
441456
}
442457
impl<'tcx> Eq for TyS<'tcx> {}
443458

444459
impl<'tcx> Hash for TyS<'tcx> {
445460
fn hash<H: Hasher>(&self, s: &mut H) {
461+
// Pointer hashing is sufficient (due to the unique contents
462+
// assumption).
446463
(self as *const TyS<'_>).hash(s)
447464
}
448465
}

0 commit comments

Comments
 (0)