about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-03-15 16:22:52 +0100
committerGitHub <noreply@github.com>2021-03-15 16:22:52 +0100
commit75a15bf2757d372d7511bed70e1ad2c5814a1012 (patch)
tree20cc799c22168d37739d1d5ebe3d5a5caa2b4f1d /compiler
parentb8622f2b3bad72a3f4fd5fb6de88b55e04017c55 (diff)
parent8f40e1180f65bdf7e88baa4bcc03d24baded9fca (diff)
downloadrust-75a15bf2757d372d7511bed70e1ad2c5814a1012.tar.gz
rust-75a15bf2757d372d7511bed70e1ad2c5814a1012.zip
Rollup merge of #83098 - camelid:more-doc-attr-check, r=davidtwco
Find more invalid doc attributes

- Lint on `#[doc(123)]`, `#[doc("hello")]`, etc.
- Lint every attribute; e.g., will now report two warnings for `#[doc(foo, bar)]`
- Add hyphen to "crate level"
- Display paths like `#[doc(foo::bar)]` correctly instead of as an empty string
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_passes/Cargo.toml1
-rw-r--r--compiler/rustc_passes/src/check_attr.rs110
2 files changed, 65 insertions, 46 deletions
diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml
index c87799f1c2a..4069fb2127e 100644
--- a/compiler/rustc_passes/Cargo.toml
+++ b/compiler/rustc_passes/Cargo.toml
@@ -19,3 +19,4 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_lexer = { path = "../rustc_lexer" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ae8883754d6..9c606f3e4d4 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -524,7 +524,7 @@ impl CheckAttrVisitor<'tcx> {
                 .struct_span_err(
                     meta.span(),
                     &format!(
-                        "`#![doc({} = \"...\")]` isn't allowed as a crate level attribute",
+                        "`#![doc({} = \"...\")]` isn't allowed as a crate-level attribute",
                         attr_name,
                     ),
                 )
@@ -535,79 +535,97 @@ impl CheckAttrVisitor<'tcx> {
     }
 
     fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
-        if let Some(mi) = attr.meta() {
-            if let Some(list) = mi.meta_item_list() {
-                for meta in list {
-                    if meta.has_name(sym::alias) {
-                        if !self.check_attr_crate_level(meta, hir_id, "alias")
-                            || !self.check_doc_alias(meta, hir_id, target)
+        let mut is_valid = true;
+
+        if let Some(list) = attr.meta().and_then(|mi| mi.meta_item_list().map(|l| l.to_vec())) {
+            for meta in list {
+                if let Some(i_meta) = meta.meta_item() {
+                    match i_meta.name_or_empty() {
+                        sym::alias
+                            if !self.check_attr_crate_level(&meta, hir_id, "alias")
+                                || !self.check_doc_alias(&meta, hir_id, target) =>
                         {
-                            return false;
+                            is_valid = false
                         }
-                    } else if meta.has_name(sym::keyword) {
-                        if !self.check_attr_crate_level(meta, hir_id, "keyword")
-                            || !self.check_doc_keyword(meta, hir_id)
+
+                        sym::keyword
+                            if !self.check_attr_crate_level(&meta, hir_id, "keyword")
+                                || !self.check_doc_keyword(&meta, hir_id) =>
                         {
-                            return false;
+                            is_valid = false
                         }
-                    } else if meta.has_name(sym::test) {
-                        if CRATE_HIR_ID != hir_id {
+
+                        sym::test if CRATE_HIR_ID != hir_id => {
                             self.tcx.struct_span_lint_hir(
                                 INVALID_DOC_ATTRIBUTES,
                                 hir_id,
                                 meta.span(),
                                 |lint| {
                                     lint.build(
-                                        "`#![doc(test(...)]` is only allowed as a crate level attribute"
+                                        "`#![doc(test(...)]` is only allowed \
+                                         as a crate-level attribute",
                                     )
                                     .emit();
                                 },
                             );
-                            return false;
+                            is_valid = false;
                         }
-                    } else if let Some(i_meta) = meta.meta_item() {
-                        if ![
-                            sym::cfg,
-                            sym::hidden,
-                            sym::html_favicon_url,
-                            sym::html_logo_url,
-                            sym::html_no_source,
-                            sym::html_playground_url,
-                            sym::html_root_url,
-                            sym::include,
-                            sym::inline,
-                            sym::issue_tracker_base_url,
-                            sym::masked,
-                            sym::no_default_passes, // deprecated
-                            sym::no_inline,
-                            sym::passes,  // deprecated
-                            sym::plugins, // removed, but rustdoc warns about it itself
-                            sym::primitive,
-                            sym::spotlight,
-                            sym::test,
-                        ]
-                        .iter()
-                        .any(|m| i_meta.has_name(*m))
-                        {
+
+                        // no_default_passes: deprecated
+                        // passes: deprecated
+                        // plugins: removed, but rustdoc warns about it itself
+                        sym::alias
+                        | sym::cfg
+                        | sym::hidden
+                        | sym::html_favicon_url
+                        | sym::html_logo_url
+                        | sym::html_no_source
+                        | sym::html_playground_url
+                        | sym::html_root_url
+                        | sym::include
+                        | sym::inline
+                        | sym::issue_tracker_base_url
+                        | sym::keyword
+                        | sym::masked
+                        | sym::no_default_passes
+                        | sym::no_inline
+                        | sym::passes
+                        | sym::plugins
+                        | sym::primitive
+                        | sym::spotlight
+                        | sym::test => {}
+
+                        _ => {
                             self.tcx.struct_span_lint_hir(
                                 INVALID_DOC_ATTRIBUTES,
                                 hir_id,
                                 i_meta.span,
                                 |lint| {
-                                    lint.build(&format!(
+                                    let msg = format!(
                                         "unknown `doc` attribute `{}`",
-                                        i_meta.name_or_empty()
-                                    ))
-                                    .emit();
+                                        rustc_ast_pretty::pprust::path_to_string(&i_meta.path),
+                                    );
+                                    lint.build(&msg).emit();
                                 },
                             );
-                            return false;
+                            is_valid = false;
                         }
                     }
+                } else {
+                    self.tcx.struct_span_lint_hir(
+                        INVALID_DOC_ATTRIBUTES,
+                        hir_id,
+                        meta.span(),
+                        |lint| {
+                            lint.build(&format!("invalid `doc` attribute")).emit();
+                        },
+                    );
+                    is_valid = false;
                 }
             }
         }
-        true
+
+        is_valid
     }
 
     /// Checks if `#[cold]` is applied to a non-function. Returns `true` if valid.