@@ -101,7 +101,6 @@ pub struct CtxtInterners<'tcx> {
101
101
// Specifically use a speedy hash algorithm for these hash sets, since
102
102
// they're accessed quite often.
103
103
type_ : InternedSet < ' tcx , TyS < ' tcx > > ,
104
- type_list : InternedSet < ' tcx , List < Ty < ' tcx > > > ,
105
104
substs : InternedSet < ' tcx , InternalSubsts < ' tcx > > ,
106
105
canonical_var_infos : InternedSet < ' tcx , List < CanonicalVarInfo < ' tcx > > > ,
107
106
region : InternedSet < ' tcx , RegionKind > ,
@@ -129,7 +128,6 @@ impl<'tcx> CtxtInterners<'tcx> {
129
128
CtxtInterners {
130
129
arena,
131
130
type_ : Default :: default ( ) ,
132
- type_list : Default :: default ( ) ,
133
131
substs : Default :: default ( ) ,
134
132
region : Default :: default ( ) ,
135
133
poly_existential_predicates : Default :: default ( ) ,
@@ -1666,6 +1664,23 @@ macro_rules! nop_lift {
1666
1664
} ;
1667
1665
}
1668
1666
1667
+ // Can't use the macros as we have reuse the `substs` here.
1668
+ //
1669
+ // See `intern_type_list` for more info.
1670
+ impl < ' a , ' tcx > Lift < ' tcx > for & ' a List < Ty < ' a > > {
1671
+ type Lifted = & ' tcx List < Ty < ' tcx > > ;
1672
+ fn lift_to_tcx ( self , tcx : TyCtxt < ' tcx > ) -> Option < Self :: Lifted > {
1673
+ if self . is_empty ( ) {
1674
+ return Some ( List :: empty ( ) ) ;
1675
+ }
1676
+ if tcx. interners . substs . contains_pointer_to ( & InternedInSet ( self . as_substs ( ) ) ) {
1677
+ Some ( unsafe { mem:: transmute ( self ) } )
1678
+ } else {
1679
+ None
1680
+ }
1681
+ }
1682
+ }
1683
+
1669
1684
macro_rules! nop_list_lift {
1670
1685
( $set: ident; $ty: ty => $lifted: ty) => {
1671
1686
impl <' a, ' tcx> Lift <' tcx> for & ' a List <$ty> {
@@ -1690,7 +1705,6 @@ nop_lift! {const_; Const<'a> => Const<'tcx>}
1690
1705
nop_lift_old ! { const_allocation; & ' a Allocation => & ' tcx Allocation }
1691
1706
nop_lift ! { predicate; Predicate <' a> => Predicate <' tcx>}
1692
1707
1693
- nop_list_lift ! { type_list; Ty <' a> => Ty <' tcx>}
1694
1708
nop_list_lift ! { poly_existential_predicates; ty:: Binder <' a, ExistentialPredicate <' a>> => ty:: Binder <' tcx, ExistentialPredicate <' tcx>>}
1695
1709
nop_list_lift ! { predicates; Predicate <' a> => Predicate <' tcx>}
1696
1710
nop_list_lift ! { canonical_var_infos; CanonicalVarInfo <' a> => CanonicalVarInfo <' tcx>}
@@ -2189,7 +2203,6 @@ macro_rules! slice_interners {
2189
2203
}
2190
2204
2191
2205
slice_interners ! (
2192
- type_list: _intern_type_list( Ty <' tcx>) ,
2193
2206
substs: _intern_substs( GenericArg <' tcx>) ,
2194
2207
canonical_var_infos: _intern_canonical_var_infos( CanonicalVarInfo <' tcx>) ,
2195
2208
poly_existential_predicates:
@@ -2611,7 +2624,19 @@ impl<'tcx> TyCtxt<'tcx> {
2611
2624
}
2612
2625
2613
2626
pub fn intern_type_list ( self , ts : & [ Ty < ' tcx > ] ) -> & ' tcx List < Ty < ' tcx > > {
2614
- if ts. is_empty ( ) { List :: empty ( ) } else { self . _intern_type_list ( ts) }
2627
+ if ts. is_empty ( ) {
2628
+ List :: empty ( )
2629
+ } else {
2630
+ // Actually intern type lists as lists of `GenericArg`s.
2631
+ //
2632
+ // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
2633
+ // as explained in ty_slice_as_generic_arg`. With this,
2634
+ // we guarantee that even when transmuting between `List<Ty<'tcx>>`
2635
+ // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
2636
+ // lists is upheld.
2637
+ let substs = self . _intern_substs ( ty:: subst:: ty_slice_as_generic_args ( ts) ) ;
2638
+ substs. try_as_type_list ( ) . unwrap ( )
2639
+ }
2615
2640
}
2616
2641
2617
2642
pub fn intern_substs ( self , ts : & [ GenericArg < ' tcx > ] ) -> & ' tcx List < GenericArg < ' tcx > > {
0 commit comments