Emit invalid_doc_attributes warnings in more cases

This commit is contained in:
LeSeulArtichaut 2021-05-08 16:25:00 +02:00
parent 50e1dc1536
commit 245f582139
5 changed files with 169 additions and 49 deletions

View file

@ -8,7 +8,7 @@ use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_ast::{Attribute, Lit, LitKind, NestedMetaItem};
use rustc_ast::{AttrStyle, Attribute, Lit, LitKind, NestedMetaItem};
use rustc_errors::{pluralize, struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
@ -564,7 +564,7 @@ impl CheckAttrVisitor<'tcx> {
true
}
fn check_attr_crate_level(
fn check_attr_not_crate_level(
&self,
meta: &NestedMetaItem,
hir_id: HirId,
@ -586,6 +586,48 @@ impl CheckAttrVisitor<'tcx> {
true
}
fn check_attr_crate_level(
&self,
attr: &Attribute,
meta: &NestedMetaItem,
hir_id: HirId,
) -> bool {
if hir_id != CRATE_HIR_ID {
self.tcx.struct_span_lint_hir(
INVALID_DOC_ATTRIBUTES,
hir_id,
meta.span(),
|lint| {
let mut err = lint.build(
"this attribute can only be applied at the crate level",
);
if attr.style == AttrStyle::Outer && self.tcx.hir().get_parent_item(hir_id) == CRATE_HIR_ID {
if let Ok(mut src) =
self.tcx.sess.source_map().span_to_snippet(attr.span)
{
src.insert(1, '!');
err.span_suggestion_verbose(
attr.span,
"to apply to the crate, use an inner attribute",
src,
Applicability::MaybeIncorrect,
);
} else {
err.span_help(
attr.span,
"to apply to the crate, use an inner attribute",
);
}
}
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information")
.emit();
},
);
return false;
}
true
}
fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
let mut is_valid = true;
@ -594,35 +636,58 @@ impl CheckAttrVisitor<'tcx> {
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")
if !self.check_attr_not_crate_level(&meta, hir_id, "alias")
|| !self.check_doc_alias(&meta, hir_id, target) =>
{
is_valid = false
}
sym::keyword
if !self.check_attr_crate_level(&meta, hir_id, "keyword")
if !self.check_attr_not_crate_level(&meta, hir_id, "keyword")
|| !self.check_doc_keyword(&meta, hir_id) =>
{
is_valid = false
}
sym::test if CRATE_HIR_ID != hir_id => {
sym::html_favicon_url
| sym::html_logo_url
| sym::html_playground_url
| sym::issue_tracker_base_url
| sym::html_root_url
| sym::html_no_source
| sym::test
if !self.check_attr_crate_level(&attr, &meta, hir_id) =>
{
is_valid = false;
}
sym::inline | sym::no_inline if target != Target::Use => {
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",
)
.emit();
let mut err = lint.build(
"this attribute can only be applied to a `use` item",
);
err.span_label(meta.span(), "only applicable on `use` items");
if attr.style == AttrStyle::Outer {
err.span_label(
self.tcx.hir().span(hir_id),
"not a `use` item",
);
}
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information")
.emit();
},
);
is_valid = false;
}
sym::inline | sym::no_inline => {
// FIXME(#80275): conflicting inline attributes
}
// no_default_passes: deprecated
// passes: deprecated
// plugins: removed, but rustdoc warns about it itself
@ -635,12 +700,10 @@ impl CheckAttrVisitor<'tcx> {
| 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::notable_trait
| sym::passes
| sym::plugins

View file

@ -1,11 +0,0 @@
#![crate_type = "lib"]
#![deny(warnings)]
#[doc(test(no_crate_inject))] //~ ERROR
//~^ WARN
pub fn foo() {}
pub mod bar {
#![doc(test(no_crate_inject))] //~ ERROR
//~^ WARN
}

View file

@ -1,26 +0,0 @@
error: `#![doc(test(...)]` is only allowed as a crate-level attribute
--> $DIR/doc-attr2.rs:4:7
|
LL | #[doc(test(no_crate_inject))]
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/doc-attr2.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(invalid_doc_attributes)]` implied by `#[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!
= 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
--> $DIR/doc-attr2.rs:9:12
|
LL | #![doc(test(no_crate_inject))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= 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: aborting due to 2 previous errors

View file

@ -0,0 +1,26 @@
#![crate_type = "lib"]
#![deny(warnings)]
#[doc(test(no_crate_inject))]
//~^ ERROR can only be applied at the crate level
//~| WARN is being phased out
//~| HELP to apply to the crate, use an inner attribute
//~| SUGGESTION #![doc(test(no_crate_inject))]
#[doc(inline)]
//~^ ERROR can only be applied to a `use` item
//~| WARN is being phased out
pub fn foo() {}
pub mod bar {
#![doc(test(no_crate_inject))]
//~^ ERROR can only be applied at the crate level
//~| WARN is being phased out
#[doc(test(no_crate_inject))]
//~^ ERROR can only be applied at the crate level
//~| WARN is being phased out
#[doc(inline)]
//~^ ERROR can only be applied to a `use` item
//~| WARN is being phased out
pub fn baz() {}
}

View file

@ -0,0 +1,68 @@
error: this attribute can only be applied at the crate level
--> $DIR/invalid-doc-attr.rs:4:7
|
LL | #[doc(test(no_crate_inject))]
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/invalid-doc-attr.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(invalid_doc_attributes)]` implied by `#[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!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
help: to apply to the crate, use an inner attribute
|
LL | #![doc(test(no_crate_inject))]
|
error: this attribute can only be applied to a `use` item
--> $DIR/invalid-doc-attr.rs:9:7
|
LL | #[doc(inline)]
| ^^^^^^ only applicable on `use` items
...
LL | pub fn foo() {}
| ------------ not a `use` item
|
= 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: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
error: this attribute can only be applied at the crate level
--> $DIR/invalid-doc-attr.rs:15:12
|
LL | #![doc(test(no_crate_inject))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= 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: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
error: this attribute can only be applied at the crate level
--> $DIR/invalid-doc-attr.rs:19:11
|
LL | #[doc(test(no_crate_inject))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= 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: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
error: this attribute can only be applied to a `use` item
--> $DIR/invalid-doc-attr.rs:22:11
|
LL | #[doc(inline)]
| ^^^^^^ only applicable on `use` items
...
LL | pub fn baz() {}
| ------------ not a `use` item
|
= 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: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
error: aborting due to 5 previous errors