diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 5377ebde168..2cbf348f13a 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -221,6 +221,8 @@ declare_features! ( (active, rustc_private, "1.0.0", Some(27812), None), /// Allows using internal rustdoc features like `doc(primitive)` or `doc(keyword)`. (active, rustdoc_internals, "1.58.0", Some(90418), None), + /// Allows using the `rustdoc::missing_doc_code_examples` lint + (active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None), /// Allows using `#[start]` on a function indicating that it is the program entrypoint. (active, start, "1.0.0", Some(29633), None), /// Allows using `#[structural_match]` which indicates that a type is structurally matchable. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 871bc5c1cdb..1779ff4bcf1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1292,6 +1292,7 @@ symbols! { rustc_variance, rustdoc, rustdoc_internals, + rustdoc_missing_doc_code_examples, rustfmt, rvalue_static_promotion, s, diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index 240aec52cff..e76c19a61c5 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -64,9 +64,13 @@ where } macro_rules! declare_rustdoc_lint { - ($(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)?) => { + ( + $(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)? + $(@feature_gate = $gate:expr;)? + ) => { declare_tool_lint! { $(#[$attr])* pub rustdoc::$name, $level, $descr + $(, @feature_gate = $gate;)? } } } @@ -123,7 +127,8 @@ declare_rustdoc_lint! { /// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples MISSING_DOC_CODE_EXAMPLES, Allow, - "detects publicly-exported items without code samples in their documentation" + "detects publicly-exported items without code samples in their documentation", + @feature_gate = rustc_span::symbol::sym::rustdoc_missing_doc_code_examples; } declare_rustdoc_lint! { diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index e86f9083394..55d5f303d34 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -117,7 +117,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item find_testable_code(dox, &mut tests, ErrorCodes::No, false, None); - if tests.found_tests == 0 && cx.tcx.sess.is_nightly_build() { + if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples { if should_have_doc_example(cx, item) { debug!("reporting error for {:?} (hir_id={:?})", item, hir_id); let sp = item.attr_span(cx.tcx); diff --git a/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs index 2355d6a3d6c..c5e1759ee2d 100644 --- a/src/test/rustdoc-ui/check-fail.rs +++ b/src/test/rustdoc-ui/check-fail.rs @@ -1,5 +1,6 @@ // compile-flags: -Z unstable-options --check +#![feature(rustdoc_missing_doc_code_examples)] #![deny(missing_docs)] #![deny(rustdoc::all)] diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr index 5d46dc72014..217b89d935b 100644 --- a/src/test/rustdoc-ui/check-fail.stderr +++ b/src/test/rustdoc-ui/check-fail.stderr @@ -1,30 +1,30 @@ error: missing documentation for a function - --> $DIR/check-fail.rs:11:1 + --> $DIR/check-fail.rs:12:1 | LL | pub fn foo() {} | ^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/check-fail.rs:3:9 + --> $DIR/check-fail.rs:4:9 | LL | #![deny(missing_docs)] | ^^^^^^^^^^^^ error: missing code example in this documentation - --> $DIR/check-fail.rs:11:1 + --> $DIR/check-fail.rs:12:1 | LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/check-fail.rs:4:9 + --> $DIR/check-fail.rs:5:9 | LL | #![deny(rustdoc::all)] | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]` error: unknown attribute `testharness`. Did you mean `test_harness`? - --> $DIR/check-fail.rs:6:1 + --> $DIR/check-fail.rs:7:1 | LL | / //! ```rust,testharness LL | | @@ -36,7 +36,7 @@ LL | | //! ``` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function error: unknown attribute `testharness`. Did you mean `test_harness`? - --> $DIR/check-fail.rs:15:1 + --> $DIR/check-fail.rs:16:1 | LL | / /// hello LL | | diff --git a/src/test/rustdoc-ui/check.rs b/src/test/rustdoc-ui/check.rs index 2b44ba24b44..f70b0336151 100644 --- a/src/test/rustdoc-ui/check.rs +++ b/src/test/rustdoc-ui/check.rs @@ -2,9 +2,11 @@ // compile-flags: -Z unstable-options --check // normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" -#![warn(missing_docs)] +#![feature(rustdoc_missing_doc_code_examples)] //~^ WARN //~^^ WARN + +#![warn(missing_docs)] #![warn(rustdoc::all)] pub fn foo() {} diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr index 06e607fbe55..78ae65d313a 100644 --- a/src/test/rustdoc-ui/check.stderr +++ b/src/test/rustdoc-ui/check.stderr @@ -1,22 +1,23 @@ warning: missing documentation for the crate --> $DIR/check.rs:5:1 | -LL | / #![warn(missing_docs)] +LL | / #![feature(rustdoc_missing_doc_code_examples)] LL | | LL | | -LL | | #![warn(rustdoc::all)] +LL | | +... | LL | | LL | | pub fn foo() {} | |_______________^ | note: the lint level is defined here - --> $DIR/check.rs:5:9 + --> $DIR/check.rs:9:9 | LL | #![warn(missing_docs)] | ^^^^^^^^^^^^ warning: missing documentation for a function - --> $DIR/check.rs:10:1 + --> $DIR/check.rs:12:1 | LL | pub fn foo() {} | ^^^^^^^^^^^^ @@ -24,7 +25,7 @@ LL | pub fn foo() {} warning: no documentation found for this crate's top-level module | note: the lint level is defined here - --> $DIR/check.rs:8:9 + --> $DIR/check.rs:10:9 | LL | #![warn(rustdoc::all)] | ^^^^^^^^^^^^ @@ -35,10 +36,11 @@ LL | #![warn(rustdoc::all)] warning: missing code example in this documentation --> $DIR/check.rs:5:1 | -LL | / #![warn(missing_docs)] +LL | / #![feature(rustdoc_missing_doc_code_examples)] LL | | LL | | -LL | | #![warn(rustdoc::all)] +LL | | +... | LL | | LL | | pub fn foo() {} | |_______________^ @@ -46,7 +48,7 @@ LL | | pub fn foo() {} = note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]` warning: missing code example in this documentation - --> $DIR/check.rs:10:1 + --> $DIR/check.rs:12:1 | LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ diff --git a/src/test/rustdoc-ui/doc-without-codeblock.rs b/src/test/rustdoc-ui/doc-without-codeblock.rs index 315fca19587..86d7c83d335 100644 --- a/src/test/rustdoc-ui/doc-without-codeblock.rs +++ b/src/test/rustdoc-ui/doc-without-codeblock.rs @@ -1,4 +1,5 @@ -#![deny(rustdoc::missing_doc_code_examples)] //~ ERROR missing code example in this documentation +#![feature(rustdoc_missing_doc_code_examples)] //~ ERROR missing code example in this documentation +#![deny(rustdoc::missing_doc_code_examples)] /// Some docs. //~^ ERROR missing code example in this documentation diff --git a/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr index 1c138044165..ebf2a2d54f7 100644 --- a/src/test/rustdoc-ui/doc-without-codeblock.stderr +++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr @@ -1,35 +1,35 @@ error: missing code example in this documentation --> $DIR/doc-without-codeblock.rs:1:1 | -LL | / #![deny(rustdoc::missing_doc_code_examples)] +LL | / #![feature(rustdoc_missing_doc_code_examples)] +LL | | #![deny(rustdoc::missing_doc_code_examples)] LL | | LL | | /// Some docs. -LL | | ... | LL | | } LL | | } | |_^ | note: the lint level is defined here - --> $DIR/doc-without-codeblock.rs:1:9 + --> $DIR/doc-without-codeblock.rs:2:9 | LL | #![deny(rustdoc::missing_doc_code_examples)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing code example in this documentation - --> $DIR/doc-without-codeblock.rs:7:1 + --> $DIR/doc-without-codeblock.rs:8:1 | LL | /// And then, the princess died. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing code example in this documentation - --> $DIR/doc-without-codeblock.rs:10:5 + --> $DIR/doc-without-codeblock.rs:11:5 | LL | /// Or maybe not because she saved herself! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing code example in this documentation - --> $DIR/doc-without-codeblock.rs:3:1 + --> $DIR/doc-without-codeblock.rs:4:1 | LL | /// Some docs. | ^^^^^^^^^^^^^^ diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs new file mode 100644 index 00000000000..daba6986864 --- /dev/null +++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs @@ -0,0 +1,10 @@ +#![deny(unknown_lints)] +//~^ NOTE defined here + +#![allow(rustdoc::missing_doc_code_examples)] +//~^ ERROR unknown lint +//~| ERROR unknown lint +//~| NOTE lint is unstable +//~| NOTE lint is unstable +//~| NOTE see issue +//~| NOTE see issue diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr new file mode 100644 index 00000000000..517e08aa7c9 --- /dev/null +++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr @@ -0,0 +1,29 @@ +error: unknown lint: `rustdoc::missing_doc_code_examples` + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1 + | +LL | #![allow(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9 + | +LL | #![deny(unknown_lints)] + | ^^^^^^^^^^^^^ + = note: the `rustdoc::missing_doc_code_examples` lint is unstable + = note: see issue #101730 for more information + = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable + +error: unknown lint: `rustdoc::missing_doc_code_examples` + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1 + | +LL | #![allow(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the `rustdoc::missing_doc_code_examples` lint is unstable + = note: see issue #101730 for more information + = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable + +error: Compilation failed, aborting rustdoc + +error: aborting due to 3 previous errors + diff --git a/src/test/rustdoc-ui/lint-group.rs b/src/test/rustdoc-ui/lint-group.rs index 61555a6e686..09aca6d2b27 100644 --- a/src/test/rustdoc-ui/lint-group.rs +++ b/src/test/rustdoc-ui/lint-group.rs @@ -1,3 +1,5 @@ +#![feature(rustdoc_missing_doc_code_examples)] + //! Documenting the kinds of lints emitted by rustdoc. //! //! ``` diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index e28600160b1..5336c044574 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -1,18 +1,18 @@ error: missing code example in this documentation - --> $DIR/lint-group.rs:16:1 + --> $DIR/lint-group.rs:18:1 | LL | /// wait, this doesn't have a doctest? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/lint-group.rs:7:9 + --> $DIR/lint-group.rs:9:9 | LL | #![deny(rustdoc::all)] | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]` error: documentation test in private item - --> $DIR/lint-group.rs:19:1 + --> $DIR/lint-group.rs:21:1 | LL | / /// wait, this *does* have a doctest? LL | | /// @@ -24,13 +24,13 @@ LL | | /// ``` = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]` error: missing code example in this documentation - --> $DIR/lint-group.rs:26:1 + --> $DIR/lint-group.rs:28:1 | LL | /// | ^^^^^^^^^^^^^ error: unresolved link to `error` - --> $DIR/lint-group.rs:9:29 + --> $DIR/lint-group.rs:11:29 | LL | /// what up, let's make an [error] | ^^^^^ no item named `error` in scope @@ -39,7 +39,7 @@ LL | /// what up, let's make an [error] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unclosed HTML tag `unknown` - --> $DIR/lint-group.rs:26:5 + --> $DIR/lint-group.rs:28:5 | LL | /// | ^^^^^^^^^ diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs index fac6342cd24..40f35728d79 100644 --- a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs @@ -1,3 +1,4 @@ +#![feature(rustdoc_missing_doc_code_examples)] #![deny(missing_docs)] #![deny(rustdoc::missing_doc_code_examples)] diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr index 9e51ecd2ba0..f9331250154 100644 --- a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr @@ -1,35 +1,35 @@ error: missing code example in this documentation - --> $DIR/lint-missing-doc-code-example.rs:19:1 + --> $DIR/lint-missing-doc-code-example.rs:20:1 | LL | pub mod module1 { | ^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/lint-missing-doc-code-example.rs:2:9 + --> $DIR/lint-missing-doc-code-example.rs:3:9 | LL | #![deny(rustdoc::missing_doc_code_examples)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing code example in this documentation - --> $DIR/lint-missing-doc-code-example.rs:37:3 + --> $DIR/lint-missing-doc-code-example.rs:38:3 | LL | /// doc | ^^^^^^^ error: missing code example in this documentation - --> $DIR/lint-missing-doc-code-example.rs:49:1 + --> $DIR/lint-missing-doc-code-example.rs:50:1 | LL | /// Doc | ^^^^^^^ error: missing code example in this documentation - --> $DIR/lint-missing-doc-code-example.rs:56:1 + --> $DIR/lint-missing-doc-code-example.rs:57:1 | LL | /// Doc | ^^^^^^^ error: missing code example in this documentation - --> $DIR/lint-missing-doc-code-example.rs:63:1 + --> $DIR/lint-missing-doc-code-example.rs:64:1 | LL | /// Doc | ^^^^^^^