diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2021-03-15 16:22:52 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-15 16:22:52 +0100 |
| commit | 75a15bf2757d372d7511bed70e1ad2c5814a1012 (patch) | |
| tree | 20cc799c22168d37739d1d5ebe3d5a5caa2b4f1d /compiler | |
| parent | b8622f2b3bad72a3f4fd5fb6de88b55e04017c55 (diff) | |
| parent | 8f40e1180f65bdf7e88baa4bcc03d24baded9fca (diff) | |
| download | rust-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.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 110 |
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. |
