@@ -36,8 +36,10 @@ use syntax_pos::{self, DUMMY_SP, Pos};
36
36
use rustc_trans:: back:: link;
37
37
use rustc:: middle:: cstore;
38
38
use rustc:: middle:: privacy:: AccessLevels ;
39
+ use rustc:: middle:: resolve_lifetime:: DefRegion :: * ;
39
40
use rustc:: hir:: def:: Def ;
40
41
use rustc:: hir:: def_id:: { DefId , DefIndex , CRATE_DEF_INDEX } ;
42
+ use rustc:: hir:: fold:: Folder ;
41
43
use rustc:: hir:: print as pprust;
42
44
use rustc:: ty:: subst:: { self , ParamSpace , VecPerParamSpace } ;
43
45
use rustc:: ty;
@@ -1636,6 +1638,43 @@ impl PrimitiveType {
1636
1638
}
1637
1639
}
1638
1640
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
+
1639
1678
impl Clean < Type > for hir:: Ty {
1640
1679
fn clean ( & self , cx : & DocContext ) -> Type {
1641
1680
use rustc:: hir:: * ;
@@ -1665,8 +1704,46 @@ impl Clean<Type> for hir::Ty {
1665
1704
FixedVector ( box ty. clean ( cx) , n)
1666
1705
} ,
1667
1706
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 )
1670
1747
}
1671
1748
TyPath ( Some ( ref qself) , ref p) => {
1672
1749
let mut segments: Vec < _ > = p. segments . clone ( ) . into ( ) ;
0 commit comments