@@ -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 ( ) ,
@@ -1657,6 +1655,8 @@ macro_rules! nop_lift {
1657
1655
type Lifted = $lifted;
1658
1656
fn lift_to_tcx( self , tcx: TyCtxt <' tcx>) -> Option <Self :: Lifted > {
1659
1657
if tcx. interners. $set. contains_pointer_to( & InternedInSet ( self . 0.0 ) ) {
1658
+ // SAFETY: `self` is interned and therefore valid
1659
+ // for the entire lifetime of the `TyCtxt`.
1660
1660
Some ( unsafe { mem:: transmute( self ) } )
1661
1661
} else {
1662
1662
None
@@ -1666,6 +1666,25 @@ macro_rules! nop_lift {
1666
1666
} ;
1667
1667
}
1668
1668
1669
+ // Can't use the macros as we have reuse the `substs` here.
1670
+ //
1671
+ // See `intern_type_list` for more info.
1672
+ impl < ' a , ' tcx > Lift < ' tcx > for & ' a List < Ty < ' a > > {
1673
+ type Lifted = & ' tcx List < Ty < ' tcx > > ;
1674
+ fn lift_to_tcx ( self , tcx : TyCtxt < ' tcx > ) -> Option < Self :: Lifted > {
1675
+ if self . is_empty ( ) {
1676
+ return Some ( List :: empty ( ) ) ;
1677
+ }
1678
+ if tcx. interners . substs . contains_pointer_to ( & InternedInSet ( self . as_substs ( ) ) ) {
1679
+ // SAFETY: `self` is interned and therefore valid
1680
+ // for the entire lifetime of the `TyCtxt`.
1681
+ Some ( unsafe { mem:: transmute :: < & ' a List < Ty < ' a > > , & ' tcx List < Ty < ' tcx > > > ( self ) } )
1682
+ } else {
1683
+ None
1684
+ }
1685
+ }
1686
+ }
1687
+
1669
1688
macro_rules! nop_list_lift {
1670
1689
( $set: ident; $ty: ty => $lifted: ty) => {
1671
1690
impl <' a, ' tcx> Lift <' tcx> for & ' a List <$ty> {
@@ -1690,7 +1709,6 @@ nop_lift! {const_; Const<'a> => Const<'tcx>}
1690
1709
nop_lift_old ! { const_allocation; & ' a Allocation => & ' tcx Allocation }
1691
1710
nop_lift ! { predicate; Predicate <' a> => Predicate <' tcx>}
1692
1711
1693
- nop_list_lift ! { type_list; Ty <' a> => Ty <' tcx>}
1694
1712
nop_list_lift ! { poly_existential_predicates; ty:: Binder <' a, ExistentialPredicate <' a>> => ty:: Binder <' tcx, ExistentialPredicate <' tcx>>}
1695
1713
nop_list_lift ! { predicates; Predicate <' a> => Predicate <' tcx>}
1696
1714
nop_list_lift ! { canonical_var_infos; CanonicalVarInfo <' a> => CanonicalVarInfo <' tcx>}
@@ -2189,7 +2207,6 @@ macro_rules! slice_interners {
2189
2207
}
2190
2208
2191
2209
slice_interners ! (
2192
- type_list: _intern_type_list( Ty <' tcx>) ,
2193
2210
substs: _intern_substs( GenericArg <' tcx>) ,
2194
2211
canonical_var_infos: _intern_canonical_var_infos( CanonicalVarInfo <' tcx>) ,
2195
2212
poly_existential_predicates:
@@ -2259,7 +2276,7 @@ impl<'tcx> TyCtxt<'tcx> {
2259
2276
) -> PolyFnSig < ' tcx > {
2260
2277
sig. map_bound ( |s| {
2261
2278
let params_iter = match s. inputs ( ) [ 0 ] . kind ( ) {
2262
- ty:: Tuple ( params) => params. into_iter ( ) . map ( |k| k . expect_ty ( ) ) ,
2279
+ ty:: Tuple ( params) => params. into_iter ( ) ,
2263
2280
_ => bug ! ( ) ,
2264
2281
} ;
2265
2282
self . mk_fn_sig ( params_iter, s. output ( ) , s. c_variadic , unsafety, abi:: Abi :: Rust )
@@ -2421,15 +2438,11 @@ impl<'tcx> TyCtxt<'tcx> {
2421
2438
2422
2439
#[ inline]
2423
2440
pub fn intern_tup ( self , ts : & [ Ty < ' tcx > ] ) -> Ty < ' tcx > {
2424
- let kinds: Vec < _ > = ts. iter ( ) . map ( |& t| GenericArg :: from ( t) ) . collect ( ) ;
2425
- self . mk_ty ( Tuple ( self . intern_substs ( & kinds) ) )
2441
+ self . mk_ty ( Tuple ( self . intern_type_list ( & ts) ) )
2426
2442
}
2427
2443
2428
2444
pub fn mk_tup < I : InternAs < [ Ty < ' tcx > ] , Ty < ' tcx > > > ( self , iter : I ) -> I :: Output {
2429
- iter. intern_with ( |ts| {
2430
- let kinds: Vec < _ > = ts. iter ( ) . map ( |& t| GenericArg :: from ( t) ) . collect ( ) ;
2431
- self . mk_ty ( Tuple ( self . intern_substs ( & kinds) ) )
2432
- } )
2445
+ iter. intern_with ( |ts| self . mk_ty ( Tuple ( self . intern_type_list ( & ts) ) ) )
2433
2446
}
2434
2447
2435
2448
#[ inline]
@@ -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