@@ -1942,6 +1942,79 @@ fn clean_bare_fn_ty<'tcx>(
1942
1942
BareFunctionDecl { unsafety : bare_fn. unsafety , abi : bare_fn. abi , decl, generic_params }
1943
1943
}
1944
1944
1945
+ /// This visitor is used to go through only the "top level" of a item and not enter any sub
1946
+ /// item while looking for a given `Ident` which is stored into `item` if found.
1947
+ struct OneLevelVisitor < ' hir > {
1948
+ map : rustc_middle:: hir:: map:: Map < ' hir > ,
1949
+ item : Option < & ' hir hir:: Item < ' hir > > ,
1950
+ looking_for : Ident ,
1951
+ target_hir_id : hir:: HirId ,
1952
+ }
1953
+
1954
+ impl < ' hir > OneLevelVisitor < ' hir > {
1955
+ fn new ( map : rustc_middle:: hir:: map:: Map < ' hir > , target_hir_id : hir:: HirId ) -> Self {
1956
+ Self { map, item : None , looking_for : Ident :: empty ( ) , target_hir_id }
1957
+ }
1958
+
1959
+ fn reset ( & mut self , looking_for : Ident ) {
1960
+ self . looking_for = looking_for;
1961
+ self . item = None ;
1962
+ }
1963
+ }
1964
+
1965
+ impl < ' hir > hir:: intravisit:: Visitor < ' hir > for OneLevelVisitor < ' hir > {
1966
+ type NestedFilter = rustc_middle:: hir:: nested_filter:: All ;
1967
+
1968
+ fn nested_visit_map ( & mut self ) -> Self :: Map {
1969
+ self . map
1970
+ }
1971
+
1972
+ fn visit_item ( & mut self , item : & ' hir hir:: Item < ' hir > ) {
1973
+ if self . item . is_none ( )
1974
+ && item. ident == self . looking_for
1975
+ && matches ! ( item. kind, hir:: ItemKind :: Use ( _, _) )
1976
+ || item. hir_id ( ) == self . target_hir_id
1977
+ {
1978
+ self . item = Some ( item) ;
1979
+ }
1980
+ }
1981
+ }
1982
+
1983
+ /// Because a `Use` item directly links to the imported item, we need to manually go through each
1984
+ /// import one by one. To do so, we go to the parent item and look for the `Ident` into it. Then,
1985
+ /// if we found the "end item" (the imported one), we stop there because we don't need its
1986
+ /// documentation. Otherwise, we repeat the same operation until we find the "end item".
1987
+ fn get_all_import_attributes < ' hir > (
1988
+ mut item : & hir:: Item < ' hir > ,
1989
+ tcx : TyCtxt < ' hir > ,
1990
+ target_hir_id : hir:: HirId ,
1991
+ attributes : & mut Vec < ast:: Attribute > ,
1992
+ ) {
1993
+ let hir_map = tcx. hir ( ) ;
1994
+ let mut visitor = OneLevelVisitor :: new ( hir_map, target_hir_id) ;
1995
+ // If the item is an import and has at least a path with two parts, we go into it.
1996
+ while let hir:: ItemKind :: Use ( path, _) = item. kind &&
1997
+ path. segments . len ( ) > 1 &&
1998
+ let hir:: def:: Res :: Def ( _, def_id) = path. segments [ path. segments . len ( ) - 2 ] . res
1999
+ {
2000
+ if let Some ( hir:: Node :: Item ( parent_item) ) = hir_map. get_if_local ( def_id) {
2001
+ // We add the attributes from this import into the list.
2002
+ attributes. extend_from_slice ( hir_map. attrs ( item. hir_id ( ) ) ) ;
2003
+ // We get the `Ident` we will be looking for into `item`.
2004
+ let looking_for = path. segments [ path. segments . len ( ) - 1 ] . ident ;
2005
+ visitor. reset ( looking_for) ;
2006
+ hir:: intravisit:: walk_item ( & mut visitor, parent_item) ;
2007
+ if let Some ( i) = visitor. item {
2008
+ item = i;
2009
+ } else {
2010
+ break ;
2011
+ }
2012
+ } else {
2013
+ break ;
2014
+ }
2015
+ }
2016
+ }
2017
+
1945
2018
fn clean_maybe_renamed_item < ' tcx > (
1946
2019
cx : & mut DocContext < ' tcx > ,
1947
2020
item : & hir:: Item < ' tcx > ,
@@ -2023,13 +2096,20 @@ fn clean_maybe_renamed_item<'tcx>(
2023
2096
}
2024
2097
_ => unreachable ! ( "not yet converted" ) ,
2025
2098
} ;
2026
- if let Some ( import_id) = import_id {
2027
- let ( attrs, cfg) = inline:: merge_attrs (
2028
- cx,
2029
- Some ( cx. tcx . parent_module ( import_id) . to_def_id ( ) ) ,
2030
- inline:: load_attrs ( cx, def_id) ,
2031
- Some ( inline:: load_attrs ( cx, cx. tcx . hir ( ) . local_def_id ( import_id) . to_def_id ( ) ) ) ,
2032
- ) ;
2099
+
2100
+ let mut extra_attrs = Vec :: new ( ) ;
2101
+ if let Some ( hir:: Node :: Item ( use_node) ) =
2102
+ import_id. and_then ( |hir_id| cx. tcx . hir ( ) . find ( hir_id) )
2103
+ {
2104
+ // We get all the various imports' attributes.
2105
+ get_all_import_attributes ( use_node, cx. tcx , item. hir_id ( ) , & mut extra_attrs) ;
2106
+ }
2107
+
2108
+ if !extra_attrs. is_empty ( ) {
2109
+ extra_attrs. extend_from_slice ( inline:: load_attrs ( cx, def_id) ) ;
2110
+ let attrs = Attributes :: from_ast ( & extra_attrs) ;
2111
+ let cfg = extra_attrs. cfg ( cx. tcx , & cx. cache . hidden_cfg ) ;
2112
+
2033
2113
vec ! [ Item :: from_def_id_and_attrs_and_parts(
2034
2114
def_id,
2035
2115
Some ( name) ,
0 commit comments