about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-24 13:01:46 +0000
committerbors <bors@rust-lang.org>2020-09-24 13:01:46 +0000
commit893fadd11a52aa26fc19c67ee1b79f03d6a1bed3 (patch)
treee6c915bbd8db951ad547f07f20211b9e6a420091 /compiler
parent3a4da87f58099f08620a9a3e812abd77301cafb2 (diff)
parent2f1bfd6399cfe439fbf2e446beafa5c55d1bb843 (diff)
downloadrust-893fadd11a52aa26fc19c67ee1b79f03d6a1bed3.tar.gz
rust-893fadd11a52aa26fc19c67ee1b79f03d6a1bed3.zip
Auto merge of #76820 - jyn514:query-comments, r=davidtwco
Preserve doc-comments when generating queries

Closes https://github.com/rust-lang/rust/issues/76812
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_macros/src/query.rs29
-rw-r--r--compiler/rustc_middle/src/query/mod.rs48
2 files changed, 43 insertions, 34 deletions
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 95096ef3fc4..204e8e800cd 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -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)]
@@ -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,
@@ -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>()?;
@@ -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 })
     }
 }
 
@@ -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,
             });
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 33854432af5..428baefe278 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -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()) }
@@ -334,9 +334,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
@@ -1538,7 +1538,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()) }