@@ -36,6 +36,7 @@ use ty::maps;
3636use util:: common:: MemoizationMap ;
3737use util:: nodemap:: { NodeMap , NodeSet , DefIdMap , DefIdSet } ;
3838use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
39+ use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
3940
4041use arena:: TypedArena ;
4142use std:: borrow:: Borrow ;
@@ -44,6 +45,7 @@ use std::hash::{Hash, Hasher};
4445use std:: mem;
4546use std:: ops:: Deref ;
4647use std:: rc:: Rc ;
48+ use std:: iter;
4749use syntax:: ast:: { self , Name , NodeId } ;
4850use syntax:: attr;
4951use syntax:: parse:: token:: { self , keywords} ;
@@ -824,6 +826,9 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
824826impl < ' a , ' tcx > Lift < ' tcx > for & ' a Substs < ' a > {
825827 type Lifted = & ' tcx Substs < ' tcx > ;
826828 fn lift_to_tcx < ' b , ' gcx > ( & self , tcx : TyCtxt < ' b , ' gcx , ' tcx > ) -> Option < & ' tcx Substs < ' tcx > > {
829+ if self . len ( ) == 0 {
830+ return Some ( Slice :: empty ( ) ) ;
831+ }
827832 if let Some ( & Interned ( substs) ) = tcx. interners . substs . borrow ( ) . get ( & self [ ..] ) {
828833 if * self as * const _ == substs as * const _ {
829834 return Some ( substs) ;
@@ -859,6 +864,9 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Ty<'a>> {
859864 type Lifted = & ' tcx Slice < Ty < ' tcx > > ;
860865 fn lift_to_tcx < ' b , ' gcx > ( & self , tcx : TyCtxt < ' b , ' gcx , ' tcx > )
861866 -> Option < & ' tcx Slice < Ty < ' tcx > > > {
867+ if self . len ( ) == 0 {
868+ return Some ( Slice :: empty ( ) ) ;
869+ }
862870 if let Some ( & Interned ( list) ) = tcx. interners . type_list . borrow ( ) . get ( & self [ ..] ) {
863871 if * self as * const _ == list as * const _ {
864872 return Some ( list) ;
@@ -1212,8 +1220,8 @@ macro_rules! slice_interners {
12121220}
12131221
12141222slice_interners ! (
1215- type_list: mk_type_list ( Ty ) ,
1216- substs: mk_substs ( Kind )
1223+ type_list: _intern_type_list ( Ty ) ,
1224+ substs: _intern_substs ( Kind )
12171225) ;
12181226
12191227impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
@@ -1318,12 +1326,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13181326 self . mk_ty ( TySlice ( ty) )
13191327 }
13201328
1321- pub fn mk_tup ( self , ts : & [ Ty < ' tcx > ] ) -> Ty < ' tcx > {
1322- self . mk_ty ( TyTuple ( self . mk_type_list ( ts) ) )
1329+ pub fn intern_tup ( self , ts : & [ Ty < ' tcx > ] ) -> Ty < ' tcx > {
1330+ self . mk_ty ( TyTuple ( self . intern_type_list ( ts) ) )
1331+ }
1332+
1333+ pub fn mk_tup < I : InternAs < [ Ty < ' tcx > ] , Ty < ' tcx > > > ( self , iter : I ) -> I :: Output {
1334+ iter. intern_with ( |ts| self . mk_ty ( TyTuple ( self . intern_type_list ( ts) ) ) )
13231335 }
13241336
13251337 pub fn mk_nil ( self ) -> Ty < ' tcx > {
1326- self . mk_tup ( & [ ] )
1338+ self . intern_tup ( & [ ] )
13271339 }
13281340
13291341 pub fn mk_diverging_default ( self ) -> Ty < ' tcx > {
@@ -1369,7 +1381,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13691381 -> Ty < ' tcx > {
13701382 self . mk_closure_from_closure_substs ( closure_id, ClosureSubsts {
13711383 func_substs : substs,
1372- upvar_tys : self . mk_type_list ( tys)
1384+ upvar_tys : self . intern_type_list ( tys)
13731385 } )
13741386 }
13751387
@@ -1414,6 +1426,40 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14141426 self . mk_ty ( TyAnon ( def_id, substs) )
14151427 }
14161428
1429+ pub fn intern_type_list ( self , ts : & [ Ty < ' tcx > ] ) -> & ' tcx Slice < Ty < ' tcx > > {
1430+ if ts. len ( ) == 0 {
1431+ Slice :: empty ( )
1432+ } else {
1433+ self . _intern_type_list ( ts)
1434+ }
1435+ }
1436+
1437+ pub fn intern_substs ( self , ts : & [ Kind < ' tcx > ] ) -> & ' tcx Slice < Kind < ' tcx > > {
1438+ if ts. len ( ) == 0 {
1439+ Slice :: empty ( )
1440+ } else {
1441+ self . _intern_substs ( ts)
1442+ }
1443+ }
1444+
1445+ pub fn mk_type_list < I : InternAs < [ Ty < ' tcx > ] ,
1446+ & ' tcx Slice < Ty < ' tcx > > > > ( self , iter : I ) -> I :: Output {
1447+ iter. intern_with ( |xs| self . intern_type_list ( xs) )
1448+ }
1449+
1450+ pub fn mk_substs < I : InternAs < [ Kind < ' tcx > ] ,
1451+ & ' tcx Slice < Kind < ' tcx > > > > ( self , iter : I ) -> I :: Output {
1452+ iter. intern_with ( |xs| self . intern_substs ( xs) )
1453+ }
1454+
1455+ pub fn mk_substs_trait ( self ,
1456+ s : Ty < ' tcx > ,
1457+ t : & [ Ty < ' tcx > ] )
1458+ -> & ' tcx Substs < ' tcx >
1459+ {
1460+ self . mk_substs ( iter:: once ( s) . chain ( t. into_iter ( ) . cloned ( ) ) . map ( Kind :: from) )
1461+ }
1462+
14171463 pub fn trait_items ( self , trait_did : DefId ) -> Rc < Vec < ty:: ImplOrTraitItem < ' gcx > > > {
14181464 self . trait_items_cache . memoize ( trait_did, || {
14191465 let def_ids = self . impl_or_trait_items ( trait_did) ;
@@ -1432,3 +1478,39 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14321478 } )
14331479 }
14341480}
1481+
1482+ pub trait InternAs < T : ?Sized , R > {
1483+ type Output ;
1484+ fn intern_with < F > ( self , F ) -> Self :: Output
1485+ where F : FnOnce ( & T ) -> R ;
1486+ }
1487+
1488+ impl < I , T , R , E > InternAs < [ T ] , R > for I
1489+ where E : InternIteratorElement < T , R > ,
1490+ I : Iterator < Item =E > {
1491+ type Output = E :: Output ;
1492+ fn intern_with < F > ( self , f : F ) -> Self :: Output
1493+ where F : FnOnce ( & [ T ] ) -> R {
1494+ E :: intern_with ( self , f)
1495+ }
1496+ }
1497+
1498+ pub trait InternIteratorElement < T , R > : Sized {
1499+ type Output ;
1500+ fn intern_with < I : Iterator < Item =Self > , F : FnOnce ( & [ T ] ) -> R > ( iter : I , f : F ) -> Self :: Output ;
1501+ }
1502+
1503+ impl < T , R > InternIteratorElement < T , R > for T {
1504+ type Output = R ;
1505+ fn intern_with < I : Iterator < Item =Self > , F : FnOnce ( & [ T ] ) -> R > ( iter : I , f : F ) -> Self :: Output {
1506+ f ( & iter. collect :: < AccumulateVec < [ _ ; 8 ] > > ( ) )
1507+ }
1508+ }
1509+
1510+ impl < T , R , E > InternIteratorElement < T , R > for Result < T , E > {
1511+ type Output = Result < R , E > ;
1512+ fn intern_with < I : Iterator < Item =Self > , F : FnOnce ( & [ T ] ) -> R > ( iter : I , f : F ) -> Self :: Output {
1513+ Ok ( f ( & iter. collect :: < Result < AccumulateVec < [ _ ; 8 ] > , _ > > ( ) ?) )
1514+ }
1515+ }
1516+
0 commit comments