8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use context:: SharedCrateContext ;
12
11
use monomorphize:: Instance ;
13
- use rustc:: util:: nodemap:: FxHashMap ;
14
- use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE } ;
12
+ use rustc:: util:: nodemap:: { FxHashMap , NodeSet } ;
13
+ use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE , INVALID_CRATE , CRATE_DEF_INDEX } ;
15
14
use rustc:: session:: config;
16
15
use rustc:: ty:: TyCtxt ;
17
16
use syntax:: attr;
@@ -28,59 +27,87 @@ pub enum SymbolExportLevel {
28
27
}
29
28
30
29
/// The set of symbols exported from each crate in the crate graph.
30
+ #[ derive( Debug ) ]
31
31
pub struct ExportedSymbols {
32
- exports : FxHashMap < CrateNum , Vec < ( String , SymbolExportLevel ) > > ,
32
+ pub export_threshold : SymbolExportLevel ,
33
+ exports : FxHashMap < CrateNum , Vec < ( String , DefId , SymbolExportLevel ) > > ,
34
+ local_exports : NodeSet ,
33
35
}
34
36
35
37
impl ExportedSymbols {
36
38
pub fn empty ( ) -> ExportedSymbols {
37
39
ExportedSymbols {
40
+ export_threshold : SymbolExportLevel :: C ,
38
41
exports : FxHashMap ( ) ,
42
+ local_exports : NodeSet ( ) ,
39
43
}
40
44
}
41
45
42
- pub fn compute < ' a , ' tcx > ( scx : & SharedCrateContext < ' a , ' tcx > ) -> ExportedSymbols {
43
- let mut local_crate: Vec < _ > = scx
44
- . exported_symbols ( )
46
+ pub fn compute < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
47
+ local_exported_symbols : & NodeSet )
48
+ -> ExportedSymbols {
49
+ let export_threshold = crates_export_threshold ( & tcx. sess . crate_types . borrow ( ) ) ;
50
+
51
+ let mut local_crate: Vec < _ > = local_exported_symbols
45
52
. iter ( )
46
53
. map ( |& node_id| {
47
- scx . tcx ( ) . hir . local_def_id ( node_id)
54
+ tcx. hir . local_def_id ( node_id)
48
55
} )
49
56
. map ( |def_id| {
50
- let name = scx . tcx ( ) . symbol_name ( Instance :: mono ( scx . tcx ( ) , def_id) ) ;
51
- let export_level = export_level ( scx , def_id) ;
57
+ let name = tcx. symbol_name ( Instance :: mono ( tcx, def_id) ) ;
58
+ let export_level = export_level ( tcx , def_id) ;
52
59
debug ! ( "EXPORTED SYMBOL (local): {} ({:?})" , name, export_level) ;
53
- ( str:: to_owned ( & name) , export_level)
60
+ ( str:: to_owned ( & name) , def_id , export_level)
54
61
} )
55
62
. collect ( ) ;
56
63
57
- if scx. sess ( ) . entry_fn . borrow ( ) . is_some ( ) {
58
- local_crate. push ( ( "main" . to_string ( ) , SymbolExportLevel :: C ) ) ;
64
+ let mut local_exports = local_crate
65
+ . iter ( )
66
+ . filter_map ( |& ( _, def_id, level) | {
67
+ if is_below_threshold ( level, export_threshold) {
68
+ tcx. hir . as_local_node_id ( def_id)
69
+ } else {
70
+ None
71
+ }
72
+ } )
73
+ . collect :: < NodeSet > ( ) ;
74
+
75
+ const INVALID_DEF_ID : DefId = DefId {
76
+ krate : INVALID_CRATE ,
77
+ index : CRATE_DEF_INDEX ,
78
+ } ;
79
+
80
+ if let Some ( _) = * tcx. sess . entry_fn . borrow ( ) {
81
+ local_crate. push ( ( "main" . to_string ( ) ,
82
+ INVALID_DEF_ID ,
83
+ SymbolExportLevel :: C ) ) ;
59
84
}
60
85
61
- if let Some ( id) = scx . sess ( ) . derive_registrar_fn . get ( ) {
62
- let def_id = scx . tcx ( ) . hir . local_def_id ( id) ;
86
+ if let Some ( id) = tcx . sess . derive_registrar_fn . get ( ) {
87
+ let def_id = tcx. hir . local_def_id ( id) ;
63
88
let idx = def_id. index ;
64
- let disambiguator = scx. sess ( ) . local_crate_disambiguator ( ) ;
65
- let registrar = scx. sess ( ) . generate_derive_registrar_symbol ( disambiguator, idx) ;
66
- local_crate. push ( ( registrar, SymbolExportLevel :: C ) ) ;
89
+ let disambiguator = tcx. sess . local_crate_disambiguator ( ) ;
90
+ let registrar = tcx. sess . generate_derive_registrar_symbol ( disambiguator, idx) ;
91
+ local_crate. push ( ( registrar, def_id, SymbolExportLevel :: C ) ) ;
92
+ local_exports. insert ( id) ;
67
93
}
68
94
69
- if scx. sess ( ) . crate_types . borrow ( ) . contains ( & config:: CrateTypeDylib ) {
70
- local_crate. push ( ( metadata_symbol_name ( scx. tcx ( ) ) ,
95
+ if tcx. sess . crate_types . borrow ( ) . contains ( & config:: CrateTypeDylib ) {
96
+ local_crate. push ( ( metadata_symbol_name ( tcx) ,
97
+ INVALID_DEF_ID ,
71
98
SymbolExportLevel :: Rust ) ) ;
72
99
}
73
100
74
101
let mut exports = FxHashMap ( ) ;
75
102
exports. insert ( LOCAL_CRATE , local_crate) ;
76
103
77
- for cnum in scx . sess ( ) . cstore . crates ( ) {
104
+ for cnum in tcx . sess . cstore . crates ( ) {
78
105
debug_assert ! ( cnum != LOCAL_CRATE ) ;
79
106
80
107
// If this crate is a plugin and/or a custom derive crate, then
81
108
// we're not even going to link those in so we skip those crates.
82
- if scx . sess ( ) . cstore . plugin_registrar_fn ( cnum) . is_some ( ) ||
83
- scx . sess ( ) . cstore . derive_registrar_fn ( cnum) . is_some ( ) {
109
+ if tcx . sess . cstore . plugin_registrar_fn ( cnum) . is_some ( ) ||
110
+ tcx . sess . cstore . derive_registrar_fn ( cnum) . is_some ( ) {
84
111
continue ;
85
112
}
86
113
@@ -92,16 +119,16 @@ impl ExportedSymbols {
92
119
// Down below we'll hardwire all of the symbols to the `Rust` export
93
120
// level instead.
94
121
let special_runtime_crate =
95
- scx . tcx ( ) . is_panic_runtime ( cnum. as_def_id ( ) ) ||
96
- scx . sess ( ) . cstore . is_compiler_builtins ( cnum) ;
122
+ tcx. is_panic_runtime ( cnum. as_def_id ( ) ) ||
123
+ tcx . sess . cstore . is_compiler_builtins ( cnum) ;
97
124
98
- let crate_exports = scx
99
- . sess ( )
125
+ let crate_exports = tcx
126
+ . sess
100
127
. cstore
101
128
. exported_symbols ( cnum)
102
129
. iter ( )
103
130
. map ( |& def_id| {
104
- let name = scx . tcx ( ) . symbol_name ( Instance :: mono ( scx . tcx ( ) , def_id) ) ;
131
+ let name = tcx. symbol_name ( Instance :: mono ( tcx, def_id) ) ;
105
132
let export_level = if special_runtime_crate {
106
133
// We can probably do better here by just ensuring that
107
134
// it has hidden visibility rather than public
@@ -118,35 +145,41 @@ impl ExportedSymbols {
118
145
SymbolExportLevel :: Rust
119
146
}
120
147
} else {
121
- export_level ( scx , def_id)
148
+ export_level ( tcx , def_id)
122
149
} ;
123
150
debug ! ( "EXPORTED SYMBOL (re-export): {} ({:?})" , name, export_level) ;
124
- ( str:: to_owned ( & name) , export_level)
151
+ ( str:: to_owned ( & name) , def_id , export_level)
125
152
} )
126
153
. collect ( ) ;
127
154
128
155
exports. insert ( cnum, crate_exports) ;
129
156
}
130
157
131
158
return ExportedSymbols {
132
- exports : exports
159
+ export_threshold,
160
+ exports,
161
+ local_exports,
133
162
} ;
134
163
135
- fn export_level ( scx : & SharedCrateContext ,
164
+ fn export_level ( tcx : TyCtxt ,
136
165
sym_def_id : DefId )
137
166
-> SymbolExportLevel {
138
- let attrs = scx . tcx ( ) . get_attrs ( sym_def_id) ;
139
- if attr:: contains_extern_indicator ( scx . sess ( ) . diagnostic ( ) , & attrs) {
167
+ let attrs = tcx. get_attrs ( sym_def_id) ;
168
+ if attr:: contains_extern_indicator ( tcx . sess . diagnostic ( ) , & attrs) {
140
169
SymbolExportLevel :: C
141
170
} else {
142
171
SymbolExportLevel :: Rust
143
172
}
144
173
}
145
174
}
146
175
176
+ pub fn local_exports ( & self ) -> & NodeSet {
177
+ & self . local_exports
178
+ }
179
+
147
180
pub fn exported_symbols ( & self ,
148
181
cnum : CrateNum )
149
- -> & [ ( String , SymbolExportLevel ) ] {
182
+ -> & [ ( String , DefId , SymbolExportLevel ) ] {
150
183
match self . exports . get ( & cnum) {
151
184
Some ( exports) => exports,
152
185
None => & [ ]
@@ -155,13 +188,12 @@ impl ExportedSymbols {
155
188
156
189
pub fn for_each_exported_symbol < F > ( & self ,
157
190
cnum : CrateNum ,
158
- export_threshold : SymbolExportLevel ,
159
191
mut f : F )
160
- where F : FnMut ( & str , SymbolExportLevel )
192
+ where F : FnMut ( & str , DefId , SymbolExportLevel )
161
193
{
162
- for & ( ref name, export_level) in self . exported_symbols ( cnum) {
163
- if is_below_threshold ( export_level, export_threshold) {
164
- f ( & name, export_level)
194
+ for & ( ref name, def_id , export_level) in self . exported_symbols ( cnum) {
195
+ if is_below_threshold ( export_level, self . export_threshold ) {
196
+ f ( & name, def_id , export_level)
165
197
}
166
198
}
167
199
}
0 commit comments