@@ -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
118124impl < ' 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.
19771970struct Interned < ' tcx , T : ?Sized > ( & ' tcx T ) ;
19781971
19791972impl < ' tcx , T : ' tcx + ?Sized > Clone for Interned < ' tcx , T > {
19801973 fn clone ( & self ) -> Self {
19811974 Interned ( self . 0 )
19821975 }
19831976}
1977+
19841978impl < ' tcx , T : ' tcx + ?Sized > Copy for Interned < ' tcx , T > { }
19851979
19861980impl < ' 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+
19921993impl < ' 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
20002003impl < ' 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+
20132016impl < ' 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
20212026impl < ' 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.
20342039impl < ' 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
20422049impl < ' 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-
20542056macro_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
20942102macro_rules! slice_interners {
0 commit comments