@@ -45,6 +45,9 @@ enum QueryModifier {
4545
4646 /// Don't hash the result, instead just mark a query red if it runs
4747 NoHash ,
48+
49+ /// Don't force the query
50+ NoForce ,
4851}
4952
5053impl Parse for QueryModifier {
@@ -94,6 +97,8 @@ impl Parse for QueryModifier {
9497 Ok ( QueryModifier :: FatalCycle )
9598 } else if modifier == "no_hash" {
9699 Ok ( QueryModifier :: NoHash )
100+ } else if modifier == "no_force" {
101+ Ok ( QueryModifier :: NoForce )
97102 } else {
98103 Err ( Error :: new ( modifier. span ( ) , "unknown query modifier" ) )
99104 }
@@ -194,6 +199,9 @@ struct QueryModifiers {
194199
195200 /// Don't hash the result, instead just mark a query red if it runs
196201 no_hash : bool ,
202+
203+ /// Don't force the query
204+ no_force : bool ,
197205}
198206
199207/// Process query modifiers into a struct, erroring on duplicates
@@ -203,6 +211,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
203211 let mut desc = None ;
204212 let mut fatal_cycle = false ;
205213 let mut no_hash = false ;
214+ let mut no_force = false ;
206215 for modifier in query. modifiers . 0 . drain ( ..) {
207216 match modifier {
208217 QueryModifier :: LoadCached ( tcx, id, block) => {
@@ -235,6 +244,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
235244 }
236245 no_hash = true ;
237246 }
247+ QueryModifier :: NoForce => {
248+ if no_force {
249+ panic ! ( "duplicate modifier `no_force` for query `{}`" , query. name) ;
250+ }
251+ no_force = true ;
252+ }
238253 }
239254 }
240255 QueryModifiers {
@@ -243,6 +258,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
243258 desc,
244259 fatal_cycle,
245260 no_hash,
261+ no_force,
246262 }
247263}
248264
@@ -329,6 +345,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
329345 let mut query_description_stream = quote ! { } ;
330346 let mut dep_node_def_stream = quote ! { } ;
331347 let mut dep_node_force_stream = quote ! { } ;
348+ let mut no_force_queries = Vec :: new ( ) ;
332349
333350 for group in groups. 0 {
334351 let mut group_stream = quote ! { } ;
@@ -364,29 +381,46 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
364381 [ #attribute_stream] fn #name: #name( #arg) #result,
365382 } ) ;
366383
367- add_query_description_impl ( & query, modifiers, & mut query_description_stream) ;
368-
369384 // Create a dep node for the query
370385 dep_node_def_stream. extend ( quote ! {
371386 [ ] #name( #arg) ,
372387 } ) ;
373388
374- // Add a match arm to force the query given the dep node
375- dep_node_force_stream. extend ( quote ! {
376- DepKind :: #name => {
377- if let Some ( key) = RecoverKey :: recover( $tcx, $dep_node) {
378- force_ex!( $tcx, #name, key) ;
379- } else {
380- return false ;
389+ if modifiers. no_force {
390+ no_force_queries. push ( name. clone ( ) ) ;
391+ } else {
392+ // Add a match arm to force the query given the dep node
393+ dep_node_force_stream. extend ( quote ! {
394+ DepKind :: #name => {
395+ if let Some ( key) = RecoverKey :: recover( $tcx, $dep_node) {
396+ force_ex!( $tcx, #name, key) ;
397+ } else {
398+ return false ;
399+ }
381400 }
382- }
383- } ) ;
401+ } ) ;
402+ }
403+
404+ add_query_description_impl ( & query, modifiers, & mut query_description_stream) ;
384405 }
385406 let name = & group. name ;
386407 query_stream. extend ( quote ! {
387408 #name { #group_stream } ,
388409 } ) ;
389410 }
411+
412+ // Add an arm for the no force queries to panic when trying to force them
413+ for query in no_force_queries {
414+ dep_node_force_stream. extend ( quote ! {
415+ DepKind :: #query |
416+ } ) ;
417+ }
418+ dep_node_force_stream. extend ( quote ! {
419+ DepKind :: Null => {
420+ bug!( "Cannot force dep node: {:?}" , $dep_node)
421+ }
422+ } ) ;
423+
390424 TokenStream :: from ( quote ! {
391425 macro_rules! rustc_query_append {
392426 ( [ $( $macro: tt) * ] [ $( $other: tt) * ] ) => {
0 commit comments