Skip to content
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

Preserve doc-comments when generating queries #76820

Merged
merged 1 commit into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions compiler/rustc_macros/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{
braced, parenthesized, parse_macro_input, Attribute, Block, Error, Expr, Ident, ReturnType,
Token, Type,
braced, parenthesized, parse_macro_input, AttrStyle, Attribute, Block, Error, Expr, Ident,
ReturnType, Token, Type,
};

#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -128,17 +128,25 @@ impl Parse for QueryModifier {
}

/// Ensures only doc comment attributes are used
fn check_attributes(attrs: Vec<Attribute>) -> Result<()> {
for attr in attrs {
fn check_attributes(attrs: Vec<Attribute>) -> Result<Vec<Attribute>> {
let inner = |attr: Attribute| {
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 ... { ... }`
struct Query {
doc_comments: Vec<Attribute>,
modifiers: List<QueryModifier>,
name: Ident,
key: IdentOrWild,
Expand All @@ -148,7 +156,7 @@ struct Query {

impl Parse for Query {
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>`
input.parse::<kw::query>()?;
Expand All @@ -165,7 +173,7 @@ impl Parse for Query {
braced!(content in input);
let modifiers = content.parse()?;

Ok(Query { modifiers, name, key, arg, result })
Ok(Query { doc_comments, modifiers, name, key, arg, result })
}
}

Expand Down Expand Up @@ -476,9 +484,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
};

let attribute_stream = quote! {#(#attributes),*};

let doc_comments = query.doc_comments.iter();
// Add the query to the group
group_stream.extend(quote! {
#(#doc_comments)*
[#attribute_stream] fn #name: #name(#arg) #result,
});

Expand Down
48 changes: 24 additions & 24 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,48 +42,48 @@ rustc_queries! {
}

Other {
// 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()`),
// 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.
// To avoid this fate, do not call `tcx.hir().krate()`; instead,
// prefer wrappers like `tcx.visit_all_items_in_krate()`.
/// 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()`),
/// 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.
/// To avoid this fate, do not call `tcx.hir().krate()`; instead,
/// prefer wrappers like `tcx.visit_all_items_in_krate()`.
query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
eval_always
no_hash
desc { "get the crate HIR" }
}

// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
// Avoid calling this query directly.
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
/// Avoid calling this query directly.
query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> {
eval_always
no_hash
desc { "index HIR" }
}

// The items in a module.
//
// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
// Avoid calling this query directly.
/// The items in a module.
///
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
/// Avoid calling this query directly.
query hir_module_items(key: LocalDefId) -> &'tcx hir::ModuleItems {
eval_always
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`.
//
// This can be conveniently accessed by methods on `tcx.hir()`.
// Avoid calling this query directly.
/// Gives access to the HIR node for the HIR owner `key`.
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_owner(key: LocalDefId) -> Option<&'tcx crate::hir::Owner<'tcx>> {
eval_always
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`.
//
// This can be conveniently accessed by methods on `tcx.hir()`.
// Avoid calling this query directly.
/// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx crate::hir::OwnerNodes<'tcx>> {
eval_always
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
Expand Down Expand Up @@ -305,9 +305,9 @@ rustc_queries! {
}

TypeChecking {
// Erases regions from `ty` to yield a new type.
// Normally you would just use `tcx.erase_regions(&value)`,
// however, which uses this query as a kind of cache.
/// Erases regions from `ty` to yield a new type.
/// Normally you would just use `tcx.erase_regions(&value)`,
/// however, which uses this query as a kind of cache.
query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
// This query is not expected to have input -- as a result, it
// is not a good candidates for "replay" because it is essentially a
Expand Down Expand Up @@ -1514,7 +1514,7 @@ rustc_queries! {
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>)
-> usize {
desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
Expand Down