Auto merge of #76820 - jyn514:query-comments, r=davidtwco
Preserve doc-comments when generating queries Closes https://github.com/rust-lang/rust/issues/76812
This commit is contained in:
commit
893fadd11a
2 changed files with 43 additions and 34 deletions
|
@ -5,8 +5,8 @@ use syn::parse::{Parse, ParseStream, Result};
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::{
|
use syn::{
|
||||||
braced, parenthesized, parse_macro_input, Attribute, Block, Error, Expr, Ident, ReturnType,
|
braced, parenthesized, parse_macro_input, AttrStyle, Attribute, Block, Error, Expr, Ident,
|
||||||
Token, Type,
|
ReturnType, Token, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -128,17 +128,25 @@ impl Parse for QueryModifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures only doc comment attributes are used
|
/// Ensures only doc comment attributes are used
|
||||||
fn check_attributes(attrs: Vec<Attribute>) -> Result<()> {
|
fn check_attributes(attrs: Vec<Attribute>) -> Result<Vec<Attribute>> {
|
||||||
for attr in attrs {
|
let inner = |attr: Attribute| {
|
||||||
if !attr.path.is_ident("doc") {
|
if !attr.path.is_ident("doc") {
|
||||||
return Err(Error::new(attr.span(), "attributes not supported on queries"));
|
Err(Error::new(attr.span(), "attributes not supported on queries"))
|
||||||
|
} else if attr.style != AttrStyle::Outer {
|
||||||
|
Err(Error::new(
|
||||||
|
attr.span(),
|
||||||
|
"attributes must be outer attributes (`///`), not inner attributes",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(attr)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Ok(())
|
attrs.into_iter().map(inner).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A compiler query. `query ... { ... }`
|
/// A compiler query. `query ... { ... }`
|
||||||
struct Query {
|
struct Query {
|
||||||
|
doc_comments: Vec<Attribute>,
|
||||||
modifiers: List<QueryModifier>,
|
modifiers: List<QueryModifier>,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
key: IdentOrWild,
|
key: IdentOrWild,
|
||||||
|
@ -148,7 +156,7 @@ struct Query {
|
||||||
|
|
||||||
impl Parse for Query {
|
impl Parse for Query {
|
||||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||||
check_attributes(input.call(Attribute::parse_outer)?)?;
|
let doc_comments = check_attributes(input.call(Attribute::parse_outer)?)?;
|
||||||
|
|
||||||
// Parse the query declaration. Like `query type_of(key: DefId) -> Ty<'tcx>`
|
// Parse the query declaration. Like `query type_of(key: DefId) -> Ty<'tcx>`
|
||||||
input.parse::<kw::query>()?;
|
input.parse::<kw::query>()?;
|
||||||
|
@ -165,7 +173,7 @@ impl Parse for Query {
|
||||||
braced!(content in input);
|
braced!(content in input);
|
||||||
let modifiers = content.parse()?;
|
let modifiers = content.parse()?;
|
||||||
|
|
||||||
Ok(Query { modifiers, name, key, arg, result })
|
Ok(Query { doc_comments, modifiers, name, key, arg, result })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,9 +484,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
let attribute_stream = quote! {#(#attributes),*};
|
let attribute_stream = quote! {#(#attributes),*};
|
||||||
|
let doc_comments = query.doc_comments.iter();
|
||||||
// Add the query to the group
|
// Add the query to the group
|
||||||
group_stream.extend(quote! {
|
group_stream.extend(quote! {
|
||||||
|
#(#doc_comments)*
|
||||||
[#attribute_stream] fn #name: #name(#arg) #result,
|
[#attribute_stream] fn #name: #name(#arg) #result,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -42,48 +42,48 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
Other {
|
Other {
|
||||||
// Represents crate as a whole (as distinct from the top-level crate module).
|
/// Represents crate as a whole (as distinct from the top-level crate module).
|
||||||
// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
|
/// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
|
||||||
// we will have to assume that any change means that you need to be recompiled.
|
/// we will have to assume that any change means that you need to be recompiled.
|
||||||
// This is because the `hir_crate` query gives you access to all other items.
|
/// This is because the `hir_crate` query gives you access to all other items.
|
||||||
// To avoid this fate, do not call `tcx.hir().krate()`; instead,
|
/// To avoid this fate, do not call `tcx.hir().krate()`; instead,
|
||||||
// prefer wrappers like `tcx.visit_all_items_in_krate()`.
|
/// prefer wrappers like `tcx.visit_all_items_in_krate()`.
|
||||||
query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
|
query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
|
||||||
eval_always
|
eval_always
|
||||||
no_hash
|
no_hash
|
||||||
desc { "get the crate HIR" }
|
desc { "get the crate HIR" }
|
||||||
}
|
}
|
||||||
|
|
||||||
// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
|
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
|
||||||
// Avoid calling this query directly.
|
/// Avoid calling this query directly.
|
||||||
query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> {
|
query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> {
|
||||||
eval_always
|
eval_always
|
||||||
no_hash
|
no_hash
|
||||||
desc { "index HIR" }
|
desc { "index HIR" }
|
||||||
}
|
}
|
||||||
|
|
||||||
// The items in a module.
|
/// The items in a module.
|
||||||
//
|
///
|
||||||
// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
|
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
|
||||||
// Avoid calling this query directly.
|
/// Avoid calling this query directly.
|
||||||
query hir_module_items(key: LocalDefId) -> &'tcx hir::ModuleItems {
|
query hir_module_items(key: LocalDefId) -> &'tcx hir::ModuleItems {
|
||||||
eval_always
|
eval_always
|
||||||
desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gives access to the HIR node for the HIR owner `key`.
|
/// Gives access to the HIR node for the HIR owner `key`.
|
||||||
//
|
///
|
||||||
// This can be conveniently accessed by methods on `tcx.hir()`.
|
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||||
// Avoid calling this query directly.
|
/// Avoid calling this query directly.
|
||||||
query hir_owner(key: LocalDefId) -> Option<&'tcx crate::hir::Owner<'tcx>> {
|
query hir_owner(key: LocalDefId) -> Option<&'tcx crate::hir::Owner<'tcx>> {
|
||||||
eval_always
|
eval_always
|
||||||
desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
|
/// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
|
||||||
//
|
///
|
||||||
// This can be conveniently accessed by methods on `tcx.hir()`.
|
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||||
// Avoid calling this query directly.
|
/// Avoid calling this query directly.
|
||||||
query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx crate::hir::OwnerNodes<'tcx>> {
|
query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx crate::hir::OwnerNodes<'tcx>> {
|
||||||
eval_always
|
eval_always
|
||||||
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
|
@ -334,9 +334,9 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeChecking {
|
TypeChecking {
|
||||||
// Erases regions from `ty` to yield a new type.
|
/// Erases regions from `ty` to yield a new type.
|
||||||
// Normally you would just use `tcx.erase_regions(&value)`,
|
/// Normally you would just use `tcx.erase_regions(&value)`,
|
||||||
// however, which uses this query as a kind of cache.
|
/// however, which uses this query as a kind of cache.
|
||||||
query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
|
query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
// This query is not expected to have input -- as a result, it
|
// This query is not expected to have input -- as a result, it
|
||||||
// is not a good candidates for "replay" because it is essentially a
|
// is not a good candidates for "replay" because it is essentially a
|
||||||
|
@ -1538,7 +1538,7 @@ rustc_queries! {
|
||||||
desc { "looking up supported target features" }
|
desc { "looking up supported target features" }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
|
/// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
|
||||||
query instance_def_size_estimate(def: ty::InstanceDef<'tcx>)
|
query instance_def_size_estimate(def: ty::InstanceDef<'tcx>)
|
||||||
-> usize {
|
-> usize {
|
||||||
desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
|
desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue