1
1
//! Validates all used crates and extern libraries and loads their metadata
2
2
3
- use crate :: cstore:: CStore ;
4
3
use crate :: locator:: { CrateLocator , CratePaths } ;
5
4
use crate :: rmeta:: { CrateMetadata , CrateNumMap , CrateRoot , CrateDep , MetadataBlob } ;
6
5
7
6
use rustc:: hir:: def_id:: CrateNum ;
8
7
use rustc_data_structures:: svh:: Svh ;
8
+ use rustc_data_structures:: sync:: Lrc ;
9
+ use rustc_index:: vec:: IndexVec ;
9
10
use rustc:: middle:: cstore:: DepKind ;
10
11
use rustc:: session:: { Session , CrateDisambiguator } ;
11
12
use rustc:: session:: config:: { Sanitizer , self } ;
@@ -21,18 +22,22 @@ use std::{cmp, fs};
21
22
22
23
use syntax:: ast;
23
24
use syntax:: attr;
25
+ use syntax:: edition:: Edition ;
24
26
use syntax:: expand:: allocator:: { global_allocator_spans, AllocatorKind } ;
25
27
use syntax:: symbol:: { Symbol , sym} ;
26
28
use syntax:: span_fatal;
29
+ use syntax_expand:: base:: SyntaxExtension ;
27
30
use syntax_pos:: { Span , DUMMY_SP } ;
28
31
use log:: { debug, info, log_enabled} ;
29
32
use proc_macro:: bridge:: client:: ProcMacro ;
30
33
31
34
use rustc_error_codes:: * ;
32
35
33
- crate struct Library {
34
- pub source : CrateSource ,
35
- pub metadata : MetadataBlob ,
36
+ #[ derive( Clone ) ]
37
+ pub struct CStore {
38
+ metas : IndexVec < CrateNum , Option < Lrc < CrateMetadata > > > ,
39
+ crate injected_panic_runtime : Option < CrateNum > ,
40
+ crate allocator_kind : Option < AllocatorKind > ,
36
41
}
37
42
38
43
pub struct CrateLoader < ' a > {
@@ -44,6 +49,33 @@ pub struct CrateLoader<'a> {
44
49
cstore : CStore ,
45
50
}
46
51
52
+ pub enum LoadedMacro {
53
+ MacroDef ( ast:: Item , Edition ) ,
54
+ ProcMacro ( SyntaxExtension ) ,
55
+ }
56
+
57
+ crate struct Library {
58
+ pub source : CrateSource ,
59
+ pub metadata : MetadataBlob ,
60
+ }
61
+
62
+ enum LoadResult {
63
+ Previous ( CrateNum ) ,
64
+ Loaded ( Library ) ,
65
+ }
66
+
67
+ enum LoadError < ' a > {
68
+ LocatorError ( CrateLocator < ' a > ) ,
69
+ }
70
+
71
+ impl < ' a > LoadError < ' a > {
72
+ fn report ( self ) -> ! {
73
+ match self {
74
+ LoadError :: LocatorError ( locator) => locator. report_errs ( ) ,
75
+ }
76
+ }
77
+ }
78
+
47
79
fn dump_crates ( cstore : & CStore ) {
48
80
info ! ( "resolved crates:" ) ;
49
81
cstore. iter_crate_data ( |cnum, data| {
@@ -58,21 +90,58 @@ fn dump_crates(cstore: &CStore) {
58
90
} ) ;
59
91
}
60
92
61
- enum LoadResult {
62
- Previous ( CrateNum ) ,
63
- Loaded ( Library ) ,
64
- }
93
+ impl CStore {
94
+ crate fn alloc_new_crate_num ( & mut self ) -> CrateNum {
95
+ self . metas . push ( None ) ;
96
+ CrateNum :: new ( self . metas . len ( ) - 1 )
97
+ }
65
98
66
- enum LoadError < ' a > {
67
- LocatorError ( CrateLocator < ' a > ) ,
68
- }
99
+ crate fn get_crate_data ( & self , cnum : CrateNum ) -> & CrateMetadata {
100
+ self . metas [ cnum] . as_ref ( )
101
+ . unwrap_or_else ( || panic ! ( "Failed to get crate data for {:?}" , cnum) )
102
+ }
69
103
70
- impl < ' a > LoadError < ' a > {
71
- fn report ( self ) -> ! {
72
- match self {
73
- LoadError :: LocatorError ( locator) => locator. report_errs ( ) ,
104
+ crate fn set_crate_data ( & mut self , cnum : CrateNum , data : CrateMetadata ) {
105
+ assert ! ( self . metas[ cnum] . is_none( ) , "Overwriting crate metadata entry" ) ;
106
+ self . metas [ cnum] = Some ( Lrc :: new ( data) ) ;
107
+ }
108
+
109
+ crate fn iter_crate_data ( & self , mut f : impl FnMut ( CrateNum , & CrateMetadata ) ) {
110
+ for ( cnum, data) in self . metas . iter_enumerated ( ) {
111
+ if let Some ( data) = data {
112
+ f ( cnum, data) ;
113
+ }
114
+ }
115
+ }
116
+
117
+ fn push_dependencies_in_postorder ( & self , deps : & mut Vec < CrateNum > , cnum : CrateNum ) {
118
+ if !deps. contains ( & cnum) {
119
+ let data = self . get_crate_data ( cnum) ;
120
+ for & dep in data. dependencies ( ) . iter ( ) {
121
+ if dep != cnum {
122
+ self . push_dependencies_in_postorder ( deps, dep) ;
123
+ }
124
+ }
125
+
126
+ deps. push ( cnum) ;
74
127
}
75
128
}
129
+
130
+ crate fn crate_dependencies_in_postorder ( & self , cnum : CrateNum ) -> Vec < CrateNum > {
131
+ let mut deps = Vec :: new ( ) ;
132
+ if cnum == LOCAL_CRATE {
133
+ self . iter_crate_data ( |cnum, _| self . push_dependencies_in_postorder ( & mut deps, cnum) ) ;
134
+ } else {
135
+ self . push_dependencies_in_postorder ( & mut deps, cnum) ;
136
+ }
137
+ deps
138
+ }
139
+
140
+ crate fn crate_dependencies_in_reverse_postorder ( & self , cnum : CrateNum ) -> Vec < CrateNum > {
141
+ let mut deps = self . crate_dependencies_in_postorder ( cnum) ;
142
+ deps. reverse ( ) ;
143
+ deps
144
+ }
76
145
}
77
146
78
147
impl < ' a > CrateLoader < ' a > {
@@ -85,7 +154,15 @@ impl<'a> CrateLoader<'a> {
85
154
sess,
86
155
metadata_loader,
87
156
local_crate_name : Symbol :: intern ( local_crate_name) ,
88
- cstore : Default :: default ( ) ,
157
+ cstore : CStore {
158
+ // We add an empty entry for LOCAL_CRATE (which maps to zero) in
159
+ // order to make array indices in `metas` match with the
160
+ // corresponding `CrateNum`. This first entry will always remain
161
+ // `None`.
162
+ metas : IndexVec :: from_elem_n ( None , 1 ) ,
163
+ injected_panic_runtime : None ,
164
+ allocator_kind : None ,
165
+ }
89
166
}
90
167
}
91
168
0 commit comments