@@ -32,6 +32,7 @@ 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 ;
@@ -2171,26 +2172,25 @@ fn get_all_import_attributes<'hir>(
21712172 target_def_id : LocalDefId ,
21722173 is_inline : bool ,
21732174 mut prev_import : LocalDefId ,
2174- ) -> Vec < ( ast:: Attribute , Option < DefId > ) > {
2175- let mut attributes: Vec < ( ast:: Attribute , Option < DefId > ) > = Vec :: new ( ) ;
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 ;
21772178 let hir_map = cx. tcx . hir ( ) ;
21782179 let mut visitor = OneLevelVisitor :: new ( hir_map, target_def_id) ;
21792180 let mut visited = FxHashSet :: default ( ) ;
2180- let mut import_attrs = Vec :: new ( ) ;
21812181
21822182 // If the item is an import and has at least a path with two parts, we go into it.
21832183 while let hir:: ItemKind :: Use ( path, _) = item. kind && visited. insert ( item. hir_id ( ) ) {
21842184 let import_parent = cx. tcx . opt_local_parent ( prev_import) . map ( |def_id| def_id. to_def_id ( ) ) ;
21852185 if first {
21862186 // This is the "original" reexport so we get all its attributes without filtering them.
2187- attributes = hir_map. attrs ( item. hir_id ( ) ) . iter ( ) . cloned ( ) . map ( |attr| ( attr, import_parent) ) . collect :: < Vec < _ > > ( ) ;
2187+ attributes = hir_map. attrs ( item. hir_id ( ) )
2188+ . iter ( )
2189+ . map ( |attr| ( Cow :: Borrowed ( attr) , import_parent) )
2190+ . collect :: < Vec < _ > > ( ) ;
21882191 first = false ;
21892192 } else {
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- }
2193+ add_without_unwanted_attributes ( & mut attributes, hir_map. attrs ( item. hir_id ( ) ) , is_inline, import_parent) ;
21942194 }
21952195
21962196 if let Some ( i) = visitor. find_target ( cx. tcx , item. owner_id . def_id . to_def_id ( ) , path) {
@@ -2246,17 +2246,24 @@ fn filter_tokens_from_list(
22462246/// * `doc(inline)`
22472247/// * `doc(no_inline)`
22482248/// * `doc(hidden)`
2249- fn add_without_unwanted_attributes (
2250- attrs : & mut Vec < ast:: Attribute > ,
2251- 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 ] ,
22522252 is_inline : bool ,
2253+ import_parent : Option < DefId > ,
22532254) {
22542255 // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
22552256 if !is_inline {
2256- attrs. extend_from_slice ( new_attrs) ;
2257+ for attr in new_attrs {
2258+ attrs. push ( ( Cow :: Borrowed ( attr) , import_parent) ) ;
2259+ }
22572260 return ;
22582261 }
22592262 for attr in new_attrs {
2263+ if matches ! ( attr. kind, ast:: AttrKind :: DocComment ( ..) ) {
2264+ attrs. push ( ( Cow :: Borrowed ( attr) , import_parent) ) ;
2265+ continue ;
2266+ }
22602267 let mut attr = attr. clone ( ) ;
22612268 match attr. kind {
22622269 ast:: AttrKind :: Normal ( ref mut normal) => {
@@ -2283,18 +2290,15 @@ fn add_without_unwanted_attributes(
22832290 )
22842291 } ) ;
22852292 args. tokens = TokenStream :: new ( tokens) ;
2286- attrs. push ( attr) ;
2293+ attrs. push ( ( Cow :: Owned ( attr) , import_parent ) ) ;
22872294 }
22882295 ast:: AttrArgs :: Empty | ast:: AttrArgs :: Eq ( ..) => {
2289- attrs. push ( attr) ;
2290- continue ;
2296+ attrs. push ( ( Cow :: Owned ( attr) , import_parent) ) ;
22912297 }
22922298 }
22932299 }
22942300 }
2295- ast:: AttrKind :: DocComment ( ..) => {
2296- attrs. push ( attr) ;
2297- }
2301+ _ => unreachable ! ( ) ,
22982302 }
22992303 }
23002304}
@@ -2397,23 +2401,23 @@ fn clean_maybe_renamed_item<'tcx>(
23972401 import_id,
23982402 ) ;
23992403
2400- let mut target_attrs = Vec :: new ( ) ;
24012404 add_without_unwanted_attributes (
2402- & mut target_attrs ,
2405+ & mut attrs ,
24032406 inline:: load_attrs ( cx, def_id) ,
24042407 is_inline,
2408+ None
24052409 ) ;
2406- for attr in target_attrs. into_iter ( ) {
2407- attrs. push ( ( attr, None ) ) ;
2408- }
24092410 attrs
24102411 } else {
24112412 // We only keep the item's attributes.
2412- inline:: load_attrs ( cx, def_id) . iter ( ) . cloned ( ) . map ( |attr| ( attr, None ) ) . collect :: < Vec < _ > > ( )
2413+ inline:: load_attrs ( cx, def_id) . iter ( ) . map ( |attr| ( Cow :: Borrowed ( attr) , None ) ) . collect :: < Vec < _ > > ( )
24132414 } ;
24142415
24152416 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 ) ;
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 ) ;
24172421
24182422 let mut item =
24192423 Item :: from_def_id_and_attrs_and_parts ( def_id, Some ( name) , kind, Box :: new ( attrs) , cfg) ;
0 commit comments