1
1
use proc_macro:: TokenStream ;
2
2
use proc_macro2:: Span ;
3
3
use syn:: {
4
- Token , Ident , Type , Attribute , ReturnType , Expr ,
4
+ Token , Ident , Type , Attribute , ReturnType , Expr , Block ,
5
5
braced, parenthesized, parse_macro_input,
6
6
} ;
7
7
use syn:: parse:: { Result , Parse , ParseStream } ;
@@ -25,6 +25,7 @@ impl Parse for IdentOrWild {
25
25
enum QueryAttribute {
26
26
Desc ( Option < Ident > , Punctuated < Expr , Token ! [ , ] > ) ,
27
27
Cache ( Option < Ident > , Expr ) ,
28
+ LoadCached ( Ident , Ident , Block ) ,
28
29
FatalCycle ,
29
30
}
30
31
@@ -63,6 +64,17 @@ impl Parse for QueryAttribute {
63
64
panic ! ( "unexpected tokens in block" ) ;
64
65
} ;
65
66
Ok ( QueryAttribute :: Cache ( tcx, expr) )
67
+ } else if attr == "load_cached" {
68
+ let args;
69
+ parenthesized ! ( args in input) ;
70
+ let tcx = args. parse ( ) ?;
71
+ args. parse :: < Token ! [ , ] > ( ) ?;
72
+ let id = args. parse ( ) ?;
73
+ if !args. is_empty ( ) {
74
+ panic ! ( "unexpected tokens in arguments" ) ;
75
+ } ;
76
+ let block = input. parse ( ) ?;
77
+ Ok ( QueryAttribute :: LoadCached ( tcx, id, block) )
66
78
} else if attr == "fatal_cycle" {
67
79
Ok ( QueryAttribute :: FatalCycle )
68
80
} else {
@@ -153,22 +165,6 @@ impl Parse for Group {
153
165
}
154
166
}
155
167
156
- fn camel_case ( string : & str ) -> String {
157
- let mut pos = vec ! [ 0 ] ;
158
- for ( i, c) in string. chars ( ) . enumerate ( ) {
159
- if c == '_' {
160
- pos. push ( i + 1 ) ;
161
- }
162
- }
163
- string. chars ( ) . enumerate ( ) . filter ( |c| c. 1 != '_' ) . flat_map ( |( i, c) | {
164
- if pos. contains ( & i) {
165
- c. to_uppercase ( ) . collect :: < Vec < char > > ( )
166
- } else {
167
- vec ! [ c]
168
- }
169
- } ) . collect ( )
170
- }
171
-
172
168
pub fn rustc_queries ( input : TokenStream ) -> TokenStream {
173
169
let groups = parse_macro_input ! ( input as List <Group >) ;
174
170
@@ -181,9 +177,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
181
177
let mut group_stream = quote ! { } ;
182
178
for query in & group. queries . 0 {
183
179
let name = & query. name ;
184
- let dep_node_name = Ident :: new (
185
- & camel_case ( & name. to_string ( ) ) ,
186
- name. span ( ) ) ;
187
180
let arg = & query. arg ;
188
181
let key = & query. key . 0 ;
189
182
let result_full = & query. result ;
@@ -192,35 +185,60 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
192
185
_ => quote ! { #result_full } ,
193
186
} ;
194
187
188
+ let load_cached = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
189
+ QueryAttribute :: LoadCached ( tcx, id, block) => Some ( ( tcx, id, block) ) ,
190
+ _ => None ,
191
+ } ) ;
192
+
195
193
// Find out if we should cache the query on disk
196
194
let cache = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
197
195
QueryAttribute :: Cache ( tcx, expr) => Some ( ( tcx, expr) ) ,
198
196
_ => None ,
199
197
} ) . map ( |( tcx, expr) | {
198
+ let try_load_from_disk = if let Some ( ( tcx, id, block) ) = load_cached {
199
+ quote ! {
200
+ #[ inline]
201
+ fn try_load_from_disk(
202
+ #tcx: TyCtxt <' _, ' tcx, ' tcx>,
203
+ #id: SerializedDepNodeIndex
204
+ ) -> Option <Self :: Value > {
205
+ #block
206
+ }
207
+ }
208
+ } else {
209
+ quote ! {
210
+ #[ inline]
211
+ fn try_load_from_disk(
212
+ tcx: TyCtxt <' _, ' tcx, ' tcx>,
213
+ id: SerializedDepNodeIndex
214
+ ) -> Option <Self :: Value > {
215
+ tcx. queries. on_disk_cache. try_load_query_result( tcx, id)
216
+ }
217
+ }
218
+ } ;
219
+
200
220
let tcx = tcx. as_ref ( ) . map ( |t| quote ! { #t } ) . unwrap_or ( quote ! { _ } ) ;
201
221
quote ! {
202
222
#[ inline]
203
223
fn cache_on_disk( #tcx: TyCtxt <' _, ' tcx, ' tcx>, #key: Self :: Key ) -> bool {
204
224
#expr
205
225
}
206
226
207
- #[ inline]
208
- fn try_load_from_disk(
209
- tcx: TyCtxt <' _, ' tcx, ' tcx>,
210
- id: SerializedDepNodeIndex
211
- ) -> Option <Self :: Value > {
212
- tcx. queries. on_disk_cache. try_load_query_result( tcx, id)
213
- }
227
+ #try_load_from_disk
214
228
}
215
229
} ) ;
216
230
231
+ if cache. is_none ( ) && load_cached. is_some ( ) {
232
+ panic ! ( "load_cached modifier on query `{}` without a cache modifier" , name) ;
233
+ }
234
+
217
235
let fatal_cycle = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
218
236
QueryAttribute :: FatalCycle => Some ( ( ) ) ,
219
237
_ => None ,
220
238
} ) . map ( |_| quote ! { fatal_cycle } ) . unwrap_or ( quote ! { } ) ;
221
239
222
240
group_stream. extend ( quote ! {
223
- [ #fatal_cycle] fn #name: #dep_node_name ( #arg) #result,
241
+ [ #fatal_cycle] fn #name: #name ( #arg) #result,
224
242
} ) ;
225
243
226
244
let desc = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
@@ -251,10 +269,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
251
269
}
252
270
253
271
dep_node_def_stream. extend ( quote ! {
254
- [ ] #dep_node_name ( #arg) ,
272
+ [ ] #name ( #arg) ,
255
273
} ) ;
256
274
dep_node_force_stream. extend ( quote ! {
257
- DepKind :: #dep_node_name => {
275
+ DepKind :: #name => {
258
276
if let Some ( key) = RecoverKey :: recover( $tcx, $dep_node) {
259
277
force_ex!( $tcx, #name, key) ;
260
278
} else {
0 commit comments