2
2
use std:: sync:: Arc ;
3
3
4
4
use crate :: clean:: cfg:: Cfg ;
5
+ use crate :: clean:: inline:: { load_attrs, merge_attrs} ;
5
6
use crate :: clean:: { Crate , Item } ;
6
7
use crate :: core:: DocContext ;
7
8
use crate :: fold:: DocFolder ;
8
9
use crate :: passes:: Pass ;
9
10
11
+ use rustc_hir:: def_id:: LocalDefId ;
12
+
10
13
pub ( crate ) const PROPAGATE_DOC_CFG : Pass = Pass {
11
14
name : "propagate-doc-cfg" ,
12
15
run : propagate_doc_cfg,
13
16
description : "propagates `#[doc(cfg(...))]` to child items" ,
14
17
} ;
15
18
16
- pub ( crate ) fn propagate_doc_cfg ( cr : Crate , _ : & mut DocContext < ' _ > ) -> Crate {
17
- CfgPropagator { parent_cfg : None } . fold_crate ( cr)
19
+ pub ( crate ) fn propagate_doc_cfg ( cr : Crate , cx : & mut DocContext < ' _ > ) -> Crate {
20
+ CfgPropagator { parent_cfg : None , parent : None , cx } . fold_crate ( cr)
18
21
}
19
22
20
- struct CfgPropagator {
23
+ struct CfgPropagator < ' a , ' tcx > {
21
24
parent_cfg : Option < Arc < Cfg > > ,
25
+ parent : Option < LocalDefId > ,
26
+ cx : & ' a mut DocContext < ' tcx > ,
22
27
}
23
28
24
- impl DocFolder for CfgPropagator {
29
+ impl < ' a , ' tcx > DocFolder for CfgPropagator < ' a , ' tcx > {
25
30
fn fold_item ( & mut self , mut item : Item ) -> Option < Item > {
26
31
let old_parent_cfg = self . parent_cfg . clone ( ) ;
27
32
33
+ if item. kind . is_non_assoc ( ) &&
34
+ let Some ( def_id) = item. item_id . as_def_id ( ) . and_then ( |def_id| def_id. as_local ( ) ) {
35
+ let hir = self . cx . tcx . hir ( ) ;
36
+ let hir_id = hir. local_def_id_to_hir_id ( def_id) ;
37
+ let expected_parent = hir. get_parent_item ( hir_id) ;
38
+
39
+ // If parents are different, it means that `item` is a reexport and we need to compute
40
+ // the actual `cfg` by iterating through its "real" parents.
41
+ if self . parent != Some ( expected_parent) {
42
+ let mut attrs = Vec :: new ( ) ;
43
+ for ( parent_hir_id, _) in hir. parent_iter ( hir_id) {
44
+ let def_id = hir. local_def_id ( parent_hir_id) . to_def_id ( ) ;
45
+ attrs. extend_from_slice ( load_attrs ( self . cx , def_id) ) ;
46
+ }
47
+ let ( _, cfg) =
48
+ merge_attrs ( self . cx , None , item. attrs . other_attrs . as_slice ( ) , Some ( & attrs) ) ;
49
+ item. cfg = cfg;
50
+ }
51
+ }
28
52
let new_cfg = match ( self . parent_cfg . take ( ) , item. cfg . take ( ) ) {
29
53
( None , None ) => None ,
30
54
( Some ( rc) , None ) | ( None , Some ( rc) ) => Some ( rc) ,
@@ -37,8 +61,15 @@ impl DocFolder for CfgPropagator {
37
61
self . parent_cfg = new_cfg. clone ( ) ;
38
62
item. cfg = new_cfg;
39
63
64
+ let old_parent =
65
+ if let Some ( def_id) = item. item_id . as_def_id ( ) . and_then ( |def_id| def_id. as_local ( ) ) {
66
+ self . parent . replace ( def_id)
67
+ } else {
68
+ self . parent . take ( )
69
+ } ;
40
70
let result = self . fold_item_recur ( item) ;
41
71
self . parent_cfg = old_parent_cfg;
72
+ self . parent = old_parent;
42
73
43
74
Some ( result)
44
75
}
0 commit comments