diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 12d849e3b94..e6f81ce828f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3059,3 +3059,33 @@ declare_lint! { Allow, "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 ", + edition: None, + }; +} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 39245ea77e5..ed971951b0f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -17,7 +17,9 @@ use rustc_hir::{ self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, }; 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_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -544,6 +546,21 @@ impl CheckAttrVisitor<'tcx> { { 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() { if ![ sym::cfg, @@ -568,7 +585,7 @@ impl CheckAttrVisitor<'tcx> { .any(|m| i_meta.has_name(*m)) { self.tcx.struct_span_lint_hir( - UNUSED_ATTRIBUTES, + INVALID_DOC_ATTRIBUTES, hir_id, i_meta.span, |lint| { @@ -576,11 +593,6 @@ impl CheckAttrVisitor<'tcx> { "unknown `doc` attribute `{}`", 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(); }, ); diff --git a/src/test/rustdoc-ui/doc-attr.rs b/src/test/rustdoc-ui/doc-attr.rs index 3519b5707b3..3a584112973 100644 --- a/src/test/rustdoc-ui/doc-attr.rs +++ b/src/test/rustdoc-ui/doc-attr.rs @@ -1,11 +1,10 @@ #![crate_type = "lib"] -#![deny(unused_attributes)] -//~^ NOTE lint level is defined here +#![deny(warnings)] #![doc(as_ptr)] //~^ ERROR unknown `doc` attribute -//~| WARNING will become a hard error in a future release +//~^^ WARN #[doc(as_ptr)] //~^ ERROR unknown `doc` attribute -//~| WARNING will become a hard error in a future release +//~^^ WARN pub fn foo() {} diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr index 9666db2b10e..21479d25fc2 100644 --- a/src/test/rustdoc-ui/doc-attr.stderr +++ b/src/test/rustdoc-ui/doc-attr.stderr @@ -1,5 +1,5 @@ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:8:7 + --> $DIR/doc-attr.rs:7:7 | LL | #[doc(as_ptr)] | ^^^^^^ @@ -7,17 +7,20 @@ LL | #[doc(as_ptr)] note: the lint level is defined here --> $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! + = note: for more information, see issue #82730 error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:4:8 + --> $DIR/doc-attr.rs:3:8 | 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! + = note: for more information, see issue #82730 error: aborting due to 2 previous errors diff --git a/src/test/rustdoc-ui/doc-attr2.rs b/src/test/rustdoc-ui/doc-attr2.rs new file mode 100644 index 00000000000..3fb484644d7 --- /dev/null +++ b/src/test/rustdoc-ui/doc-attr2.rs @@ -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 +} diff --git a/src/test/rustdoc-ui/doc-attr2.stderr b/src/test/rustdoc-ui/doc-attr2.stderr new file mode 100644 index 00000000000..eeb2c2be085 --- /dev/null +++ b/src/test/rustdoc-ui/doc-attr2.stderr @@ -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 + +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 + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/attributes/doc-attr.rs b/src/test/ui/attributes/doc-attr.rs index 3519b5707b3..3a584112973 100644 --- a/src/test/ui/attributes/doc-attr.rs +++ b/src/test/ui/attributes/doc-attr.rs @@ -1,11 +1,10 @@ #![crate_type = "lib"] -#![deny(unused_attributes)] -//~^ NOTE lint level is defined here +#![deny(warnings)] #![doc(as_ptr)] //~^ ERROR unknown `doc` attribute -//~| WARNING will become a hard error in a future release +//~^^ WARN #[doc(as_ptr)] //~^ ERROR unknown `doc` attribute -//~| WARNING will become a hard error in a future release +//~^^ WARN pub fn foo() {} diff --git a/src/test/ui/attributes/doc-attr.stderr b/src/test/ui/attributes/doc-attr.stderr index 9666db2b10e..21479d25fc2 100644 --- a/src/test/ui/attributes/doc-attr.stderr +++ b/src/test/ui/attributes/doc-attr.stderr @@ -1,5 +1,5 @@ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:8:7 + --> $DIR/doc-attr.rs:7:7 | LL | #[doc(as_ptr)] | ^^^^^^ @@ -7,17 +7,20 @@ LL | #[doc(as_ptr)] note: the lint level is defined here --> $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! + = note: for more information, see issue #82730 error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:4:8 + --> $DIR/doc-attr.rs:3:8 | 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! + = note: for more information, see issue #82730 error: aborting due to 2 previous errors diff --git a/src/test/ui/attributes/doc-attr2.rs b/src/test/ui/attributes/doc-attr2.rs new file mode 100644 index 00000000000..3fb484644d7 --- /dev/null +++ b/src/test/ui/attributes/doc-attr2.rs @@ -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 +} diff --git a/src/test/ui/attributes/doc-attr2.stderr b/src/test/ui/attributes/doc-attr2.stderr new file mode 100644 index 00000000000..eeb2c2be085 --- /dev/null +++ b/src/test/ui/attributes/doc-attr2.stderr @@ -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 + +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 + +error: aborting due to 2 previous errors +