diff options
Diffstat (limited to 'compiler/rustc_macros/src')
| -rw-r--r-- | compiler/rustc_macros/src/hash_stable.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/query.rs | 83 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/session_diagnostic.rs | 8 |
3 files changed, 54 insertions, 45 deletions
diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index 63bdcea87f8..dba885a27fe 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs @@ -24,9 +24,11 @@ fn parse_attributes(field: &syn::Field) -> Attributes { } if meta.path().is_ident("project") { if let Meta::List(list) = meta { - if let Some(NestedMeta::Meta(meta)) = list.nested.iter().next() { - attrs.project = meta.path().get_ident().cloned(); - any_attr = true; + if let Some(nested) = list.nested.iter().next() { + if let NestedMeta::Meta(meta) = nested { + attrs.project = meta.path().get_ident().cloned(); + any_attr = true; + } } } } diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 005017185c1..6dbba274360 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -36,7 +36,7 @@ enum QueryModifier { Storage(Type), /// Cache the query to disk if the `Expr` returns true. - Cache(Option<(IdentOrWild, IdentOrWild)>, Block), + Cache(Option<IdentOrWild>, Block), /// Custom code to load the query from disk. LoadCached(Ident, Ident, Block), @@ -55,6 +55,9 @@ enum QueryModifier { /// Always evaluate the query, ignoring its dependencies EvalAlways(Ident), + + /// Use a separate query provider for local and extern crates + SeparateProvideExtern(Ident), } impl Parse for QueryModifier { @@ -87,9 +90,7 @@ impl Parse for QueryModifier { let args; parenthesized!(args in input); let tcx = args.parse()?; - args.parse::<Token![,]>()?; - let value = args.parse()?; - Some((tcx, value)) + Some(tcx) } else { None }; @@ -120,6 +121,8 @@ impl Parse for QueryModifier { Ok(QueryModifier::Anon(modifier)) } else if modifier == "eval_always" { Ok(QueryModifier::EvalAlways(modifier)) + } else if modifier == "separate_provide_extern" { + Ok(QueryModifier::SeparateProvideExtern(modifier)) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -197,7 +200,7 @@ struct QueryModifiers { storage: Option<Type>, /// Cache the query to disk if the `Block` returns true. - cache: Option<(Option<(IdentOrWild, IdentOrWild)>, Block)>, + cache: Option<(Option<IdentOrWild>, Block)>, /// Custom code to load the query from disk. load_cached: Option<(Ident, Ident, Block)>, @@ -216,6 +219,9 @@ struct QueryModifiers { // Always evaluate the query, ignoring its dependencies eval_always: Option<Ident>, + + /// Use a separate query provider for local and extern crates + separate_provide_extern: Option<Ident>, } /// Process query modifiers into a struct, erroring on duplicates @@ -229,6 +235,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut no_hash = None; let mut anon = None; let mut eval_always = None; + let mut separate_provide_extern = None; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -319,6 +326,15 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } eval_always = Some(ident); } + QueryModifier::SeparateProvideExtern(ident) => { + if separate_provide_extern.is_some() { + panic!( + "duplicate modifier `separate_provide_extern` for query `{}`", + query.name + ); + } + separate_provide_extern = Some(ident); + } } } let desc = desc.unwrap_or_else(|| { @@ -334,6 +350,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { no_hash, anon, eval_always, + separate_provide_extern, } } @@ -351,51 +368,30 @@ fn add_query_description_impl( let try_load_from_disk = if let Some((tcx, id, block)) = modifiers.load_cached.as_ref() { // Use custom code to load the query from disk quote! { - #[inline] - fn try_load_from_disk( - #tcx: QueryCtxt<'tcx>, - #id: SerializedDepNodeIndex - ) -> Option<Self::Value> { - #block - } + const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>> + = Some(|#tcx, #id| { #block }); } } else { // Use the default code to load the query from disk quote! { - #[inline] - fn try_load_from_disk( - tcx: QueryCtxt<'tcx>, - id: SerializedDepNodeIndex - ) -> Option<Self::Value> { - tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id) - } + const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>> + = Some(|tcx, id| tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id)); } }; let tcx = args .as_ref() .map(|t| { - let t = &(t.0).0; - quote! { #t } - }) - .unwrap_or_else(|| quote! { _ }); - let value = args - .as_ref() - .map(|t| { - let t = &(t.1).0; + let t = &t.0; quote! { #t } }) .unwrap_or_else(|| quote! { _ }); // expr is a `Block`, meaning that `{ #expr }` gets expanded // to `{ { stmts... } }`, which triggers the `unused_braces` lint. quote! { - #[inline] #[allow(unused_variables, unused_braces)] - fn cache_on_disk( - #tcx: QueryCtxt<'tcx>, - #key: &Self::Key, - #value: Option<&Self::Value> - ) -> bool { + #[inline] + fn cache_on_disk(#tcx: TyCtxt<'tcx>, #key: &Self::Key) -> bool { #expr } @@ -405,7 +401,14 @@ fn add_query_description_impl( if modifiers.load_cached.is_some() { panic!("load_cached modifier on query `{}` without a cache modifier", name); } - quote! {} + quote! { + #[inline] + fn cache_on_disk(_: TyCtxt<'tcx>, _: &Self::Key) -> bool { + false + } + + const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>> = None; + } }; let (tcx, desc) = modifiers.desc; @@ -413,17 +416,17 @@ fn add_query_description_impl( let desc = quote! { #[allow(unused_variables)] - fn describe(tcx: QueryCtxt<'tcx>, key: Self::Key) -> String { + fn describe(tcx: QueryCtxt<$tcx>, key: Self::Key) -> String { let (#tcx, #key) = (*tcx, key); ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into()) } }; impls.extend(quote! { - impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::#name<'tcx> { + (#name<$tcx:tt>) => { #desc #cache - } + }; }); } @@ -478,6 +481,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { if let Some(eval_always) = &modifiers.eval_always { attributes.push(quote! { (#eval_always) }); }; + // Pass on the separate_provide_extern modifier + if let Some(separate_provide_extern) = &modifiers.separate_provide_extern { + attributes.push(quote! { (#separate_provide_extern) }); + } // This uses the span of the query definition for the commas, // which can be important if we later encounter any ambiguity @@ -531,7 +538,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { } #[macro_export] macro_rules! rustc_query_description { - () => { #query_description_stream } + #query_description_stream } }) } diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index c8959dc86ad..80dcf99da62 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -349,14 +349,14 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> { let field_binding = &info.binding.binding; - let option_ty = option_inner_ty(info.ty); + let option_ty = option_inner_ty(&info.ty); let generated_code = self.generate_non_option_field_code( attr, FieldInfo { vis: info.vis, binding: info.binding, - ty: option_ty.unwrap_or(info.ty), + ty: option_ty.unwrap_or(&info.ty), span: info.span, }, )?; @@ -388,7 +388,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { let formatted_str = self.build_format(&s.value(), attr.span()); match name { "message" => { - if type_matches_path(info.ty, &["rustc_span", "Span"]) { + if type_matches_path(&info.ty, &["rustc_span", "Span"]) { quote! { #diag.set_span(*#field_binding); #diag.set_primary_message(#formatted_str); @@ -401,7 +401,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { } } "label" => { - if type_matches_path(info.ty, &["rustc_span", "Span"]) { + if type_matches_path(&info.ty, &["rustc_span", "Span"]) { quote! { #diag.span_label(*#field_binding, #formatted_str); } |
