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
This commit is contained in:
Dylan DPC 2021-03-15 16:22:52 +01:00 committed by GitHub
commit 75a15bf275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 195 additions and 55 deletions

View File

@ -4247,6 +4247,7 @@ name = "rustc_passes"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"rustc_ast", "rustc_ast",
"rustc_ast_pretty",
"rustc_attr", "rustc_attr",
"rustc_data_structures", "rustc_data_structures",
"rustc_errors", "rustc_errors",

View File

@ -19,3 +19,4 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_lexer = { path = "../rustc_lexer" } rustc_lexer = { path = "../rustc_lexer" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }

View File

@ -524,7 +524,7 @@ impl CheckAttrVisitor<'tcx> {
.struct_span_err( .struct_span_err(
meta.span(), meta.span(),
&format!( &format!(
"`#![doc({} = \"...\")]` isn't allowed as a crate level attribute", "`#![doc({} = \"...\")]` isn't allowed as a crate-level attribute",
attr_name, attr_name,
), ),
) )
@ -535,79 +535,97 @@ impl CheckAttrVisitor<'tcx> {
} }
fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool { fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
if let Some(mi) = attr.meta() { let mut is_valid = true;
if let Some(list) = mi.meta_item_list() {
for meta in list { if let Some(list) = attr.meta().and_then(|mi| mi.meta_item_list().map(|l| l.to_vec())) {
if meta.has_name(sym::alias) { for meta in list {
if !self.check_attr_crate_level(meta, hir_id, "alias") if let Some(i_meta) = meta.meta_item() {
|| !self.check_doc_alias(meta, hir_id, target) 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") sym::keyword
|| !self.check_doc_keyword(meta, hir_id) 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( self.tcx.struct_span_lint_hir(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
meta.span(), meta.span(),
|lint| { |lint| {
lint.build( lint.build(
"`#![doc(test(...)]` is only allowed as a crate level attribute" "`#![doc(test(...)]` is only allowed \
as a crate-level attribute",
) )
.emit(); .emit();
}, },
); );
return false; is_valid = false;
} }
} else if let Some(i_meta) = meta.meta_item() {
if ![ // no_default_passes: deprecated
sym::cfg, // passes: deprecated
sym::hidden, // plugins: removed, but rustdoc warns about it itself
sym::html_favicon_url, sym::alias
sym::html_logo_url, | sym::cfg
sym::html_no_source, | sym::hidden
sym::html_playground_url, | sym::html_favicon_url
sym::html_root_url, | sym::html_logo_url
sym::include, | sym::html_no_source
sym::inline, | sym::html_playground_url
sym::issue_tracker_base_url, | sym::html_root_url
sym::masked, | sym::include
sym::no_default_passes, // deprecated | sym::inline
sym::no_inline, | sym::issue_tracker_base_url
sym::passes, // deprecated | sym::keyword
sym::plugins, // removed, but rustdoc warns about it itself | sym::masked
sym::primitive, | sym::no_default_passes
sym::spotlight, | sym::no_inline
sym::test, | sym::passes
] | sym::plugins
.iter() | sym::primitive
.any(|m| i_meta.has_name(*m)) | sym::spotlight
{ | sym::test => {}
_ => {
self.tcx.struct_span_lint_hir( self.tcx.struct_span_lint_hir(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
i_meta.span, i_meta.span,
|lint| { |lint| {
lint.build(&format!( let msg = format!(
"unknown `doc` attribute `{}`", "unknown `doc` attribute `{}`",
i_meta.name_or_empty() rustc_ast_pretty::pprust::path_to_string(&i_meta.path),
)) );
.emit(); 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. /// Checks if `#[cold]` is applied to a non-function. Returns `true` if valid.

View File

@ -4,7 +4,7 @@ error: '\'' character isn't allowed in `#[doc(alias = "...")]`
LL | #[doc(alias = "shouldn't work!")] LL | #[doc(alias = "shouldn't work!")]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute
--> $DIR/doc-alias-crate-level.rs:1:8 --> $DIR/doc-alias-crate-level.rs:1:8
| |
LL | #![doc(alias = "crate-level-not-working")] LL | #![doc(alias = "crate-level-not-working")]

View File

@ -8,3 +8,18 @@
//~^ ERROR unknown `doc` attribute //~^ ERROR unknown `doc` attribute
//~^^ WARN //~^^ WARN
pub fn foo() {} pub fn foo() {}
#[doc(123)]
//~^ ERROR invalid `doc` attribute
//~| WARN
#[doc("hello", "bar")]
//~^ ERROR invalid `doc` attribute
//~| WARN
//~| ERROR invalid `doc` attribute
//~| WARN
#[doc(foo::bar, crate::bar::baz = "bye")]
//~^ ERROR unknown `doc` attribute
//~| WARN
//~| ERROR unknown `doc` attribute
//~| WARN
fn bar() {}

View File

@ -13,6 +13,51 @@ LL | #![deny(warnings)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: invalid `doc` attribute
--> $DIR/doc-attr.rs:12:7
|
LL | #[doc(123)]
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: invalid `doc` attribute
--> $DIR/doc-attr.rs:15:7
|
LL | #[doc("hello", "bar")]
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: invalid `doc` attribute
--> $DIR/doc-attr.rs:15:16
|
LL | #[doc("hello", "bar")]
| ^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: unknown `doc` attribute `foo::bar`
--> $DIR/doc-attr.rs:20:7
|
LL | #[doc(foo::bar, crate::bar::baz = "bye")]
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: unknown `doc` attribute `crate::bar::baz`
--> $DIR/doc-attr.rs:20:17
|
LL | #[doc(foo::bar, crate::bar::baz = "bye")]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: unknown `doc` attribute `as_ptr` error: unknown `doc` attribute `as_ptr`
--> $DIR/doc-attr.rs:3:8 --> $DIR/doc-attr.rs:3:8
| |
@ -22,5 +67,5 @@ LL | #![doc(as_ptr)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: aborting due to 2 previous errors error: aborting due to 7 previous errors

View File

@ -1,4 +1,4 @@
error: `#![doc(test(...)]` is only allowed as a crate level attribute error: `#![doc(test(...)]` is only allowed as a crate-level attribute
--> $DIR/doc-attr2.rs:4:7 --> $DIR/doc-attr2.rs:4:7
| |
LL | #[doc(test(no_crate_inject))] LL | #[doc(test(no_crate_inject))]
@ -13,7 +13,7 @@ LL | #![deny(warnings)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: `#![doc(test(...)]` is only allowed as a crate level attribute error: `#![doc(test(...)]` is only allowed as a crate-level attribute
--> $DIR/doc-attr2.rs:9:12 --> $DIR/doc-attr2.rs:9:12
| |
LL | #![doc(test(no_crate_inject))] LL | #![doc(test(no_crate_inject))]

View File

@ -8,3 +8,18 @@
//~^ ERROR unknown `doc` attribute //~^ ERROR unknown `doc` attribute
//~^^ WARN //~^^ WARN
pub fn foo() {} pub fn foo() {}
#[doc(123)]
//~^ ERROR invalid `doc` attribute
//~| WARN
#[doc("hello", "bar")]
//~^ ERROR invalid `doc` attribute
//~| WARN
//~| ERROR invalid `doc` attribute
//~| WARN
#[doc(foo::bar, crate::bar::baz = "bye")]
//~^ ERROR unknown `doc` attribute
//~| WARN
//~| ERROR unknown `doc` attribute
//~| WARN
fn bar() {}

View File

@ -13,6 +13,51 @@ LL | #![deny(warnings)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: invalid `doc` attribute
--> $DIR/doc-attr.rs:12:7
|
LL | #[doc(123)]
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: invalid `doc` attribute
--> $DIR/doc-attr.rs:15:7
|
LL | #[doc("hello", "bar")]
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: invalid `doc` attribute
--> $DIR/doc-attr.rs:15:16
|
LL | #[doc("hello", "bar")]
| ^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: unknown `doc` attribute `foo::bar`
--> $DIR/doc-attr.rs:20:7
|
LL | #[doc(foo::bar, crate::bar::baz = "bye")]
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: unknown `doc` attribute `crate::bar::baz`
--> $DIR/doc-attr.rs:20:17
|
LL | #[doc(foo::bar, crate::bar::baz = "bye")]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: unknown `doc` attribute `as_ptr` error: unknown `doc` attribute `as_ptr`
--> $DIR/doc-attr.rs:3:8 --> $DIR/doc-attr.rs:3:8
| |
@ -22,5 +67,5 @@ LL | #![doc(as_ptr)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: aborting due to 2 previous errors error: aborting due to 7 previous errors

View File

@ -1,4 +1,4 @@
error: `#![doc(test(...)]` is only allowed as a crate level attribute error: `#![doc(test(...)]` is only allowed as a crate-level attribute
--> $DIR/doc-attr2.rs:4:7 --> $DIR/doc-attr2.rs:4:7
| |
LL | #[doc(test(no_crate_inject))] LL | #[doc(test(no_crate_inject))]
@ -13,7 +13,7 @@ LL | #![deny(warnings)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
error: `#![doc(test(...)]` is only allowed as a crate level attribute error: `#![doc(test(...)]` is only allowed as a crate-level attribute
--> $DIR/doc-attr2.rs:9:12 --> $DIR/doc-attr2.rs:9:12
| |
LL | #![doc(test(no_crate_inject))] LL | #![doc(test(no_crate_inject))]

View File

@ -4,7 +4,7 @@ error: '\'' character isn't allowed in `#[doc(alias = "...")]`
LL | #[doc(alias = "shouldn't work!")] LL | #[doc(alias = "shouldn't work!")]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute
--> $DIR/doc-alias-crate-level.rs:5:8 --> $DIR/doc-alias-crate-level.rs:5:8
| |
LL | #![doc(alias = "not working!")] LL | #![doc(alias = "not working!")]

View File

@ -10,7 +10,7 @@ error: `#[doc(keyword = "...")]` can only be used on modules
LL | #[doc(keyword = "hall")] LL | #[doc(keyword = "hall")]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: `#![doc(keyword = "...")]` isn't allowed as a crate level attribute error: `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute
--> $DIR/doc_keyword.rs:4:8 --> $DIR/doc_keyword.rs:4:8
| |
LL | #![doc(keyword = "hello")] LL | #![doc(keyword = "hello")]