about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-12-04 03:30:19 +0100
committerGitHub <noreply@github.com>2020-12-04 03:30:19 +0100
commitf4060521a951a7457ce59009486e2f12bce9bde1 (patch)
tree1da08ceb45db9dd567a1fb80ef12e708d5556b4b
parent6f2fbc1613489e300cf22e18219651dbcada140e (diff)
parent50eb3a89f8e2a4c1d809d2b0170b0063b9338d6d (diff)
downloadrust-f4060521a951a7457ce59009486e2f12bce9bde1.tar.gz
rust-f4060521a951a7457ce59009486e2f12bce9bde1.zip
Rollup merge of #79541 - GuillaumeGomez:doc-keyword-lint-pass, r=lcnr
Doc keyword lint pass

`x.py test` doesn't seem to work locally for multiple reasons so simpler to just run CI...
-rw-r--r--compiler/rustc_lint/src/internal.rs46
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--src/test/ui-fulldeps/internal-lints/existing_doc_keyword.rs11
-rw-r--r--src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr15
5 files changed, 75 insertions, 1 deletions
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index c2d98b8e4ad..af5972c6c81 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -10,7 +10,7 @@ use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath,
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::hygiene::{ExpnKind, MacroKind};
-use rustc_span::symbol::{sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 
 declare_tool_lint! {
     pub rustc::DEFAULT_HASH_TYPES,
@@ -267,3 +267,47 @@ impl EarlyLintPass for LintPassImpl {
         }
     }
 }
+
+declare_tool_lint! {
+    pub rustc::EXISTING_DOC_KEYWORD,
+    Allow,
+    "Check that documented keywords in std and core actually exist",
+    report_in_external_macro: true
+}
+
+declare_lint_pass!(ExistingDocKeyword => [EXISTING_DOC_KEYWORD]);
+
+fn is_doc_keyword(s: Symbol) -> bool {
+    s <= kw::Union
+}
+
+impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
+    fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) {
+        for attr in item.attrs {
+            if !attr.has_name(sym::doc) {
+                continue;
+            }
+            if let Some(list) = attr.meta_item_list() {
+                for nested in list {
+                    if nested.has_name(sym::keyword) {
+                        let v = nested
+                            .value_str()
+                            .expect("#[doc(keyword = \"...\")] expected a value!");
+                        if is_doc_keyword(v) {
+                            return;
+                        }
+                        cx.struct_span_lint(EXISTING_DOC_KEYWORD, attr.span, |lint| {
+                            lint.build(&format!(
+                                "Found non-existing keyword `{}` used in \
+                                     `#[doc(keyword = \"...\")]`",
+                                v,
+                            ))
+                            .help("only existing keywords are allowed in core/std")
+                            .emit();
+                        });
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 81549be4b09..80ef855c385 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -463,6 +463,8 @@ fn register_internals(store: &mut LintStore) {
     store.register_early_pass(|| box DefaultHashTypes::new());
     store.register_lints(&LintPassImpl::get_lints());
     store.register_early_pass(|| box LintPassImpl);
+    store.register_lints(&ExistingDocKeyword::get_lints());
+    store.register_late_pass(|| box ExistingDocKeyword);
     store.register_lints(&TyTyKind::get_lints());
     store.register_late_pass(|| box TyTyKind);
     store.register_group(
@@ -475,6 +477,7 @@ fn register_internals(store: &mut LintStore) {
             LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
             LintId::of(TY_PASS_BY_REFERENCE),
             LintId::of(USAGE_OF_QUALIFIED_TY),
+            LintId::of(EXISTING_DOC_KEYWORD),
         ],
     );
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 83eb847697d..6c240cb4c3e 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -212,6 +212,7 @@
     all(target_vendor = "fortanix", target_env = "sgx"),
     feature(slice_index_methods, coerce_unsized, sgx_platform)
 )]
+#![deny(rustc::existing_doc_keyword)]
 #![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"), feature(fixed_size_array))]
 // std is implemented with unstable features, many of which are internal
 // compiler details that will never be stable
diff --git a/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.rs b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.rs
new file mode 100644
index 00000000000..053712a4b4e
--- /dev/null
+++ b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![feature(doc_keyword)]
+
+#![crate_type = "lib"]
+
+#![deny(rustc::existing_doc_keyword)]
+
+#[doc(keyword = "tadam")] //~ ERROR
+mod tadam {}
diff --git a/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
new file mode 100644
index 00000000000..bac44f338b7
--- /dev/null
+++ b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
@@ -0,0 +1,15 @@
+error: Found non-existing keyword `tadam` used in `#[doc(keyword = "...")]`
+  --> $DIR/existing_doc_keyword.rs:10:1
+   |
+LL | #[doc(keyword = "tadam")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/existing_doc_keyword.rs:8:9
+   |
+LL | #![deny(rustc::existing_doc_keyword)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: only existing keywords are allowed in core/std
+
+error: aborting due to previous error
+