11use proc_macro:: TokenStream ;
22use proc_macro2:: Span ;
33use syn:: {
4- Token , Ident , Type , Attribute , ReturnType , Expr ,
4+ Token , Ident , Type , Attribute , ReturnType , Expr , Block ,
55 braced, parenthesized, parse_macro_input,
66} ;
77use syn:: parse:: { Result , Parse , ParseStream } ;
@@ -25,6 +25,7 @@ impl Parse for IdentOrWild {
2525enum QueryAttribute {
2626 Desc ( Option < Ident > , Punctuated < Expr , Token ! [ , ] > ) ,
2727 Cache ( Option < Ident > , Expr ) ,
28+ LoadCached ( Ident , Ident , Block ) ,
2829 FatalCycle ,
2930}
3031
@@ -63,6 +64,17 @@ impl Parse for QueryAttribute {
6364 panic ! ( "unexpected tokens in block" ) ;
6465 } ;
6566 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) )
6678 } else if attr == "fatal_cycle" {
6779 Ok ( QueryAttribute :: FatalCycle )
6880 } else {
@@ -153,22 +165,6 @@ impl Parse for Group {
153165 }
154166}
155167
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-
172168pub fn rustc_queries ( input : TokenStream ) -> TokenStream {
173169 let groups = parse_macro_input ! ( input as List <Group >) ;
174170
@@ -181,9 +177,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
181177 let mut group_stream = quote ! { } ;
182178 for query in & group. queries . 0 {
183179 let name = & query. name ;
184- let dep_node_name = Ident :: new (
185- & camel_case ( & name. to_string ( ) ) ,
186- name. span ( ) ) ;
187180 let arg = & query. arg ;
188181 let key = & query. key . 0 ;
189182 let result_full = & query. result ;
@@ -192,35 +185,60 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
192185 _ => quote ! { #result_full } ,
193186 } ;
194187
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+
195193 // Find out if we should cache the query on disk
196194 let cache = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
197195 QueryAttribute :: Cache ( tcx, expr) => Some ( ( tcx, expr) ) ,
198196 _ => None ,
199197 } ) . 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+
200220 let tcx = tcx. as_ref ( ) . map ( |t| quote ! { #t } ) . unwrap_or ( quote ! { _ } ) ;
201221 quote ! {
202222 #[ inline]
203223 fn cache_on_disk( #tcx: TyCtxt <' _, ' tcx, ' tcx>, #key: Self :: Key ) -> bool {
204224 #expr
205225 }
206226
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
214228 }
215229 } ) ;
216230
231+ if cache. is_none ( ) && load_cached. is_some ( ) {
232+ panic ! ( "load_cached modifier on query `{}` without a cache modifier" , name) ;
233+ }
234+
217235 let fatal_cycle = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
218236 QueryAttribute :: FatalCycle => Some ( ( ) ) ,
219237 _ => None ,
220238 } ) . map ( |_| quote ! { fatal_cycle } ) . unwrap_or ( quote ! { } ) ;
221239
222240 group_stream. extend ( quote ! {
223- [ #fatal_cycle] fn #name: #dep_node_name ( #arg) #result,
241+ [ #fatal_cycle] fn #name: #name ( #arg) #result,
224242 } ) ;
225243
226244 let desc = query. attrs . 0 . iter ( ) . find_map ( |attr| match attr {
@@ -251,10 +269,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
251269 }
252270
253271 dep_node_def_stream. extend ( quote ! {
254- [ ] #dep_node_name ( #arg) ,
272+ [ ] #name ( #arg) ,
255273 } ) ;
256274 dep_node_force_stream. extend ( quote ! {
257- DepKind :: #dep_node_name => {
275+ DepKind :: #name => {
258276 if let Some ( key) = RecoverKey :: recover( $tcx, $dep_node) {
259277 force_ex!( $tcx, #name, key) ;
260278 } else {
0 commit comments