@@ -32,14 +32,14 @@ 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 ;
38
39
use std:: hash:: Hash ;
39
40
use std:: mem;
40
41
use thin_vec:: ThinVec ;
41
42
42
- use crate :: clean:: inline:: merge_attrs;
43
43
use crate :: core:: { self , DocContext , ImplTraitParam } ;
44
44
use crate :: formats:: item_type:: ItemType ;
45
45
use crate :: visit_ast:: Module as DocModule ;
@@ -2168,32 +2168,39 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
2168
2168
/// documentation. Otherwise, we repeat the same operation until we find the "end item".
2169
2169
fn get_all_import_attributes < ' hir > (
2170
2170
mut item : & hir:: Item < ' hir > ,
2171
- tcx : TyCtxt < ' hir > ,
2171
+ cx : & mut DocContext < ' hir > ,
2172
2172
target_def_id : LocalDefId ,
2173
- attributes : & mut Vec < ast:: Attribute > ,
2174
2173
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 ( ) ;
2176
2177
let mut first = true ;
2177
- let hir_map = tcx. hir ( ) ;
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
2181
2181
2182
// If the item is an import and has at least a path with two parts, we go into it.
2182
2183
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 ( ) ) ;
2183
2185
if first {
2184
2186
// 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 < _ > > ( ) ;
2186
2191
first = false ;
2187
2192
} 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 ) ;
2189
2194
}
2190
2195
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) {
2192
2197
item = i;
2193
2198
} else {
2194
2199
break ;
2195
2200
}
2201
+ prev_import = item. owner_id . def_id ;
2196
2202
}
2203
+ attributes
2197
2204
}
2198
2205
2199
2206
fn filter_tokens_from_list (
@@ -2239,17 +2246,24 @@ fn filter_tokens_from_list(
2239
2246
/// * `doc(inline)`
2240
2247
/// * `doc(no_inline)`
2241
2248
/// * `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 ] ,
2245
2252
is_inline : bool ,
2253
+ import_parent : Option < DefId > ,
2246
2254
) {
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.
2248
2256
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
+ }
2250
2260
return ;
2251
2261
}
2252
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
+ }
2253
2267
let mut attr = attr. clone ( ) ;
2254
2268
match attr. kind {
2255
2269
ast:: AttrKind :: Normal ( ref mut normal) => {
@@ -2276,18 +2290,15 @@ fn add_without_unwanted_attributes(
2276
2290
)
2277
2291
} ) ;
2278
2292
args. tokens = TokenStream :: new ( tokens) ;
2279
- attrs. push ( attr) ;
2293
+ attrs. push ( ( Cow :: Owned ( attr) , import_parent ) ) ;
2280
2294
}
2281
2295
ast:: AttrArgs :: Empty | ast:: AttrArgs :: Eq ( ..) => {
2282
- attrs. push ( attr) ;
2283
- continue ;
2296
+ attrs. push ( ( Cow :: Owned ( attr) , import_parent) ) ;
2284
2297
}
2285
2298
}
2286
2299
}
2287
2300
}
2288
- ast:: AttrKind :: DocComment ( ..) => {
2289
- attrs. push ( attr) ;
2290
- }
2301
+ _ => unreachable ! ( ) ,
2291
2302
}
2292
2303
}
2293
2304
}
@@ -2374,26 +2385,43 @@ fn clean_maybe_renamed_item<'tcx>(
2374
2385
_ => unreachable ! ( "not yet converted" ) ,
2375
2386
} ;
2376
2387
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 &&
2380
2389
let Some ( hir:: Node :: Item ( use_node) ) = cx. tcx . hir ( ) . find_by_def_id ( import_id)
2381
2390
{
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 ( ) ;
2383
2395
// 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
2386
2411
} else {
2387
2412
// 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
+ } ;
2390
2415
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 ) ;
2393
2421
2394
2422
let mut item =
2395
2423
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 ( ) ) ;
2397
2425
vec ! [ item]
2398
2426
} )
2399
2427
}
0 commit comments