@@ -39,7 +39,6 @@ use std::hash::Hash;
3939use std:: mem;
4040use thin_vec:: ThinVec ;
4141
42- use crate :: clean:: inline:: merge_attrs;
4342use crate :: core:: { self , DocContext , ImplTraitParam } ;
4443use crate :: formats:: item_type:: ItemType ;
4544use crate :: visit_ast:: Module as DocModule ;
@@ -2168,32 +2167,40 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
21682167/// documentation. Otherwise, we repeat the same operation until we find the "end item".
21692168fn get_all_import_attributes < ' hir > (
21702169 mut item : & hir:: Item < ' hir > ,
2171- tcx : TyCtxt < ' hir > ,
2170+ cx : & mut DocContext < ' hir > ,
21722171 target_def_id : LocalDefId ,
2173- attributes : & mut Vec < ast:: Attribute > ,
21742172 is_inline : bool ,
2175- ) {
2173+ mut prev_import : LocalDefId ,
2174+ ) -> Vec < ( ast:: Attribute , Option < DefId > ) > {
2175+ let mut attributes: Vec < ( ast:: Attribute , Option < DefId > ) > = Vec :: new ( ) ;
21762176 let mut first = true ;
2177- let hir_map = tcx. hir ( ) ;
2177+ let hir_map = cx . tcx . hir ( ) ;
21782178 let mut visitor = OneLevelVisitor :: new ( hir_map, target_def_id) ;
21792179 let mut visited = FxHashSet :: default ( ) ;
2180+ let mut import_attrs = Vec :: new ( ) ;
21802181
21812182 // If the item is an import and has at least a path with two parts, we go into it.
21822183 while let hir:: ItemKind :: Use ( path, _) = item. kind && visited. insert ( item. hir_id ( ) ) {
2184+ let import_parent = cx. tcx . opt_local_parent ( prev_import) . map ( |def_id| def_id. to_def_id ( ) ) ;
21832185 if first {
21842186 // This is the "original" reexport so we get all its attributes without filtering them.
2185- attributes. extend_from_slice ( hir_map. attrs ( item. hir_id ( ) ) ) ;
2187+ attributes = hir_map. attrs ( item. hir_id ( ) ) . iter ( ) . cloned ( ) . map ( |attr| ( attr , import_parent ) ) . collect :: < Vec < _ > > ( ) ;
21862188 first = false ;
21872189 } else {
2188- add_without_unwanted_attributes ( attributes, hir_map. attrs ( item. hir_id ( ) ) , is_inline) ;
2190+ add_without_unwanted_attributes ( & mut import_attrs, hir_map. attrs ( item. hir_id ( ) ) , is_inline) ;
2191+ for attr in import_attrs. drain ( ..) {
2192+ attributes. push ( ( attr, import_parent) ) ;
2193+ }
21892194 }
21902195
2191- if let Some ( i) = visitor. find_target ( tcx, item. owner_id . def_id . to_def_id ( ) , path) {
2196+ if let Some ( i) = visitor. find_target ( cx . tcx , item. owner_id . def_id . to_def_id ( ) , path) {
21922197 item = i;
21932198 } else {
21942199 break ;
21952200 }
2201+ prev_import = item. owner_id . def_id ;
21962202 }
2203+ attributes
21972204}
21982205
21992206fn filter_tokens_from_list (
@@ -2244,7 +2251,7 @@ fn add_without_unwanted_attributes(
22442251 new_attrs : & [ ast:: Attribute ] ,
22452252 is_inline : bool ,
22462253) {
2247- // If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
2254+ // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
22482255 if !is_inline {
22492256 attrs. extend_from_slice ( new_attrs) ;
22502257 return ;
@@ -2374,26 +2381,43 @@ fn clean_maybe_renamed_item<'tcx>(
23742381 _ => unreachable ! ( "not yet converted" ) ,
23752382 } ;
23762383
2377- let mut import_attrs = Vec :: new ( ) ;
2378- let mut target_attrs = Vec :: new ( ) ;
2379- if let Some ( import_id) = import_id &&
2384+ let attrs = if let Some ( import_id) = import_id &&
23802385 let Some ( hir:: Node :: Item ( use_node) ) = cx. tcx . hir ( ) . find_by_def_id ( import_id)
23812386 {
2382- let is_inline = inline:: load_attrs ( cx, import_id. to_def_id ( ) ) . lists ( sym:: doc) . get_word_attr ( sym:: inline) . is_some ( ) ;
2387+ let is_inline = inline:: load_attrs ( cx, import_id. to_def_id ( ) )
2388+ . lists ( sym:: doc)
2389+ . get_word_attr ( sym:: inline)
2390+ . is_some ( ) ;
23832391 // Then we get all the various imports' attributes.
2384- get_all_import_attributes ( use_node, cx. tcx , item. owner_id . def_id , & mut import_attrs, is_inline) ;
2385- add_without_unwanted_attributes ( & mut target_attrs, inline:: load_attrs ( cx, def_id) , is_inline) ;
2392+ let mut attrs = get_all_import_attributes (
2393+ use_node,
2394+ cx,
2395+ item. owner_id . def_id ,
2396+ is_inline,
2397+ import_id,
2398+ ) ;
2399+
2400+ let mut target_attrs = Vec :: new ( ) ;
2401+ add_without_unwanted_attributes (
2402+ & mut target_attrs,
2403+ inline:: load_attrs ( cx, def_id) ,
2404+ is_inline,
2405+ ) ;
2406+ for attr in target_attrs. into_iter ( ) {
2407+ attrs. push ( ( attr, None ) ) ;
2408+ }
2409+ attrs
23862410 } else {
23872411 // We only keep the item's attributes.
2388- target_attrs . extend_from_slice ( inline:: load_attrs ( cx, def_id) ) ;
2389- }
2412+ inline:: load_attrs ( cx, def_id) . iter ( ) . cloned ( ) . map ( |attr| ( attr , None ) ) . collect :: < Vec < _ > > ( )
2413+ } ;
23902414
2391- let import_id = import_id . map ( |def_id| def_id . to_def_id ( ) ) ;
2392- let ( attrs, cfg ) = merge_attrs ( cx , & target_attrs , Some ( ( & import_attrs , import_id ) ) ) ;
2415+ let cfg = attrs . cfg ( cx . tcx , & cx . cache . hidden_cfg ) ;
2416+ let attrs = Attributes :: from_ast_iter ( attrs . iter ( ) . map ( | ( attr , did ) | ( attr , * did ) ) , false ) ;
23932417
23942418 let mut item =
23952419 Item :: from_def_id_and_attrs_and_parts ( def_id, Some ( name) , kind, Box :: new ( attrs) , cfg) ;
2396- item. inline_stmt_id = import_id;
2420+ item. inline_stmt_id = import_id. map ( |local| local . to_def_id ( ) ) ;
23972421 vec ! [ item]
23982422 } )
23992423}
0 commit comments