@@ -101,7 +101,6 @@ pub struct CtxtInterners<'tcx> {
101101 // Specifically use a speedy hash algorithm for these hash sets, since
102102 // they're accessed quite often.
103103 type_ : InternedSet < ' tcx , TyS < ' tcx > > ,
104- type_list : InternedSet < ' tcx , List < Ty < ' tcx > > > ,
105104 substs : InternedSet < ' tcx , InternalSubsts < ' tcx > > ,
106105 canonical_var_infos : InternedSet < ' tcx , List < CanonicalVarInfo < ' tcx > > > ,
107106 region : InternedSet < ' tcx , RegionKind > ,
@@ -129,7 +128,6 @@ impl<'tcx> CtxtInterners<'tcx> {
129128 CtxtInterners {
130129 arena,
131130 type_ : Default :: default ( ) ,
132- type_list : Default :: default ( ) ,
133131 substs : Default :: default ( ) ,
134132 region : Default :: default ( ) ,
135133 poly_existential_predicates : Default :: default ( ) ,
@@ -1666,6 +1664,23 @@ macro_rules! nop_lift {
16661664 } ;
16671665}
16681666
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+
16691684macro_rules! nop_list_lift {
16701685 ( $set: ident; $ty: ty => $lifted: ty) => {
16711686 impl <' a, ' tcx> Lift <' tcx> for & ' a List <$ty> {
@@ -1690,7 +1705,6 @@ nop_lift! {const_; Const<'a> => Const<'tcx>}
16901705nop_lift_old ! { const_allocation; & ' a Allocation => & ' tcx Allocation }
16911706nop_lift ! { predicate; Predicate <' a> => Predicate <' tcx>}
16921707
1693- nop_list_lift ! { type_list; Ty <' a> => Ty <' tcx>}
16941708nop_list_lift ! { poly_existential_predicates; ty:: Binder <' a, ExistentialPredicate <' a>> => ty:: Binder <' tcx, ExistentialPredicate <' tcx>>}
16951709nop_list_lift ! { predicates; Predicate <' a> => Predicate <' tcx>}
16961710nop_list_lift ! { canonical_var_infos; CanonicalVarInfo <' a> => CanonicalVarInfo <' tcx>}
@@ -2189,7 +2203,6 @@ macro_rules! slice_interners {
21892203}
21902204
21912205slice_interners ! (
2192- type_list: _intern_type_list( Ty <' tcx>) ,
21932206 substs: _intern_substs( GenericArg <' tcx>) ,
21942207 canonical_var_infos: _intern_canonical_var_infos( CanonicalVarInfo <' tcx>) ,
21952208 poly_existential_predicates:
@@ -2611,7 +2624,19 @@ impl<'tcx> TyCtxt<'tcx> {
26112624 }
26122625
26132626 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+ }
26152640 }
26162641
26172642 pub fn intern_substs ( self , ts : & [ GenericArg < ' tcx > ] ) -> & ' tcx List < GenericArg < ' tcx > > {
0 commit comments