@@ -36,8 +36,10 @@ use syntax_pos::{self, DUMMY_SP, Pos};
3636use rustc_trans:: back:: link;
3737use rustc:: middle:: cstore;
3838use rustc:: middle:: privacy:: AccessLevels ;
39+ use rustc:: middle:: resolve_lifetime:: DefRegion :: * ;
3940use rustc:: hir:: def:: Def ;
4041use rustc:: hir:: def_id:: { DefId , DefIndex , CRATE_DEF_INDEX } ;
42+ use rustc:: hir:: fold:: Folder ;
4143use rustc:: hir:: print as pprust;
4244use rustc:: ty:: subst:: { self , ParamSpace , VecPerParamSpace } ;
4345use rustc:: ty;
@@ -1636,6 +1638,43 @@ impl PrimitiveType {
16361638 }
16371639}
16381640
1641+
1642+ // Poor man's type parameter substitution at HIR level.
1643+ // Used to replace private type aliases in public signatures with their aliased types.
1644+ struct SubstAlias < ' a , ' tcx : ' a > {
1645+ tcx : & ' a ty:: TyCtxt < ' a , ' tcx , ' tcx > ,
1646+ // Table type parameter definition -> substituted type
1647+ ty_substs : HashMap < Def , hir:: Ty > ,
1648+ // Table node id of lifetime parameter definition -> substituted lifetime
1649+ lt_substs : HashMap < ast:: NodeId , hir:: Lifetime > ,
1650+ }
1651+
1652+ impl < ' a , ' tcx : ' a , ' b : ' tcx > Folder for SubstAlias < ' a , ' tcx > {
1653+ fn fold_ty ( & mut self , ty : P < hir:: Ty > ) -> P < hir:: Ty > {
1654+ if let hir:: TyPath ( ..) = ty. node {
1655+ let def = self . tcx . expect_def ( ty. id ) ;
1656+ if let Some ( new_ty) = self . ty_substs . get ( & def) . cloned ( ) {
1657+ return P ( new_ty) ;
1658+ }
1659+ }
1660+ hir:: fold:: noop_fold_ty ( ty, self )
1661+ }
1662+ fn fold_lifetime ( & mut self , lt : hir:: Lifetime ) -> hir:: Lifetime {
1663+ let def = self . tcx . named_region_map . defs . get ( & lt. id ) . cloned ( ) ;
1664+ match def {
1665+ Some ( DefEarlyBoundRegion ( _, _, node_id) ) |
1666+ Some ( DefLateBoundRegion ( _, node_id) ) |
1667+ Some ( DefFreeRegion ( _, node_id) ) => {
1668+ if let Some ( lt) = self . lt_substs . get ( & node_id) . cloned ( ) {
1669+ return lt;
1670+ }
1671+ }
1672+ _ => { }
1673+ }
1674+ hir:: fold:: noop_fold_lifetime ( lt, self )
1675+ }
1676+ }
1677+
16391678impl Clean < Type > for hir:: Ty {
16401679 fn clean ( & self , cx : & DocContext ) -> Type {
16411680 use rustc:: hir:: * ;
@@ -1665,8 +1704,46 @@ impl Clean<Type> for hir::Ty {
16651704 FixedVector ( box ty. clean ( cx) , n)
16661705 } ,
16671706 TyTup ( ref tys) => Tuple ( tys. clean ( cx) ) ,
1668- TyPath ( None , ref p) => {
1669- resolve_type ( cx, p. clean ( cx) , self . id )
1707+ TyPath ( None , ref path) => {
1708+ if let Some ( tcx) = cx. tcx_opt ( ) {
1709+ // Substitute private type aliases
1710+ let def = tcx. expect_def ( self . id ) ;
1711+ if let Def :: TyAlias ( def_id) = def {
1712+ if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
1713+ if !cx. access_levels . borrow ( ) . is_exported ( def_id) {
1714+ let item = tcx. map . expect_item ( node_id) ;
1715+ if let hir:: ItemTy ( ref ty, ref generics) = item. node {
1716+ let provided_params = & path. segments . last ( ) . unwrap ( ) . parameters ;
1717+ let mut ty_substs = HashMap :: new ( ) ;
1718+ let mut lt_substs = HashMap :: new ( ) ;
1719+ for ( i, ty_param) in generics. ty_params . iter ( ) . enumerate ( ) {
1720+ let ty_param_def = tcx. expect_def ( ty_param. id ) ;
1721+ if let Some ( ty) = provided_params. types ( ) . get ( i) . cloned ( )
1722+ . cloned ( ) {
1723+ ty_substs. insert ( ty_param_def, ty. unwrap ( ) ) ;
1724+ } else if let Some ( default) = ty_param. default . clone ( ) {
1725+ ty_substs. insert ( ty_param_def, default. unwrap ( ) ) ;
1726+ }
1727+ }
1728+ for ( i, lt_param) in generics. lifetimes . iter ( ) . enumerate ( ) {
1729+ if let Some ( lt) = provided_params. lifetimes ( ) . get ( i)
1730+ . cloned ( )
1731+ . cloned ( ) {
1732+ lt_substs. insert ( lt_param. lifetime . id , lt) ;
1733+ }
1734+ }
1735+ let mut subst_alias = SubstAlias {
1736+ tcx : & tcx,
1737+ ty_substs : ty_substs,
1738+ lt_substs : lt_substs
1739+ } ;
1740+ return subst_alias. fold_ty ( ty. clone ( ) ) . clean ( cx) ;
1741+ }
1742+ }
1743+ }
1744+ }
1745+ }
1746+ resolve_type ( cx, path. clean ( cx) , self . id )
16701747 }
16711748 TyPath ( Some ( ref qself) , ref p) => {
16721749 let mut segments: Vec < _ > = p. segments . clone ( ) . into ( ) ;
0 commit comments