@@ -10,6 +10,7 @@ use syn::{
1010} ;
1111
1212mod kw {
13+ syn:: custom_keyword!( non_query) ;
1314 syn:: custom_keyword!( query) ;
1415}
1516
@@ -54,12 +55,37 @@ struct Query {
5455 modifiers : QueryModifiers ,
5556}
5657
57- impl Parse for Query {
58+ /// Declaration of a non-query dep kind.
59+ /// ```ignore (illustrative)
60+ /// /// Doc comment for `MyNonQuery`.
61+ /// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doc_comments
62+ /// non_query MyNonQuery
63+ /// // ^^^^^^^^^^ name
64+ /// ```
65+ struct NonQuery {
66+ doc_comments : Vec < Attribute > ,
67+ name : Ident ,
68+ }
69+
70+ enum QueryEntry {
71+ Query ( Query ) ,
72+ NonQuery ( NonQuery ) ,
73+ }
74+
75+ impl Parse for QueryEntry {
5876 fn parse ( input : ParseStream < ' _ > ) -> Result < Self > {
5977 let mut doc_comments = check_attributes ( input. call ( Attribute :: parse_outer) ?) ?;
6078
79+ // Try the non-query case first.
80+ if input. parse :: < kw:: non_query > ( ) . is_ok ( ) {
81+ let name: Ident = input. parse ( ) ?;
82+ return Ok ( QueryEntry :: NonQuery ( NonQuery { doc_comments, name } ) ) ;
83+ }
84+
6185 // Parse the query declaration. Like `query type_of(key: DefId) -> Ty<'tcx>`
62- input. parse :: < kw:: query > ( ) ?;
86+ if input. parse :: < kw:: query > ( ) . is_err ( ) {
87+ return Err ( input. error ( "expected `query` or `non_query`" ) ) ;
88+ }
6389 let name: Ident = input. parse ( ) ?;
6490
6591 // `(key: DefId)`
@@ -84,7 +110,7 @@ impl Parse for Query {
84110 doc_comments. push ( doc_comment_from_desc ( & modifiers. desc . expr_list ) ?) ;
85111 }
86112
87- Ok ( Query { doc_comments, modifiers, name, key_pat, key_ty, return_ty } )
113+ Ok ( QueryEntry :: Query ( Query { doc_comments, modifiers, name, key_pat, key_ty, return_ty } ) )
88114 }
89115}
90116
@@ -375,9 +401,9 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke
375401 // macro producing a higher order macro that has all its token in the macro declaration we lose
376402 // any meaningful spans, resulting in rust-analyzer being unable to make the connection between
377403 // the query name and the corresponding providers field. The trick to fix this is to have
378- // `rustc_queries` emit a field access with the given name's span which allows it to successfully
379- // show references / go to definition to the corresponding provider assignment which is usually
380- // the more interesting place.
404+ // `rustc_queries` emit a field access with the given name's span which allows it to
405+ // successfully show references / go to definition to the corresponding provider assignment
406+ // which is usually the more interesting place.
381407 let ra_hint = quote ! {
382408 let crate :: query:: Providers { #name: _, .. } ;
383409 } ;
@@ -393,9 +419,10 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke
393419}
394420
395421pub ( super ) fn rustc_queries ( input : TokenStream ) -> TokenStream {
396- let queries = parse_macro_input ! ( input as List <Query >) ;
422+ let queries = parse_macro_input ! ( input as List <QueryEntry >) ;
397423
398424 let mut query_stream = quote ! { } ;
425+ let mut non_query_stream = quote ! { } ;
399426 let mut helpers = HelperTokenStreams :: default ( ) ;
400427 let mut analyzer_stream = quote ! { } ;
401428 let mut errors = quote ! { } ;
@@ -411,6 +438,18 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
411438 }
412439
413440 for query in queries. 0 {
441+ let query = match query {
442+ QueryEntry :: Query ( query) => query,
443+ QueryEntry :: NonQuery ( NonQuery { doc_comments, name } ) => {
444+ // Get the exceptional non-query case out of the way first.
445+ non_query_stream. extend ( quote ! {
446+ #( #doc_comments) *
447+ #name,
448+ } ) ;
449+ continue ;
450+ }
451+ } ;
452+
414453 let Query { doc_comments, name, key_ty, return_ty, modifiers, .. } = & query;
415454
416455 // Normalize an absent return type into `-> ()` to make macro-rules parsing easier.
@@ -486,24 +525,18 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
486525 let HelperTokenStreams { description_fns_stream, cache_on_disk_if_fns_stream } = helpers;
487526
488527 TokenStream :: from ( quote ! {
489- /// Higher-order macro that invokes the specified macro with a prepared
490- /// list of all query signatures (including modifiers).
491- ///
492- /// This allows multiple simpler macros to each have access to the list
493- /// of queries.
528+ /// Higher-order macro that invokes the specified macro with (a) a list of all query
529+ /// signatures (including modifiers), and (b) a list of non-query names. This allows
530+ /// multiple simpler macros to each have access to these lists.
494531 #[ macro_export]
495532 macro_rules! rustc_with_all_queries {
496533 (
497- // The macro to invoke once, on all queries (plus extras) .
534+ // The macro to invoke once, on all queries and non-queries .
498535 $macro: ident!
499-
500- // Within [], an optional list of extra "query" signatures to
501- // pass to the given macro, in addition to the actual queries.
502- $( [ $( $extra_fake_queries: tt) * ] ) ?
503536 ) => {
504537 $macro! {
505- $ ( $ ( $extra_fake_queries ) * ) ?
506- #query_stream
538+ queries { #query_stream }
539+ non_queries { #non_query_stream }
507540 }
508541 }
509542 }
0 commit comments