@@ -32,6 +32,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
32
32
use rustc_span:: { self , ExpnKind } ;
33
33
34
34
use std:: assert_matches:: assert_matches;
35
+ use std:: borrow:: Cow ;
35
36
use std:: collections:: hash_map:: Entry ;
36
37
use std:: collections:: BTreeMap ;
37
38
use std:: default:: Default ;
@@ -2171,26 +2172,25 @@ fn get_all_import_attributes<'hir>(
2171
2172
target_def_id : LocalDefId ,
2172
2173
is_inline : bool ,
2173
2174
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 ( ) ;
2176
2177
let mut first = true ;
2177
2178
let hir_map = cx. tcx . hir ( ) ;
2178
2179
let mut visitor = OneLevelVisitor :: new ( hir_map, target_def_id) ;
2179
2180
let mut visited = FxHashSet :: default ( ) ;
2180
- let mut import_attrs = Vec :: new ( ) ;
2181
2181
2182
2182
// If the item is an import and has at least a path with two parts, we go into it.
2183
2183
while let hir:: ItemKind :: Use ( path, _) = item. kind && visited. insert ( item. hir_id ( ) ) {
2184
2184
let import_parent = cx. tcx . opt_local_parent ( prev_import) . map ( |def_id| def_id. to_def_id ( ) ) ;
2185
2185
if first {
2186
2186
// 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 < _ > > ( ) ;
2188
2191
first = false ;
2189
2192
} 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) ;
2194
2194
}
2195
2195
2196
2196
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(
2246
2246
/// * `doc(inline)`
2247
2247
/// * `doc(no_inline)`
2248
2248
/// * `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 ] ,
2252
2252
is_inline : bool ,
2253
+ import_parent : Option < DefId > ,
2253
2254
) {
2254
2255
// If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
2255
2256
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
+ }
2257
2260
return ;
2258
2261
}
2259
2262
for attr in new_attrs {
2263
+ if matches ! ( attr. kind, ast:: AttrKind :: DocComment ( ..) ) {
2264
+ attrs. push ( ( Cow :: Borrowed ( attr) , import_parent) ) ;
2265
+ continue ;
2266
+ }
2260
2267
let mut attr = attr. clone ( ) ;
2261
2268
match attr. kind {
2262
2269
ast:: AttrKind :: Normal ( ref mut normal) => {
@@ -2283,18 +2290,15 @@ fn add_without_unwanted_attributes(
2283
2290
)
2284
2291
} ) ;
2285
2292
args. tokens = TokenStream :: new ( tokens) ;
2286
- attrs. push ( attr) ;
2293
+ attrs. push ( ( Cow :: Owned ( attr) , import_parent ) ) ;
2287
2294
}
2288
2295
ast:: AttrArgs :: Empty | ast:: AttrArgs :: Eq ( ..) => {
2289
- attrs. push ( attr) ;
2290
- continue ;
2296
+ attrs. push ( ( Cow :: Owned ( attr) , import_parent) ) ;
2291
2297
}
2292
2298
}
2293
2299
}
2294
2300
}
2295
- ast:: AttrKind :: DocComment ( ..) => {
2296
- attrs. push ( attr) ;
2297
- }
2301
+ _ => unreachable ! ( ) ,
2298
2302
}
2299
2303
}
2300
2304
}
@@ -2397,23 +2401,23 @@ fn clean_maybe_renamed_item<'tcx>(
2397
2401
import_id,
2398
2402
) ;
2399
2403
2400
- let mut target_attrs = Vec :: new ( ) ;
2401
2404
add_without_unwanted_attributes (
2402
- & mut target_attrs ,
2405
+ & mut attrs ,
2403
2406
inline:: load_attrs ( cx, def_id) ,
2404
2407
is_inline,
2408
+ None
2405
2409
) ;
2406
- for attr in target_attrs. into_iter ( ) {
2407
- attrs. push ( ( attr, None ) ) ;
2408
- }
2409
2410
attrs
2410
2411
} else {
2411
2412
// 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 < _ > > ( )
2413
2414
} ;
2414
2415
2415
2416
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 ) ;
2417
2421
2418
2422
let mut item =
2419
2423
Item :: from_def_id_and_attrs_and_parts ( def_id, Some ( name) , kind, Box :: new ( attrs) , cfg) ;
0 commit comments