@@ -39,7 +39,6 @@ use std::hash::Hash;
39
39
use std:: mem;
40
40
use thin_vec:: ThinVec ;
41
41
42
- use crate :: clean:: inline:: merge_attrs;
43
42
use crate :: core:: { self , DocContext , ImplTraitParam } ;
44
43
use crate :: formats:: item_type:: ItemType ;
45
44
use crate :: visit_ast:: Module as DocModule ;
@@ -2168,32 +2167,40 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
2168
2167
/// documentation. Otherwise, we repeat the same operation until we find the "end item".
2169
2168
fn get_all_import_attributes < ' hir > (
2170
2169
mut item : & hir:: Item < ' hir > ,
2171
- tcx : TyCtxt < ' hir > ,
2170
+ cx : & mut DocContext < ' hir > ,
2172
2171
target_def_id : LocalDefId ,
2173
- attributes : & mut Vec < ast:: Attribute > ,
2174
2172
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 ( ) ;
2176
2176
let mut first = true ;
2177
- let hir_map = tcx. hir ( ) ;
2177
+ let hir_map = cx . tcx . hir ( ) ;
2178
2178
let mut visitor = OneLevelVisitor :: new ( hir_map, target_def_id) ;
2179
2179
let mut visited = FxHashSet :: default ( ) ;
2180
+ let mut import_attrs = Vec :: new ( ) ;
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 ( ) ) . iter ( ) . cloned ( ) . map ( |attr| ( attr , import_parent ) ) . collect :: < Vec < _ > > ( ) ;
2186
2188
first = false ;
2187
2189
} 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
+ }
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 (
@@ -2244,7 +2251,7 @@ fn add_without_unwanted_attributes(
2244
2251
new_attrs : & [ ast:: Attribute ] ,
2245
2252
is_inline : bool ,
2246
2253
) {
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.
2248
2255
if !is_inline {
2249
2256
attrs. extend_from_slice ( new_attrs) ;
2250
2257
return ;
@@ -2374,26 +2381,43 @@ fn clean_maybe_renamed_item<'tcx>(
2374
2381
_ => unreachable ! ( "not yet converted" ) ,
2375
2382
} ;
2376
2383
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 &&
2380
2385
let Some ( hir:: Node :: Item ( use_node) ) = cx. tcx . hir ( ) . find_by_def_id ( import_id)
2381
2386
{
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 ( ) ;
2383
2391
// 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
2386
2410
} else {
2387
2411
// 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
+ } ;
2390
2414
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 ) ;
2393
2417
2394
2418
let mut item =
2395
2419
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 ( ) ) ;
2397
2421
vec ! [ item]
2398
2422
} )
2399
2423
}
0 commit comments