@@ -32,14 +32,14 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
3232use rustc_span:: { self , ExpnKind } ;
3333
3434use std:: assert_matches:: assert_matches;
35+ use std:: borrow:: Cow ;
3536use std:: collections:: hash_map:: Entry ;
3637use std:: collections:: BTreeMap ;
3738use std:: default:: Default ;
3839use std:: hash:: Hash ;
3940use std:: mem;
4041use thin_vec:: ThinVec ;
4142
42- use crate :: clean:: inline:: merge_attrs;
4343use crate :: core:: { self , DocContext , ImplTraitParam } ;
4444use crate :: formats:: item_type:: ItemType ;
4545use crate :: visit_ast:: Module as DocModule ;
@@ -2168,32 +2168,39 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
21682168/// documentation. Otherwise, we repeat the same operation until we find the "end item".
21692169fn get_all_import_attributes < ' hir > (
21702170 mut item : & hir:: Item < ' hir > ,
2171- tcx : TyCtxt < ' hir > ,
2171+ cx : & mut DocContext < ' hir > ,
21722172 target_def_id : LocalDefId ,
2173- attributes : & mut Vec < ast:: Attribute > ,
21742173 is_inline : bool ,
2175- ) {
2174+ mut prev_import : LocalDefId ,
2175+ ) -> Vec < ( Cow < ' hir , ast:: Attribute > , Option < DefId > ) > {
2176+ let mut attributes: Vec < ( Cow < ' hir , ast:: Attribute > , Option < DefId > ) > = Vec :: new ( ) ;
21762177 let mut first = true ;
2177- let hir_map = tcx. hir ( ) ;
2178+ let hir_map = cx . tcx . hir ( ) ;
21782179 let mut visitor = OneLevelVisitor :: new ( hir_map, target_def_id) ;
21792180 let mut visited = FxHashSet :: default ( ) ;
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 ( ) )
2188+ . iter ( )
2189+ . map ( |attr| ( Cow :: Borrowed ( attr) , import_parent) )
2190+ . collect :: < Vec < _ > > ( ) ;
21862191 first = false ;
21872192 } else {
2188- add_without_unwanted_attributes ( attributes, hir_map. attrs ( item. hir_id ( ) ) , is_inline) ;
2193+ add_without_unwanted_attributes ( & mut attributes, hir_map. attrs ( item. hir_id ( ) ) , is_inline, import_parent ) ;
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 (
@@ -2239,17 +2246,24 @@ fn filter_tokens_from_list(
22392246/// * `doc(inline)`
22402247/// * `doc(no_inline)`
22412248/// * `doc(hidden)`
2242- fn add_without_unwanted_attributes (
2243- attrs : & mut Vec < ast:: Attribute > ,
2244- new_attrs : & [ ast:: Attribute ] ,
2249+ fn add_without_unwanted_attributes < ' hir > (
2250+ attrs : & mut Vec < ( Cow < ' hir , ast:: Attribute > , Option < DefId > ) > ,
2251+ new_attrs : & ' hir [ ast:: Attribute ] ,
22452252 is_inline : bool ,
2253+ import_parent : Option < DefId > ,
22462254) {
2247- // If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
2255+ // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
22482256 if !is_inline {
2249- attrs. extend_from_slice ( new_attrs) ;
2257+ for attr in new_attrs {
2258+ attrs. push ( ( Cow :: Borrowed ( attr) , import_parent) ) ;
2259+ }
22502260 return ;
22512261 }
22522262 for attr in new_attrs {
2263+ if matches ! ( attr. kind, ast:: AttrKind :: DocComment ( ..) ) {
2264+ attrs. push ( ( Cow :: Borrowed ( attr) , import_parent) ) ;
2265+ continue ;
2266+ }
22532267 let mut attr = attr. clone ( ) ;
22542268 match attr. kind {
22552269 ast:: AttrKind :: Normal ( ref mut normal) => {
@@ -2276,18 +2290,15 @@ fn add_without_unwanted_attributes(
22762290 )
22772291 } ) ;
22782292 args. tokens = TokenStream :: new ( tokens) ;
2279- attrs. push ( attr) ;
2293+ attrs. push ( ( Cow :: Owned ( attr) , import_parent ) ) ;
22802294 }
22812295 ast:: AttrArgs :: Empty | ast:: AttrArgs :: Eq ( ..) => {
2282- attrs. push ( attr) ;
2283- continue ;
2296+ attrs. push ( ( Cow :: Owned ( attr) , import_parent) ) ;
22842297 }
22852298 }
22862299 }
22872300 }
2288- ast:: AttrKind :: DocComment ( ..) => {
2289- attrs. push ( attr) ;
2290- }
2301+ _ => unreachable ! ( ) ,
22912302 }
22922303 }
22932304}
@@ -2374,26 +2385,43 @@ fn clean_maybe_renamed_item<'tcx>(
23742385 _ => unreachable ! ( "not yet converted" ) ,
23752386 } ;
23762387
2377- let mut import_attrs = Vec :: new ( ) ;
2378- let mut target_attrs = Vec :: new ( ) ;
2379- if let Some ( import_id) = import_id &&
2388+ let attrs = if let Some ( import_id) = import_id &&
23802389 let Some ( hir:: Node :: Item ( use_node) ) = cx. tcx . hir ( ) . find_by_def_id ( import_id)
23812390 {
2382- let is_inline = inline:: load_attrs ( cx, import_id. to_def_id ( ) ) . lists ( sym:: doc) . get_word_attr ( sym:: inline) . is_some ( ) ;
2391+ let is_inline = inline:: load_attrs ( cx, import_id. to_def_id ( ) )
2392+ . lists ( sym:: doc)
2393+ . get_word_attr ( sym:: inline)
2394+ . is_some ( ) ;
23832395 // 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) ;
2396+ let mut attrs = get_all_import_attributes (
2397+ use_node,
2398+ cx,
2399+ item. owner_id . def_id ,
2400+ is_inline,
2401+ import_id,
2402+ ) ;
2403+
2404+ add_without_unwanted_attributes (
2405+ & mut attrs,
2406+ inline:: load_attrs ( cx, def_id) ,
2407+ is_inline,
2408+ None
2409+ ) ;
2410+ attrs
23862411 } else {
23872412 // We only keep the item's attributes.
2388- target_attrs . extend_from_slice ( inline:: load_attrs ( cx, def_id) ) ;
2389- }
2413+ inline:: load_attrs ( cx, def_id) . iter ( ) . map ( |attr| ( Cow :: Borrowed ( attr ) , None ) ) . collect :: < Vec < _ > > ( )
2414+ } ;
23902415
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) ) ) ;
2416+ let cfg = attrs. cfg ( cx. tcx , & cx. cache . hidden_cfg ) ;
2417+ let attrs = Attributes :: from_ast_iter ( attrs. iter ( ) . map ( |( attr, did) | match attr {
2418+ Cow :: Borrowed ( attr) => ( * attr, * did) ,
2419+ Cow :: Owned ( attr) => ( attr, * did)
2420+ } ) , false ) ;
23932421
23942422 let mut item =
23952423 Item :: from_def_id_and_attrs_and_parts ( def_id, Some ( name) , kind, Box :: new ( attrs) , cfg) ;
2396- item. inline_stmt_id = import_id;
2424+ item. inline_stmt_id = import_id. map ( |local| local . to_def_id ( ) ) ;
23972425 vec ! [ item]
23982426 } )
23992427}
0 commit comments