Rollup merge of #82708 - GuillaumeGomez:doc-test-attr-check, r=Manishearth

Warn on `#![doc(test(...))]` on items other than the crate root and use future incompatible lint

Part of #82672.

This PR does multiple things:
 * Create a new `INVALID_DOC_ATTRIBUTE` lint which is also "future incompatible", allowing us to use it as a warning for the moment until it turns (eventually) into a hard error.
 * Use this link when `#![doc(test(...))]` isn't used at the crate level.
 * Make #82702 use this new lint as well.

r? ``@jyn514``
This commit is contained in:
Guillaume Gomez 2021-03-05 21:44:38 +01:00 committed by GitHub
commit 8867f7f650
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 143 additions and 23 deletions

View file

@ -3059,3 +3059,33 @@ declare_lint! {
Allow, Allow,
"No declared ABI for extern declaration" "No declared ABI for extern declaration"
} }
declare_lint! {
/// The `invalid_doc_attributes` lint detects when the `#[doc(...)]` is
/// misused.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(warnings)]
///
/// pub mod submodule {
/// #![doc(test(no_crate_inject))]
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Previously, there were very like checks being performed on `#[doc(..)]`
/// unlike the other attributes. It'll now catch all the issues that it
/// silently ignored previously.
pub INVALID_DOC_ATTRIBUTES,
Warn,
"detects invalid `#[doc(...)]` attributes",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>",
edition: None,
};
}

View file

@ -17,7 +17,9 @@ use rustc_hir::{
self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID,
}; };
use rustc_hir::{MethodKind, Target}; use rustc_hir::{MethodKind, Target};
use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES}; use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES,
};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -544,6 +546,21 @@ impl CheckAttrVisitor<'tcx> {
{ {
return false; return false;
} }
} else if meta.has_name(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"
)
.emit();
},
);
return false;
}
} else if let Some(i_meta) = meta.meta_item() { } else if let Some(i_meta) = meta.meta_item() {
if ![ if ![
sym::cfg, sym::cfg,
@ -568,7 +585,7 @@ impl CheckAttrVisitor<'tcx> {
.any(|m| i_meta.has_name(*m)) .any(|m| i_meta.has_name(*m))
{ {
self.tcx.struct_span_lint_hir( self.tcx.struct_span_lint_hir(
UNUSED_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
i_meta.span, i_meta.span,
|lint| { |lint| {
@ -576,11 +593,6 @@ impl CheckAttrVisitor<'tcx> {
"unknown `doc` attribute `{}`", "unknown `doc` attribute `{}`",
i_meta.name_or_empty() i_meta.name_or_empty()
)) ))
.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
)
.emit(); .emit();
}, },
); );

View file

@ -1,11 +1,10 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![deny(unused_attributes)] #![deny(warnings)]
//~^ NOTE lint level is defined here
#![doc(as_ptr)] #![doc(as_ptr)]
//~^ ERROR unknown `doc` attribute //~^ ERROR unknown `doc` attribute
//~| WARNING will become a hard error in a future release //~^^ WARN
#[doc(as_ptr)] #[doc(as_ptr)]
//~^ ERROR unknown `doc` attribute //~^ ERROR unknown `doc` attribute
//~| WARNING will become a hard error in a future release //~^^ WARN
pub fn foo() {} pub fn foo() {}

View file

@ -1,5 +1,5 @@
error: unknown `doc` attribute `as_ptr` error: unknown `doc` attribute `as_ptr`
--> $DIR/doc-attr.rs:8:7 --> $DIR/doc-attr.rs:7:7
| |
LL | #[doc(as_ptr)] LL | #[doc(as_ptr)]
| ^^^^^^ | ^^^^^^
@ -7,17 +7,20 @@ LL | #[doc(as_ptr)]
note: the lint level is defined here note: the lint level is defined here
--> $DIR/doc-attr.rs:2:9 --> $DIR/doc-attr.rs:2:9
| |
LL | #![deny(unused_attributes)] 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! = 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:4:8 --> $DIR/doc-attr.rs:3:8
| |
LL | #![doc(as_ptr)] 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>
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -0,0 +1,11 @@
#![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

@ -0,0 +1,26 @@
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

@ -1,11 +1,10 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![deny(unused_attributes)] #![deny(warnings)]
//~^ NOTE lint level is defined here
#![doc(as_ptr)] #![doc(as_ptr)]
//~^ ERROR unknown `doc` attribute //~^ ERROR unknown `doc` attribute
//~| WARNING will become a hard error in a future release //~^^ WARN
#[doc(as_ptr)] #[doc(as_ptr)]
//~^ ERROR unknown `doc` attribute //~^ ERROR unknown `doc` attribute
//~| WARNING will become a hard error in a future release //~^^ WARN
pub fn foo() {} pub fn foo() {}

View file

@ -1,5 +1,5 @@
error: unknown `doc` attribute `as_ptr` error: unknown `doc` attribute `as_ptr`
--> $DIR/doc-attr.rs:8:7 --> $DIR/doc-attr.rs:7:7
| |
LL | #[doc(as_ptr)] LL | #[doc(as_ptr)]
| ^^^^^^ | ^^^^^^
@ -7,17 +7,20 @@ LL | #[doc(as_ptr)]
note: the lint level is defined here note: the lint level is defined here
--> $DIR/doc-attr.rs:2:9 --> $DIR/doc-attr.rs:2:9
| |
LL | #![deny(unused_attributes)] 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! = 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:4:8 --> $DIR/doc-attr.rs:3:8
| |
LL | #![doc(as_ptr)] 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>
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -0,0 +1,11 @@
#![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

@ -0,0 +1,26 @@
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