-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Make rustc_with_all_queries! pass query modifiers as named values
#153326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+260
−372
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,54 +137,23 @@ struct CacheOnDiskIf { | |
| block: Block, | ||
| } | ||
|
|
||
| /// See `rustc_middle::query::modifiers` for documentation of each query modifier. | ||
| struct QueryModifiers { | ||
| /// The description of the query. | ||
| desc: Desc, | ||
|
|
||
| /// Use this type for the in-memory cache. | ||
| // tidy-alphabetical-start | ||
| anon: Option<Ident>, | ||
| arena_cache: Option<Ident>, | ||
|
|
||
| /// Cache the query to disk if the `Block` returns true. | ||
| cache_on_disk_if: Option<CacheOnDiskIf>, | ||
|
|
||
| /// A cycle error for this query aborting the compilation with a fatal error. | ||
| cycle_fatal: Option<Ident>, | ||
|
|
||
| /// A cycle error results in a delay_bug call | ||
| cycle_delay_bug: Option<Ident>, | ||
|
|
||
| /// A cycle error results in a stashed cycle error that can be unstashed and canceled later | ||
| cycle_fatal: Option<Ident>, | ||
| cycle_stash: Option<Ident>, | ||
|
|
||
| /// Don't hash the result, instead just mark a query red if it runs | ||
| no_hash: Option<Ident>, | ||
|
|
||
| /// Generate a dep node based on the dependencies of the query | ||
| anon: Option<Ident>, | ||
|
|
||
| /// Always evaluate the query, ignoring its dependencies | ||
| eval_always: Option<Ident>, | ||
|
|
||
| /// Whether the query has a call depth limit | ||
| depth_limit: Option<Ident>, | ||
|
|
||
| /// Use a separate query provider for local and extern crates | ||
| separate_provide_extern: Option<Ident>, | ||
|
|
||
| /// Generate a `feed` method to set the query's value from another query. | ||
| desc: Desc, | ||
| eval_always: Option<Ident>, | ||
| feedable: Option<Ident>, | ||
|
|
||
| /// When this query is called via `tcx.ensure_ok()`, it returns | ||
| /// `Result<(), ErrorGuaranteed>` instead of `()`. If the query needs to | ||
| /// be executed, and that execution returns an error, the error result is | ||
| /// returned to the caller. | ||
| /// | ||
| /// If execution is skipped, a synthetic `Ok(())` is returned, on the | ||
| /// assumption that a query with all-green inputs must have succeeded. | ||
| /// | ||
| /// Can only be applied to queries with a return value of | ||
| /// `Result<_, ErrorGuaranteed>`. | ||
| no_hash: Option<Ident>, | ||
| return_result_from_ensure_ok: Option<Ident>, | ||
| separate_provide_extern: Option<Ident>, | ||
| // tidy-alphabetical-end | ||
| } | ||
|
|
||
| fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> { | ||
|
|
@@ -272,6 +241,68 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> { | |
| }) | ||
| } | ||
|
|
||
| fn make_modifiers_stream(query: &Query, modifiers: &QueryModifiers) -> proc_macro2::TokenStream { | ||
| let QueryModifiers { | ||
| // tidy-alphabetical-start | ||
| anon, | ||
| arena_cache, | ||
| cache_on_disk_if, | ||
| cycle_delay_bug, | ||
| cycle_fatal, | ||
| cycle_stash, | ||
| depth_limit, | ||
| desc: _, | ||
| eval_always, | ||
| feedable, | ||
| no_hash, | ||
| return_result_from_ensure_ok, | ||
| separate_provide_extern, | ||
| // tidy-alphabetical-end | ||
| } = modifiers; | ||
|
|
||
| let anon = anon.is_some(); | ||
| let arena_cache = arena_cache.is_some(); | ||
| let cache_on_disk = cache_on_disk_if.is_some(); | ||
|
|
||
| let cycle_error_handling = if cycle_delay_bug.is_some() { | ||
| quote! { DelayBug } | ||
| } else if cycle_fatal.is_some() { | ||
| quote! { Fatal } | ||
| } else if cycle_stash.is_some() { | ||
| quote! { Stash } | ||
| } else { | ||
| quote! { Error } | ||
| }; | ||
|
|
||
| let depth_limit = depth_limit.is_some(); | ||
| let eval_always = eval_always.is_some(); | ||
| let feedable = feedable.is_some(); | ||
| let no_hash = no_hash.is_some(); | ||
| let return_result_from_ensure_ok = return_result_from_ensure_ok.is_some(); | ||
| let separate_provide_extern = separate_provide_extern.is_some(); | ||
|
|
||
| // Giving an input span to the modifier names in the modifier list seems | ||
| // to give slightly more helpful errors when one of the callback macros | ||
| // fails to parse the modifier list. | ||
| let query_name_span = query.name.span(); | ||
| quote_spanned! { | ||
| query_name_span => | ||
| // Search for (QMODLIST) to find all occurrences of this query modifier list. | ||
| // tidy-alphabetical-start | ||
| anon: #anon, | ||
| arena_cache: #arena_cache, | ||
| cache_on_disk: #cache_on_disk, | ||
| cycle_error_handling: #cycle_error_handling, | ||
| depth_limit: #depth_limit, | ||
| eval_always: #eval_always, | ||
| feedable: #feedable, | ||
| no_hash: #no_hash, | ||
| return_result_from_ensure_ok: #return_result_from_ensure_ok, | ||
| separate_provide_extern: #separate_provide_extern, | ||
| // tidy-alphabetical-end | ||
| } | ||
| } | ||
|
|
||
| fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attribute> { | ||
| use ::syn::*; | ||
| let mut iter = list.iter(); | ||
|
|
@@ -458,51 +489,13 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { | |
| ReturnType::Type(..) => quote! { #return_ty }, | ||
| }; | ||
|
|
||
| let mut modifiers_out = vec![]; | ||
|
|
||
| macro_rules! passthrough { | ||
| ( $( $modifier:ident ),+ $(,)? ) => { | ||
| $( if let Some($modifier) = &modifiers.$modifier { | ||
| modifiers_out.push(quote! { (#$modifier) }); | ||
| }; )+ | ||
| } | ||
| } | ||
|
|
||
| passthrough!( | ||
| arena_cache, | ||
| cycle_fatal, | ||
| cycle_delay_bug, | ||
| cycle_stash, | ||
| no_hash, | ||
| anon, | ||
| eval_always, | ||
| feedable, | ||
| depth_limit, | ||
| separate_provide_extern, | ||
| return_result_from_ensure_ok, | ||
| ); | ||
|
|
||
| // If there was a `cache_on_disk_if` modifier in the real input, pass | ||
| // on a synthetic `(cache_on_disk)` modifier that can be inspected by | ||
| // macro-rules macros. | ||
| if modifiers.cache_on_disk_if.is_some() { | ||
| modifiers_out.push(quote! { (cache_on_disk) }); | ||
| } | ||
|
|
||
| // This uses the span of the query definition for the commas, | ||
| // which can be important if we later encounter any ambiguity | ||
| // errors with any of the numerous macro_rules! macros that | ||
| // we use. Using the call-site span would result in a span pointing | ||
| // at the entire `rustc_queries!` invocation, which wouldn't | ||
| // be very useful. | ||
| let span = name.span(); | ||
| let modifiers_stream = quote_spanned! { span => #(#modifiers_out),* }; | ||
| let modifiers_stream = make_modifiers_stream(&query, modifiers); | ||
|
|
||
| // Add the query to the group | ||
| query_stream.extend(quote! { | ||
| #(#doc_comments)* | ||
| [#modifiers_stream] | ||
| fn #name(#key_ty) #return_ty, | ||
| fn #name(#key_ty) #return_ty | ||
| { #modifiers_stream } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was there any particular motivation behind moving the modifiers after the fn signature?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| }); | ||
|
|
||
| if let Some(feedable) = &modifiers.feedable { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had been thinking about this very change myself, thanks for doing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though there is still the comments at the top of
compiler/rustc_middle/src/queries.rs.