summaryrefslogtreecommitdiffstats
path: root/tests/rustdoc-ui/lints
diff options
context:
space:
mode:
Diffstat (limited to 'tests/rustdoc-ui/lints')
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.fixed60
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.rs60
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.stderr143
-rw-r--r--tests/rustdoc-ui/lints/check-attr.rs41
-rw-r--r--tests/rustdoc-ui/lints/check-attr.stderr175
-rw-r--r--tests/rustdoc-ui/lints/check-fail.rs23
-rw-r--r--tests/rustdoc-ui/lints/check-fail.stderr56
-rw-r--r--tests/rustdoc-ui/lints/check.rs15
-rw-r--r--tests/rustdoc-ui/lints/check.stderr61
-rw-r--r--tests/rustdoc-ui/lints/deny-missing-docs-crate.rs3
-rw-r--r--tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr22
-rw-r--r--tests/rustdoc-ui/lints/deny-missing-docs-macro.rs8
-rw-r--r--tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr14
-rw-r--r--tests/rustdoc-ui/lints/doc-attr.rs25
-rw-r--r--tests/rustdoc-ui/lints/doc-attr.stderr71
-rw-r--r--tests/rustdoc-ui/lints/doc-spotlight.fixed8
-rw-r--r--tests/rustdoc-ui/lints/doc-spotlight.rs8
-rw-r--r--tests/rustdoc-ui/lints/doc-spotlight.stderr19
-rw-r--r--tests/rustdoc-ui/lints/doc-without-codeblock.rs23
-rw-r--r--tests/rustdoc-ui/lints/doc-without-codeblock.stderr38
-rw-r--r--tests/rustdoc-ui/lints/doc_cfg_hide.rs11
-rw-r--r--tests/rustdoc-ui/lints/doc_cfg_hide.stderr40
-rw-r--r--tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs157
-rw-r--r--tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr28
-rw-r--r--tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs12
-rw-r--r--tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr37
-rw-r--r--tests/rustdoc-ui/lints/invalid-doc-attr.rs32
-rw-r--r--tests/rustdoc-ui/lints/invalid-doc-attr.stderr78
-rw-r--r--tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs70
-rw-r--r--tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr80
-rw-r--r--tests/rustdoc-ui/lints/invalid-html-tags.rs123
-rw-r--r--tests/rustdoc-ui/lints/invalid-html-tags.stderr104
-rw-r--r--tests/rustdoc-ui/lints/lint-group.rs32
-rw-r--r--tests/rustdoc-ui/lints/lint-group.stderr54
-rw-r--r--tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs101
-rw-r--r--tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr38
-rw-r--r--tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs6
-rw-r--r--tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr12
-rw-r--r--tests/rustdoc-ui/lints/renamed-lint-still-applies.rs10
-rw-r--r--tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr42
-rw-r--r--tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs6
-rw-r--r--tests/rustdoc-ui/lints/unknown-renamed-lints.rs24
-rw-r--r--tests/rustdoc-ui/lints/unknown-renamed-lints.stderr62
-rw-r--r--tests/rustdoc-ui/lints/unused-braces-lint.rs14
-rw-r--r--tests/rustdoc-ui/lints/unused.rs14
45 files changed, 2060 insertions, 0 deletions
diff --git a/tests/rustdoc-ui/lints/bare-urls.fixed b/tests/rustdoc-ui/lints/bare-urls.fixed
new file mode 100644
index 000000000..23aa5c44c
--- /dev/null
+++ b/tests/rustdoc-ui/lints/bare-urls.fixed
@@ -0,0 +1,60 @@
+// run-rustfix
+
+#![deny(rustdoc::bare_urls)]
+
+/// <https://somewhere.com>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com/a>
+//~^ ERROR this URL is not a hyperlink
+/// <https://www.somewhere.com>
+//~^ ERROR this URL is not a hyperlink
+/// <https://www.somewhere.com/a>
+//~^ ERROR this URL is not a hyperlink
+/// <https://subdomain.example.com>
+//~^ ERROR not a hyperlink
+/// <https://somewhere.com?>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com/a?>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com?hello=12>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com/a?hello=12>
+//~^ ERROR this URL is not a hyperlink
+/// <https://example.com?hello=12#xyz>
+//~^ ERROR this URL is not a hyperlink
+/// <https://example.com/a?hello=12#xyz>
+//~^ ERROR this URL is not a hyperlink
+/// <https://example.com#xyz>
+//~^ ERROR this URL is not a hyperlink
+/// <https://example.com/a#xyz>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com?hello=12&bye=11>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com/a?hello=12&bye=11>
+//~^ ERROR this URL is not a hyperlink
+/// <https://somewhere.com?hello=12&bye=11#xyz>
+//~^ ERROR this URL is not a hyperlink
+/// hey! <https://somewhere.com/a?hello=12&bye=11#xyz>
+//~^ ERROR this URL is not a hyperlink
+pub fn c() {}
+
+/// <https://somewhere.com>
+/// [a](http://a.com)
+/// [b]
+///
+/// [b]: http://b.com
+///
+/// ```
+/// This link should not be linted: http://example.com
+///
+/// Nor this one: <http://example.com> or this one: [x](http://example.com)
+/// ```
+///
+/// [should_not.lint](should_not.lint)
+pub fn everything_is_fine_here() {}
+
+#[allow(rustdoc::bare_urls)]
+pub mod foo {
+ /// https://somewhere.com/a?hello=12&bye=11#xyz
+ pub fn bar() {}
+}
diff --git a/tests/rustdoc-ui/lints/bare-urls.rs b/tests/rustdoc-ui/lints/bare-urls.rs
new file mode 100644
index 000000000..592f57343
--- /dev/null
+++ b/tests/rustdoc-ui/lints/bare-urls.rs
@@ -0,0 +1,60 @@
+// run-rustfix
+
+#![deny(rustdoc::bare_urls)]
+
+/// https://somewhere.com
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com/a
+//~^ ERROR this URL is not a hyperlink
+/// https://www.somewhere.com
+//~^ ERROR this URL is not a hyperlink
+/// https://www.somewhere.com/a
+//~^ ERROR this URL is not a hyperlink
+/// https://subdomain.example.com
+//~^ ERROR not a hyperlink
+/// https://somewhere.com?
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com/a?
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com?hello=12
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com/a?hello=12
+//~^ ERROR this URL is not a hyperlink
+/// https://example.com?hello=12#xyz
+//~^ ERROR this URL is not a hyperlink
+/// https://example.com/a?hello=12#xyz
+//~^ ERROR this URL is not a hyperlink
+/// https://example.com#xyz
+//~^ ERROR this URL is not a hyperlink
+/// https://example.com/a#xyz
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com?hello=12&bye=11
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com/a?hello=12&bye=11
+//~^ ERROR this URL is not a hyperlink
+/// https://somewhere.com?hello=12&bye=11#xyz
+//~^ ERROR this URL is not a hyperlink
+/// hey! https://somewhere.com/a?hello=12&bye=11#xyz
+//~^ ERROR this URL is not a hyperlink
+pub fn c() {}
+
+/// <https://somewhere.com>
+/// [a](http://a.com)
+/// [b]
+///
+/// [b]: http://b.com
+///
+/// ```
+/// This link should not be linted: http://example.com
+///
+/// Nor this one: <http://example.com> or this one: [x](http://example.com)
+/// ```
+///
+/// [should_not.lint](should_not.lint)
+pub fn everything_is_fine_here() {}
+
+#[allow(rustdoc::bare_urls)]
+pub mod foo {
+ /// https://somewhere.com/a?hello=12&bye=11#xyz
+ pub fn bar() {}
+}
diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr
new file mode 100644
index 000000000..ccf52cd0b
--- /dev/null
+++ b/tests/rustdoc-ui/lints/bare-urls.stderr
@@ -0,0 +1,143 @@
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:5:5
+ |
+LL | /// https://somewhere.com
+ | ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+note: the lint level is defined here
+ --> $DIR/bare-urls.rs:3:9
+ |
+LL | #![deny(rustdoc::bare_urls)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:7:5
+ |
+LL | /// https://somewhere.com/a
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:9:5
+ |
+LL | /// https://www.somewhere.com
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:11:5
+ |
+LL | /// https://www.somewhere.com/a
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com/a>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:13:5
+ |
+LL | /// https://subdomain.example.com
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://subdomain.example.com>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:15:5
+ |
+LL | /// https://somewhere.com?
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:17:5
+ |
+LL | /// https://somewhere.com/a?
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:19:5
+ |
+LL | /// https://somewhere.com?hello=12
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:21:5
+ |
+LL | /// https://somewhere.com/a?hello=12
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:23:5
+ |
+LL | /// https://example.com?hello=12#xyz
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com?hello=12#xyz>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:25:5
+ |
+LL | /// https://example.com/a?hello=12#xyz
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a?hello=12#xyz>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:27:5
+ |
+LL | /// https://example.com#xyz
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com#xyz>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:29:5
+ |
+LL | /// https://example.com/a#xyz
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a#xyz>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:31:5
+ |
+LL | /// https://somewhere.com?hello=12&bye=11
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:33:5
+ |
+LL | /// https://somewhere.com/a?hello=12&bye=11
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:35:5
+ |
+LL | /// https://somewhere.com?hello=12&bye=11#xyz
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11#xyz>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+ --> $DIR/bare-urls.rs:37:10
+ |
+LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11#xyz>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+
+error: aborting due to 17 previous errors
+
diff --git a/tests/rustdoc-ui/lints/check-attr.rs b/tests/rustdoc-ui/lints/check-attr.rs
new file mode 100644
index 000000000..0b3f7bedd
--- /dev/null
+++ b/tests/rustdoc-ui/lints/check-attr.rs
@@ -0,0 +1,41 @@
+#![deny(rustdoc::invalid_codeblock_attributes)]
+
+/// foo
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+///
+/// ```compile-fail,compilefail,comPile_fail
+/// boo
+/// ```
+pub fn foo() {}
+
+/// bar
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+///
+/// ```should-panic,shouldpanic,sHould_panic
+/// boo
+/// ```
+pub fn bar() {}
+
+/// foobar
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+///
+/// ```no-run,norun,no_Run
+/// boo
+/// ```
+pub fn foobar() {}
+
+/// b
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+///
+/// ```test-harness,testharness,teSt_harness
+/// boo
+/// ```
+pub fn b() {}
diff --git a/tests/rustdoc-ui/lints/check-attr.stderr b/tests/rustdoc-ui/lints/check-attr.stderr
new file mode 100644
index 000000000..f66e63ab7
--- /dev/null
+++ b/tests/rustdoc-ui/lints/check-attr.stderr
@@ -0,0 +1,175 @@
+error: unknown attribute `compile-fail`. Did you mean `compile_fail`?
+ --> $DIR/check-attr.rs:3:1
+ |
+LL | / /// foo
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
+note: the lint level is defined here
+ --> $DIR/check-attr.rs:1:9
+ |
+LL | #![deny(rustdoc::invalid_codeblock_attributes)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unknown attribute `compilefail`. Did you mean `compile_fail`?
+ --> $DIR/check-attr.rs:3:1
+ |
+LL | / /// foo
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
+
+error: unknown attribute `comPile_fail`. Did you mean `compile_fail`?
+ --> $DIR/check-attr.rs:3:1
+ |
+LL | / /// foo
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
+
+error: unknown attribute `should-panic`. Did you mean `should_panic`?
+ --> $DIR/check-attr.rs:13:1
+ |
+LL | / /// bar
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
+
+error: unknown attribute `shouldpanic`. Did you mean `should_panic`?
+ --> $DIR/check-attr.rs:13:1
+ |
+LL | / /// bar
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
+
+error: unknown attribute `sHould_panic`. Did you mean `should_panic`?
+ --> $DIR/check-attr.rs:13:1
+ |
+LL | / /// bar
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
+
+error: unknown attribute `no-run`. Did you mean `no_run`?
+ --> $DIR/check-attr.rs:23:1
+ |
+LL | / /// foobar
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
+
+error: unknown attribute `norun`. Did you mean `no_run`?
+ --> $DIR/check-attr.rs:23:1
+ |
+LL | / /// foobar
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
+
+error: unknown attribute `no_Run`. Did you mean `no_run`?
+ --> $DIR/check-attr.rs:23:1
+ |
+LL | / /// foobar
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+LL | | /// ```
+ | |_______^
+ |
+ = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
+
+error: unknown attribute `test-harness`. Did you mean `test_harness`?
+ --> $DIR/check-attr.rs:33:1
+ |
+LL | / /// b
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+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-attr.rs:33:1
+ |
+LL | / /// b
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+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 `teSt_harness`. Did you mean `test_harness`?
+ --> $DIR/check-attr.rs:33:1
+ |
+LL | / /// b
+LL | |
+LL | |
+LL | |
+... |
+LL | | /// boo
+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: aborting due to 12 previous errors
+
diff --git a/tests/rustdoc-ui/lints/check-fail.rs b/tests/rustdoc-ui/lints/check-fail.rs
new file mode 100644
index 000000000..02632b4ce
--- /dev/null
+++ b/tests/rustdoc-ui/lints/check-fail.rs
@@ -0,0 +1,23 @@
+// compile-flags: -Z unstable-options --check
+
+#![feature(rustdoc_missing_doc_code_examples)]
+#![deny(missing_docs)]
+#![deny(rustdoc::missing_doc_code_examples)]
+#![deny(rustdoc::all)]
+
+//! ```rust,testharness
+//~^ ERROR
+//! let x = 12;
+//! ```
+
+pub fn foo() {}
+//~^ ERROR
+//~^^ ERROR
+
+/// hello
+//~^ ERROR
+///
+/// ```rust,testharness
+/// let x = 12;
+/// ```
+pub fn bar() {}
diff --git a/tests/rustdoc-ui/lints/check-fail.stderr b/tests/rustdoc-ui/lints/check-fail.stderr
new file mode 100644
index 000000000..f05e457af
--- /dev/null
+++ b/tests/rustdoc-ui/lints/check-fail.stderr
@@ -0,0 +1,56 @@
+error: missing documentation for a function
+ --> $DIR/check-fail.rs:13:1
+ |
+LL | pub fn foo() {}
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/check-fail.rs:4:9
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing code example in this documentation
+ --> $DIR/check-fail.rs:13:1
+ |
+LL | pub fn foo() {}
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/check-fail.rs:5:9
+ |
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unknown attribute `testharness`. Did you mean `test_harness`?
+ --> $DIR/check-fail.rs:8:1
+ |
+LL | / //! ```rust,testharness
+LL | |
+LL | | //! let x = 12;
+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
+note: the lint level is defined here
+ --> $DIR/check-fail.rs:6:9
+ |
+LL | #![deny(rustdoc::all)]
+ | ^^^^^^^^^^^^
+ = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]`
+
+error: unknown attribute `testharness`. Did you mean `test_harness`?
+ --> $DIR/check-fail.rs:17:1
+ |
+LL | / /// hello
+LL | |
+LL | | ///
+LL | | /// ```rust,testharness
+LL | | /// let x = 12;
+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: aborting due to 4 previous errors
+
diff --git a/tests/rustdoc-ui/lints/check.rs b/tests/rustdoc-ui/lints/check.rs
new file mode 100644
index 000000000..e389a81bb
--- /dev/null
+++ b/tests/rustdoc-ui/lints/check.rs
@@ -0,0 +1,15 @@
+// check-pass
+// compile-flags: -Z unstable-options --check
+// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
+
+#![feature(rustdoc_missing_doc_code_examples)]
+//~^ WARN
+//~^^ WARN
+
+#![warn(missing_docs)]
+#![warn(rustdoc::missing_doc_code_examples)]
+#![warn(rustdoc::all)]
+
+pub fn foo() {}
+//~^ WARN
+//~^^ WARN
diff --git a/tests/rustdoc-ui/lints/check.stderr b/tests/rustdoc-ui/lints/check.stderr
new file mode 100644
index 000000000..c5ed5d0c3
--- /dev/null
+++ b/tests/rustdoc-ui/lints/check.stderr
@@ -0,0 +1,61 @@
+warning: missing documentation for the crate
+ --> $DIR/check.rs:5:1
+ |
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | |
+LL | |
+LL | |
+... |
+LL | |
+LL | | pub fn foo() {}
+ | |_______________^
+ |
+note: the lint level is defined here
+ --> $DIR/check.rs:9:9
+ |
+LL | #![warn(missing_docs)]
+ | ^^^^^^^^^^^^
+
+warning: missing documentation for a function
+ --> $DIR/check.rs:13:1
+ |
+LL | pub fn foo() {}
+ | ^^^^^^^^^^^^
+
+warning: no documentation found for this crate's top-level module
+ |
+ = help: The following guide may be of use:
+ https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
+note: the lint level is defined here
+ --> $DIR/check.rs:11:9
+ |
+LL | #![warn(rustdoc::all)]
+ | ^^^^^^^^^^^^
+ = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]`
+
+warning: missing code example in this documentation
+ --> $DIR/check.rs:5:1
+ |
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | |
+LL | |
+LL | |
+... |
+LL | |
+LL | | pub fn foo() {}
+ | |_______________^
+ |
+note: the lint level is defined here
+ --> $DIR/check.rs:10:9
+ |
+LL | #![warn(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: missing code example in this documentation
+ --> $DIR/check.rs:13:1
+ |
+LL | pub fn foo() {}
+ | ^^^^^^^^^^^^^^^
+
+warning: 5 warnings emitted
+
diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-crate.rs b/tests/rustdoc-ui/lints/deny-missing-docs-crate.rs
new file mode 100644
index 000000000..b74eba3f6
--- /dev/null
+++ b/tests/rustdoc-ui/lints/deny-missing-docs-crate.rs
@@ -0,0 +1,3 @@
+#![deny(missing_docs)] //~ ERROR
+
+pub struct Foo; //~ ERROR
diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr b/tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr
new file mode 100644
index 000000000..5025b0b0c
--- /dev/null
+++ b/tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr
@@ -0,0 +1,22 @@
+error: missing documentation for the crate
+ --> $DIR/deny-missing-docs-crate.rs:1:1
+ |
+LL | / #![deny(missing_docs)]
+LL | |
+LL | | pub struct Foo;
+ | |_______________^
+ |
+note: the lint level is defined here
+ --> $DIR/deny-missing-docs-crate.rs:1:9
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+ --> $DIR/deny-missing-docs-crate.rs:3:1
+ |
+LL | pub struct Foo;
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-macro.rs b/tests/rustdoc-ui/lints/deny-missing-docs-macro.rs
new file mode 100644
index 000000000..b1c125317
--- /dev/null
+++ b/tests/rustdoc-ui/lints/deny-missing-docs-macro.rs
@@ -0,0 +1,8 @@
+//! foo
+
+#![deny(missing_docs)]
+
+#[macro_export]
+macro_rules! foo { //~ ERROR
+ () => {}
+}
diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr b/tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr
new file mode 100644
index 000000000..0867b0818
--- /dev/null
+++ b/tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr
@@ -0,0 +1,14 @@
+error: missing documentation for a macro
+ --> $DIR/deny-missing-docs-macro.rs:6:1
+ |
+LL | macro_rules! foo {
+ | ^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/deny-missing-docs-macro.rs:3:9
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/rustdoc-ui/lints/doc-attr.rs b/tests/rustdoc-ui/lints/doc-attr.rs
new file mode 100644
index 000000000..980d1c0e2
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-attr.rs
@@ -0,0 +1,25 @@
+#![crate_type = "lib"]
+#![deny(warnings)]
+#![doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~^^ WARN
+
+#[doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~^^ WARN
+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() {}
diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr
new file mode 100644
index 000000000..68df2771f
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-attr.stderr
@@ -0,0 +1,71 @@
+error: unknown `doc` attribute `as_ptr`
+ --> $DIR/doc-attr.rs:7:7
+ |
+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 <https://github.com/rust-lang/rust/issues/82730>
+note: the lint level is defined here
+ --> $DIR/doc-attr.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+
+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`
+ --> $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 <https://github.com/rust-lang/rust/issues/82730>
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.fixed b/tests/rustdoc-ui/lints/doc-spotlight.fixed
new file mode 100644
index 000000000..4b58778ea
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-spotlight.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+#![deny(warnings)]
+#![feature(doc_notable_trait)]
+
+#[doc(notable_trait)]
+//~^ ERROR unknown `doc` attribute `spotlight`
+//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+trait MyTrait {}
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.rs b/tests/rustdoc-ui/lints/doc-spotlight.rs
new file mode 100644
index 000000000..16e387245
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-spotlight.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+#![deny(warnings)]
+#![feature(doc_notable_trait)]
+
+#[doc(spotlight)]
+//~^ ERROR unknown `doc` attribute `spotlight`
+//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+trait MyTrait {}
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.stderr b/tests/rustdoc-ui/lints/doc-spotlight.stderr
new file mode 100644
index 000000000..58612327f
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-spotlight.stderr
@@ -0,0 +1,19 @@
+error: unknown `doc` attribute `spotlight`
+ --> $DIR/doc-spotlight.rs:5:7
+ |
+LL | #[doc(spotlight)]
+ | ^^^^^^^^^ help: use `notable_trait` instead
+ |
+ = 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: `doc(spotlight)` was renamed to `doc(notable_trait)`
+ = note: `doc(spotlight)` is now a no-op
+note: the lint level is defined here
+ --> $DIR/doc-spotlight.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+
+error: aborting due to previous error
+
diff --git a/tests/rustdoc-ui/lints/doc-without-codeblock.rs b/tests/rustdoc-ui/lints/doc-without-codeblock.rs
new file mode 100644
index 000000000..86d7c83d3
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-without-codeblock.rs
@@ -0,0 +1,23 @@
+#![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
+pub struct Foo;
+
+/// And then, the princess died.
+//~^ ERROR missing code example in this documentation
+pub mod foo {
+ /// Or maybe not because she saved herself!
+ //~^ ERROR missing code example in this documentation
+ pub fn bar() {}
+}
+
+// This impl is here to ensure the lint isn't emitted for foreign traits implementations.
+impl std::ops::Neg for Foo {
+ type Output = Self;
+
+ fn neg(self) -> Self::Output {
+ Self
+ }
+}
diff --git a/tests/rustdoc-ui/lints/doc-without-codeblock.stderr b/tests/rustdoc-ui/lints/doc-without-codeblock.stderr
new file mode 100644
index 000000000..ebf2a2d54
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc-without-codeblock.stderr
@@ -0,0 +1,38 @@
+error: missing code example in this documentation
+ --> $DIR/doc-without-codeblock.rs:1:1
+ |
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | | #![deny(rustdoc::missing_doc_code_examples)]
+LL | |
+LL | | /// Some docs.
+... |
+LL | | }
+LL | | }
+ | |_^
+ |
+note: the lint level is defined here
+ --> $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:8:1
+ |
+LL | /// And then, the princess died.
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing code example in this documentation
+ --> $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:4:1
+ |
+LL | /// Some docs.
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
new file mode 100644
index 000000000..5d8791748
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
@@ -0,0 +1,11 @@
+#![feature(doc_cfg_hide)]
+#![deny(warnings)]
+
+#![doc(cfg_hide = "test")] //~ ERROR
+//~^ WARN
+#![doc(cfg_hide)] //~ ERROR
+//~^ WARN
+
+#[doc(cfg_hide(doc))] //~ ERROR
+//~^ WARN
+pub fn foo() {}
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
new file mode 100644
index 000000000..b7e8870fd
--- /dev/null
+++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
@@ -0,0 +1,40 @@
+error: this attribute can only be applied at the crate level
+ --> $DIR/doc_cfg_hide.rs:9:7
+ |
+LL | #[doc(cfg_hide(doc))]
+ | ^^^^^^^^^^^^^
+ |
+ = 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
+note: the lint level is defined here
+ --> $DIR/doc_cfg_hide.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+help: to apply to the crate, use an inner attribute
+ |
+LL | #![doc(cfg_hide(doc))]
+ | +
+
+error: `#[doc(cfg_hide(...)]` takes a list of attributes
+ --> $DIR/doc_cfg_hide.rs:4:8
+ |
+LL | #![doc(cfg_hide = "test")]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = 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(cfg_hide(...)]` takes a list of attributes
+ --> $DIR/doc_cfg_hide.rs:6:8
+ |
+LL | #![doc(cfg_hide)]
+ | ^^^^^^^^
+ |
+ = 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 3 previous errors
+
diff --git a/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs
new file mode 100644
index 000000000..0901ac364
--- /dev/null
+++ b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs
@@ -0,0 +1,157 @@
+// check-pass
+#![feature(lint_reasons)]
+
+//! This file tests the `#[expect]` attribute implementation for tool lints. The same
+//! file is used to test clippy and rustdoc. Any changes to this file should be synced
+//! to the other test files as well.
+//!
+//! Expectations:
+//! * rustc: only rustc lint expectations are emitted
+//! * clippy: rustc and Clippy's expectations are emitted
+//! * rustdoc: only rustdoc lint expectations are emitted
+//!
+//! This test can't cover every lint from Clippy, rustdoc and potentially other
+//! tools that will be developed. This therefore only tests a small subset of lints
+
+#![expect(rustdoc::missing_crate_level_docs)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+
+mod rustc_ok {
+ //! See <https://doc.rust-lang.org/rustc/lints/index.html>
+
+ #[expect(dead_code)]
+ pub fn rustc_lints() {
+ let x = 42.0;
+
+ #[expect(illegal_floating_point_literal_pattern)]
+ match x {
+ 5.0 => {}
+ 6.0 => {}
+ _ => {}
+ }
+ }
+}
+
+mod rustc_warn {
+ //! See <https://doc.rust-lang.org/rustc/lints/index.html>
+
+ #[expect(dead_code)]
+ pub fn rustc_lints() {
+ let x = 42;
+
+ #[expect(illegal_floating_point_literal_pattern)]
+ match x {
+ 5 => {}
+ 6 => {}
+ _ => {}
+ }
+ }
+}
+
+pub mod rustdoc_ok {
+ //! See <https://doc.rust-lang.org/rustdoc/lints.html>
+
+ #[expect(rustdoc::broken_intra_doc_links)]
+ /// I want to link to [`Nonexistent`] but it doesn't exist!
+ pub fn foo() {}
+
+ #[expect(rustdoc::invalid_html_tags)]
+ /// <h1>
+ pub fn bar() {}
+
+ #[expect(rustdoc::bare_urls)]
+ /// http://example.org
+ pub fn baz() {}
+}
+
+pub mod rustdoc_warn {
+ //! See <https://doc.rust-lang.org/rustdoc/lints.html>
+
+ #[expect(rustdoc::broken_intra_doc_links)]
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ /// I want to link to [`bar`] but it doesn't exist!
+ pub fn foo() {}
+
+ #[expect(rustdoc::invalid_html_tags)]
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ /// <h1></h1>
+ pub fn bar() {}
+
+ #[expect(rustdoc::bare_urls)]
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ /// <http://example.org>
+ pub fn baz() {}
+}
+
+mod clippy_ok {
+ //! See <https://rust-lang.github.io/rust-clippy/master/index.html>
+
+ #[expect(clippy::almost_swapped)]
+ fn foo() {
+ let mut a = 0;
+ let mut b = 9;
+ a = b;
+ b = a;
+ }
+
+ #[expect(clippy::bytes_nth)]
+ fn bar() {
+ let _ = "Hello".bytes().nth(3);
+ }
+
+ #[expect(clippy::if_same_then_else)]
+ fn baz() {
+ let _ = if true {
+ 42
+ } else {
+ 42
+ };
+ }
+
+ #[expect(clippy::logic_bug)]
+ fn burger() {
+ let a = false;
+ let b = true;
+
+ if a && b || a {}
+ }
+}
+
+mod clippy_warn {
+ //! See <https://rust-lang.github.io/rust-clippy/master/index.html>
+
+ #[expect(clippy::almost_swapped)]
+ fn foo() {
+ let mut a = 0;
+ let mut b = 9;
+ a = b;
+ }
+
+ #[expect(clippy::bytes_nth)]
+ fn bar() {
+ let _ = "Hello".as_bytes().get(3);
+ }
+
+ #[expect(clippy::if_same_then_else)]
+ fn baz() {
+ let _ = if true {
+ 33
+ } else {
+ 42
+ };
+ }
+
+ #[expect(clippy::logic_bug)]
+ fn burger() {
+ let a = false;
+ let b = true;
+ let c = false;
+
+ if a && b || c {}
+ }
+}
+
+fn main() {
+ rustc_warn::rustc_lints();
+}
diff --git a/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr
new file mode 100644
index 000000000..efc5f349f
--- /dev/null
+++ b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr
@@ -0,0 +1,28 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect-tool-lint-rfc-2383.rs:16:11
+ |
+LL | #![expect(rustdoc::missing_crate_level_docs)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect-tool-lint-rfc-2383.rs:71:14
+ |
+LL | #[expect(rustdoc::broken_intra_doc_links)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect-tool-lint-rfc-2383.rs:76:14
+ |
+LL | #[expect(rustdoc::invalid_html_tags)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect-tool-lint-rfc-2383.rs:81:14
+ |
+LL | #[expect(rustdoc::bare_urls)]
+ | ^^^^^^^^^^^^^^^^^^
+
+warning: 4 warnings emitted
+
diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs
new file mode 100644
index 000000000..c34ea0567
--- /dev/null
+++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs
@@ -0,0 +1,12 @@
+#![deny(unknown_lints)]
+//~^ NOTE defined here
+#![allow(rustdoc::missing_doc_code_examples)]
+//~^ ERROR unknown lint
+//~| ERROR unknown lint
+//~| ERROR unknown lint
+//~| NOTE lint is unstable
+//~| NOTE lint is unstable
+//~| NOTE lint is unstable
+//~| NOTE see issue
+//~| NOTE see issue
+//~| NOTE see issue
diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr
new file mode 100644
index 000000000..326dcfe3b
--- /dev/null
+++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr
@@ -0,0 +1,37 @@
+error: unknown lint: `rustdoc::missing_doc_code_examples`
+ --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:3:1
+ |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+ = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+ = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
+note: the lint level is defined here
+ --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9
+ |
+LL | #![deny(unknown_lints)]
+ | ^^^^^^^^^^^^^
+
+error: unknown lint: `rustdoc::missing_doc_code_examples`
+ --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:3:1
+ |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+ = note: see issue #101730 <https://github.com/rust-lang/rust/issues/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:3:1
+ |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+ = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+ = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs
new file mode 100644
index 000000000..c231e43b3
--- /dev/null
+++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs
@@ -0,0 +1,32 @@
+#![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(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() {}
+}
+
+#[doc(inline)]
+#[doc(no_inline)]
+//~^^ ERROR conflicting doc inlining attributes
+//~| HELP remove one of the conflicting attributes
+pub use bar::baz;
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr
new file mode 100644
index 000000000..b23b8ded8
--- /dev/null
+++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr
@@ -0,0 +1,78 @@
+error: this attribute can only be applied at the crate level
+ --> $DIR/invalid-doc-attr.rs:4:7
+ |
+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
+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)]`
+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#inline-and-no_inline> 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: conflicting doc inlining attributes
+ --> $DIR/invalid-doc-attr.rs:28:7
+ |
+LL | #[doc(inline)]
+ | ^^^^^^ this attribute...
+LL | #[doc(no_inline)]
+ | ^^^^^^^^^ ...conflicts with this attribute
+ |
+ = help: remove one of the conflicting attributes
+
+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#inline-and-no_inline> for more information
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs
new file mode 100644
index 000000000..d973a53cb
--- /dev/null
+++ b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs
@@ -0,0 +1,70 @@
+#![deny(rustdoc::invalid_html_tags)]
+
+/// <p/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct A;
+
+/// <p style/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct B;
+
+/// <p style=""/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct C;
+
+/// <p style="x"/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct D;
+
+/// <p style="x/></p>
+//~^ ERROR unclosed quoted HTML attribute
+pub struct E;
+
+/// <p style='x/></p>
+//~^ ERROR unclosed quoted HTML attribute
+pub struct F;
+
+/// <p style="x/"></p>
+pub struct G;
+
+/// <p style="x/"/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct H;
+
+/// <p / >
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct I;
+
+/// <br/>
+pub struct J;
+
+/// <a href=/></a>
+pub struct K;
+
+/// <a href=//></a>
+pub struct L;
+
+/// <a href="/"/>
+//~^ ERROR invalid self-closing HTML tag `a`
+pub struct M;
+
+/// <a href=x />
+//~^ ERROR invalid self-closing HTML tag `a`
+pub struct N;
+
+/// <a href= />
+//~^ ERROR invalid self-closing HTML tag `a`
+pub struct O;
+
+/// <a href=x/></a>
+pub struct P;
+
+/// <svg><rect width=1 height=1 /></svg>
+pub struct Q;
+
+/// <svg><rect width=1 height=/></svg>
+//~^ ERROR unclosed HTML tag `rect`
+pub struct R;
+
+/// <svg / q>
+pub struct S;
diff --git a/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr
new file mode 100644
index 000000000..e45edfb43
--- /dev/null
+++ b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr
@@ -0,0 +1,80 @@
+error: invalid self-closing HTML tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:3:5
+ |
+LL | /// <p/>
+ | ^^
+ |
+note: the lint level is defined here
+ --> $DIR/invalid-html-self-closing-tag.rs:1:9
+ |
+LL | #![deny(rustdoc::invalid_html_tags)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: invalid self-closing HTML tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:7:5
+ |
+LL | /// <p style/>
+ | ^^
+
+error: invalid self-closing HTML tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:11:5
+ |
+LL | /// <p style=""/>
+ | ^^
+
+error: invalid self-closing HTML tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:15:5
+ |
+LL | /// <p style="x"/>
+ | ^^
+
+error: unclosed quoted HTML attribute on tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:19:14
+ |
+LL | /// <p style="x/></p>
+ | ^
+
+error: unclosed quoted HTML attribute on tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:23:14
+ |
+LL | /// <p style='x/></p>
+ | ^
+
+error: invalid self-closing HTML tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:30:5
+ |
+LL | /// <p style="x/"/>
+ | ^^
+
+error: invalid self-closing HTML tag `p`
+ --> $DIR/invalid-html-self-closing-tag.rs:34:5
+ |
+LL | /// <p / >
+ | ^^
+
+error: invalid self-closing HTML tag `a`
+ --> $DIR/invalid-html-self-closing-tag.rs:47:5
+ |
+LL | /// <a href="/"/>
+ | ^^
+
+error: invalid self-closing HTML tag `a`
+ --> $DIR/invalid-html-self-closing-tag.rs:51:5
+ |
+LL | /// <a href=x />
+ | ^^
+
+error: invalid self-closing HTML tag `a`
+ --> $DIR/invalid-html-self-closing-tag.rs:55:5
+ |
+LL | /// <a href= />
+ | ^^
+
+error: unclosed HTML tag `rect`
+ --> $DIR/invalid-html-self-closing-tag.rs:65:10
+ |
+LL | /// <svg><rect width=1 height=/></svg>
+ | ^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/rustdoc-ui/lints/invalid-html-tags.rs b/tests/rustdoc-ui/lints/invalid-html-tags.rs
new file mode 100644
index 000000000..317f1fd1d
--- /dev/null
+++ b/tests/rustdoc-ui/lints/invalid-html-tags.rs
@@ -0,0 +1,123 @@
+#![deny(rustdoc::invalid_html_tags)]
+
+//! <p>💩<p>
+//~^ ERROR unclosed HTML tag `p`
+//~^^ ERROR unclosed HTML tag `p`
+
+/// <img><input>
+/// <script>
+/// <img><input>
+/// </script>
+/// <unknown>
+//~^ ERROR unclosed HTML tag `unknown`
+/// < ok
+/// <script>
+//~^ ERROR unclosed HTML tag `script`
+pub fn foo() {}
+
+/// <h1>
+/// <h2>
+//~^ ERROR unclosed HTML tag `h2`
+/// <h3>
+//~^ ERROR unclosed HTML tag `h3`
+/// </h1>
+/// </hello>
+//~^ ERROR unopened HTML tag `hello`
+pub fn bar() {}
+
+/// <div>
+/// <br/> <p>
+//~^ ERROR unclosed HTML tag `p`
+/// </div>
+pub fn a() {}
+
+/// <div>
+/// <p>
+/// <div></div>
+/// </p>
+/// </div>
+pub fn b() {}
+
+/// <div style="hello">
+//~^ ERROR unclosed HTML tag `div`
+/// <h3>
+//~^ ERROR unclosed HTML tag `h3`
+/// <script
+//~^ ERROR unclosed HTML tag `script`
+pub fn c() {}
+
+// Unclosed tags shouldn't warn if they are nested inside a <script> elem.
+/// <script>
+/// <h3><div>
+/// </script>
+/// <script>
+/// <div>
+/// <p>
+/// </div>
+/// </script>
+pub fn d() {}
+
+// Unclosed tags shouldn't warn if they are nested inside a <style> elem.
+/// <style>
+/// <h3><div>
+/// </style>
+/// <stYle>
+/// <div>
+/// <p>
+/// </div>
+/// </style>
+pub fn e() {}
+
+// Closing tags need to have ">" at the end, otherwise it's not a closing tag!
+/// <div></div >
+/// <div></div
+//~^ ERROR unclosed HTML tag `div`
+pub fn f() {}
+
+/// <!---->
+/// <!-- -->
+/// <!-- <div> -->
+/// <!-- <!-- -->
+pub fn g() {}
+
+/// <!--
+/// -->
+pub fn h() {}
+
+/// <!--
+//~^ ERROR Unclosed HTML comment
+pub fn i() {}
+
+/// hello
+///
+/// ```
+/// uiapp.run(&env::args().collect::<Vec<_>>());
+/// ```
+pub fn j() {}
+
+// Check that nested codeblocks are working as well
+/// hello
+///
+/// ``````markdown
+/// normal markdown
+///
+/// ```
+/// uiapp.run(&env::args().collect::<Vec<_>>());
+/// ```
+///
+/// <Vec<_> shouldn't warn!
+/// ``````
+pub fn k() {}
+
+/// Web Components style <dashed-tags>
+//~^ ERROR unclosed HTML tag `dashed-tags`
+/// Web Components style </unopened-tag>
+//~^ ERROR unopened HTML tag `unopened-tag`
+pub fn m() {}
+
+/// backslashed \<a href="">
+pub fn no_error_1() {}
+
+/// backslashed \<<a href="">
+//~^ ERROR unclosed HTML tag `a`
+pub fn p() {}
diff --git a/tests/rustdoc-ui/lints/invalid-html-tags.stderr b/tests/rustdoc-ui/lints/invalid-html-tags.stderr
new file mode 100644
index 000000000..9c2bfcf2c
--- /dev/null
+++ b/tests/rustdoc-ui/lints/invalid-html-tags.stderr
@@ -0,0 +1,104 @@
+error: unclosed HTML tag `p`
+ --> $DIR/invalid-html-tags.rs:3:5
+ |
+LL | //! <p>💩<p>
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/invalid-html-tags.rs:1:9
+ |
+LL | #![deny(rustdoc::invalid_html_tags)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unclosed HTML tag `p`
+ --> $DIR/invalid-html-tags.rs:3:9
+ |
+LL | //! <p>💩<p>
+ | ^^^
+
+error: unclosed HTML tag `unknown`
+ --> $DIR/invalid-html-tags.rs:11:5
+ |
+LL | /// <unknown>
+ | ^^^^^^^^^
+
+error: unclosed HTML tag `script`
+ --> $DIR/invalid-html-tags.rs:14:5
+ |
+LL | /// <script>
+ | ^^^^^^^^
+
+error: unclosed HTML tag `h2`
+ --> $DIR/invalid-html-tags.rs:19:7
+ |
+LL | /// <h2>
+ | ^^^^
+
+error: unclosed HTML tag `h3`
+ --> $DIR/invalid-html-tags.rs:21:9
+ |
+LL | /// <h3>
+ | ^^^^
+
+error: unopened HTML tag `hello`
+ --> $DIR/invalid-html-tags.rs:24:5
+ |
+LL | /// </hello>
+ | ^^^^^^^^
+
+error: unclosed HTML tag `p`
+ --> $DIR/invalid-html-tags.rs:29:14
+ |
+LL | /// <br/> <p>
+ | ^^^
+
+error: unclosed HTML tag `div`
+ --> $DIR/invalid-html-tags.rs:41:5
+ |
+LL | /// <div style="hello">
+ | ^^^^
+
+error: unclosed HTML tag `h3`
+ --> $DIR/invalid-html-tags.rs:43:7
+ |
+LL | /// <h3>
+ | ^^^^
+
+error: unclosed HTML tag `script`
+ --> $DIR/invalid-html-tags.rs:45:5
+ |
+LL | /// <script
+ | ^^^^^^
+
+error: unclosed HTML tag `div`
+ --> $DIR/invalid-html-tags.rs:73:5
+ |
+LL | /// <div></div
+ | ^^^^^
+
+error: Unclosed HTML comment
+ --> $DIR/invalid-html-tags.rs:87:5
+ |
+LL | /// <!--
+ | ^^^
+
+error: unopened HTML tag `unopened-tag`
+ --> $DIR/invalid-html-tags.rs:114:26
+ |
+LL | /// Web Components style </unopened-tag>
+ | ^^^^^^^^^^^^^^^
+
+error: unclosed HTML tag `dashed-tags`
+ --> $DIR/invalid-html-tags.rs:112:26
+ |
+LL | /// Web Components style <dashed-tags>
+ | ^^^^^^^^^^^^^
+
+error: unclosed HTML tag `a`
+ --> $DIR/invalid-html-tags.rs:121:19
+ |
+LL | /// backslashed \<<a href="">
+ | ^^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/rustdoc-ui/lints/lint-group.rs b/tests/rustdoc-ui/lints/lint-group.rs
new file mode 100644
index 000000000..ad88157f6
--- /dev/null
+++ b/tests/rustdoc-ui/lints/lint-group.rs
@@ -0,0 +1,32 @@
+#![feature(rustdoc_missing_doc_code_examples)]
+
+//! Documenting the kinds of lints emitted by rustdoc.
+//!
+//! ```
+//! println!("sup");
+//! ```
+
+#![deny(rustdoc::missing_doc_code_examples)]
+#![deny(rustdoc::all)]
+
+/// what up, let's make an [error]
+///
+/// ```
+/// println!("sup");
+/// ```
+pub fn link_error() {} //~^^^^^ ERROR unresolved link to `error`
+
+/// wait, this doesn't have a doctest?
+pub fn no_doctest() {} //~^ ERROR missing code example in this documentation
+
+/// wait, this *does* have a doctest?
+///
+/// ```
+/// println!("sup");
+/// ```
+fn private_doctest() {} //~^^^^^ ERROR documentation test in private item
+
+/// <unknown>
+//~^ ERROR unclosed HTML tag `unknown`
+//~^^ ERROR missing code example
+pub fn c() {}
diff --git a/tests/rustdoc-ui/lints/lint-group.stderr b/tests/rustdoc-ui/lints/lint-group.stderr
new file mode 100644
index 000000000..7ff09fcc4
--- /dev/null
+++ b/tests/rustdoc-ui/lints/lint-group.stderr
@@ -0,0 +1,54 @@
+error: missing code example in this documentation
+ --> $DIR/lint-group.rs:19:1
+ |
+LL | /// wait, this doesn't have a doctest?
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-group.rs:9:9
+ |
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: documentation test in private item
+ --> $DIR/lint-group.rs:22:1
+ |
+LL | / /// wait, this *does* have a doctest?
+LL | | ///
+LL | | /// ```
+LL | | /// println!("sup");
+LL | | /// ```
+ | |_______^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-group.rs:10:9
+ |
+LL | #![deny(rustdoc::all)]
+ | ^^^^^^^^^^^^
+ = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]`
+
+error: missing code example in this documentation
+ --> $DIR/lint-group.rs:29:1
+ |
+LL | /// <unknown>
+ | ^^^^^^^^^^^^^
+
+error: unresolved link to `error`
+ --> $DIR/lint-group.rs:12:29
+ |
+LL | /// what up, let's make an [error]
+ | ^^^^^ no item named `error` in scope
+ |
+ = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]`
+
+error: unclosed HTML tag `unknown`
+ --> $DIR/lint-group.rs:29:5
+ |
+LL | /// <unknown>
+ | ^^^^^^^^^
+ |
+ = note: `#[deny(rustdoc::invalid_html_tags)]` implied by `#[deny(rustdoc::all)]`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs
new file mode 100644
index 000000000..40f35728d
--- /dev/null
+++ b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs
@@ -0,0 +1,101 @@
+#![feature(rustdoc_missing_doc_code_examples)]
+#![deny(missing_docs)]
+#![deny(rustdoc::missing_doc_code_examples)]
+
+//! crate level doc
+//! ```
+//! println!("hello"):
+//! ```
+
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+pub fn test() {
+}
+
+#[allow(missing_docs)]
+pub mod module1 { //~ ERROR
+}
+
+#[allow(rustdoc::missing_doc_code_examples)]
+/// doc
+pub mod module2 {
+
+ /// doc
+ pub fn test() {}
+}
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+pub mod module3 {
+
+ /// doc
+ //~^ ERROR
+ pub fn test() {}
+}
+
+/// Doc, but no code example and it's fine!
+pub const Const: u32 = 0;
+/// Doc, but no code example and it's fine!
+pub static Static: u32 = 0;
+/// Doc, but no code example and it's fine!
+pub type Type = u32;
+
+/// Doc
+//~^ ERROR
+pub struct Struct {
+ /// Doc, but no code example and it's fine!
+ pub field: u32,
+}
+
+/// Doc
+//~^ ERROR
+pub enum Enum {
+ /// Doc, but no code example and it's fine!
+ X,
+}
+
+/// Doc
+//~^ ERROR
+#[repr(C)]
+pub union Union {
+ /// Doc, but no code example and it's fine!
+ a: i32,
+ /// Doc, but no code example and it's fine!
+ b: f32,
+}
+
+// no code example and it's fine!
+impl Clone for Struct {
+ fn clone(&self) -> Self {
+ Self { field: self.field }
+ }
+}
+
+
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+#[derive(Clone)]
+pub struct NiceStruct;
+
+#[doc(hidden)]
+pub mod foo {
+ pub fn bar() {}
+}
+
+fn babar() {}
+
+
+mod fofoo {
+ pub fn tadam() {}
+}
diff --git a/tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr
new file mode 100644
index 000000000..f93312501
--- /dev/null
+++ b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr
@@ -0,0 +1,38 @@
+error: missing code example in this documentation
+ --> $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:3:9
+ |
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing code example in this documentation
+ --> $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:50:1
+ |
+LL | /// Doc
+ | ^^^^^^^
+
+error: missing code example in this documentation
+ --> $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:64:1
+ |
+LL | /// Doc
+ | ^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs
new file mode 100644
index 000000000..a186410ac
--- /dev/null
+++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs
@@ -0,0 +1,6 @@
+// error-pattern: no documentation found
+// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
+#![deny(rustdoc::missing_crate_level_docs)]
+//^~ NOTE defined here
+
+pub fn foo() {}
diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr
new file mode 100644
index 000000000..fb3a5e415
--- /dev/null
+++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr
@@ -0,0 +1,12 @@
+error: no documentation found for this crate's top-level module
+ |
+ = help: The following guide may be of use:
+ https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
+note: the lint level is defined here
+ --> $DIR/no-crate-level-doc-lint.rs:3:9
+ |
+LL | #![deny(rustdoc::missing_crate_level_docs)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs b/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs
new file mode 100644
index 000000000..a4d3a4b49
--- /dev/null
+++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs
@@ -0,0 +1,10 @@
+// compile-args: --crate-type lib
+#![deny(broken_intra_doc_links)]
+//~^ WARNING renamed to `rustdoc::broken_intra_doc_links`
+//! [x]
+//~^ ERROR unresolved link
+
+#![deny(rustdoc::non_autolinks)]
+//~^ WARNING renamed to `rustdoc::bare_urls`
+//! http://example.com
+//~^ ERROR not a hyperlink
diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr
new file mode 100644
index 000000000..ee9b67cb9
--- /dev/null
+++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr
@@ -0,0 +1,42 @@
+warning: lint `broken_intra_doc_links` has been renamed to `rustdoc::broken_intra_doc_links`
+ --> $DIR/renamed-lint-still-applies.rs:2:9
+ |
+LL | #![deny(broken_intra_doc_links)]
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links`
+ |
+ = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+warning: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls`
+ --> $DIR/renamed-lint-still-applies.rs:7:9
+ |
+LL | #![deny(rustdoc::non_autolinks)]
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls`
+
+error: unresolved link to `x`
+ --> $DIR/renamed-lint-still-applies.rs:4:6
+ |
+LL | //! [x]
+ | ^ no item named `x` in scope
+ |
+ = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+note: the lint level is defined here
+ --> $DIR/renamed-lint-still-applies.rs:2:9
+ |
+LL | #![deny(broken_intra_doc_links)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: this URL is not a hyperlink
+ --> $DIR/renamed-lint-still-applies.rs:9:5
+ |
+LL | //! http://example.com
+ | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.com>`
+ |
+ = note: bare URLs are not automatically turned into clickable links
+note: the lint level is defined here
+ --> $DIR/renamed-lint-still-applies.rs:7:9
+ |
+LL | #![deny(rustdoc::non_autolinks)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
diff --git a/tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs b/tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs
new file mode 100644
index 000000000..e106d06af
--- /dev/null
+++ b/tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs
@@ -0,0 +1,6 @@
+// check-pass
+
+// Ensure `rustdoc::all` only affects stable lints. See #106289.
+
+#![deny(unknown_lints)]
+#![allow(rustdoc::all)]
diff --git a/tests/rustdoc-ui/lints/unknown-renamed-lints.rs b/tests/rustdoc-ui/lints/unknown-renamed-lints.rs
new file mode 100644
index 000000000..ddf03dd07
--- /dev/null
+++ b/tests/rustdoc-ui/lints/unknown-renamed-lints.rs
@@ -0,0 +1,24 @@
+#![deny(unknown_lints)]
+//~^ NOTE lint level is defined
+#![deny(renamed_and_removed_lints)]
+//~^ NOTE lint level is defined
+#![deny(x)]
+//~^ ERROR unknown lint
+#![deny(rustdoc::x)]
+//~^ ERROR unknown lint: `rustdoc::x`
+#![deny(intra_doc_link_resolution_failure)]
+//~^ ERROR renamed to `rustdoc::broken_intra_doc_links`
+#![deny(non_autolinks)]
+//~^ ERROR renamed to `rustdoc::bare_urls`
+#![deny(rustdoc::non_autolinks)]
+//~^ ERROR renamed to `rustdoc::bare_urls`
+
+#![deny(private_doc_tests)]
+//~^ ERROR renamed to `rustdoc::private_doc_tests`
+
+#![deny(rustdoc)]
+//~^ ERROR removed: use `rustdoc::all` instead
+
+// Explicitly don't try to handle this case, it was never valid
+#![deny(rustdoc::intra_doc_link_resolution_failure)]
+//~^ ERROR unknown lint
diff --git a/tests/rustdoc-ui/lints/unknown-renamed-lints.stderr b/tests/rustdoc-ui/lints/unknown-renamed-lints.stderr
new file mode 100644
index 000000000..bf529b9f8
--- /dev/null
+++ b/tests/rustdoc-ui/lints/unknown-renamed-lints.stderr
@@ -0,0 +1,62 @@
+error: unknown lint: `x`
+ --> $DIR/unknown-renamed-lints.rs:5:9
+ |
+LL | #![deny(x)]
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/unknown-renamed-lints.rs:1:9
+ |
+LL | #![deny(unknown_lints)]
+ | ^^^^^^^^^^^^^
+
+error: unknown lint: `rustdoc::x`
+ --> $DIR/unknown-renamed-lints.rs:7:9
+ |
+LL | #![deny(rustdoc::x)]
+ | ^^^^^^^^^^ help: did you mean: `rustdoc::all`
+
+error: lint `intra_doc_link_resolution_failure` has been renamed to `rustdoc::broken_intra_doc_links`
+ --> $DIR/unknown-renamed-lints.rs:9:9
+ |
+LL | #![deny(intra_doc_link_resolution_failure)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links`
+ |
+note: the lint level is defined here
+ --> $DIR/unknown-renamed-lints.rs:3:9
+ |
+LL | #![deny(renamed_and_removed_lints)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: lint `non_autolinks` has been renamed to `rustdoc::bare_urls`
+ --> $DIR/unknown-renamed-lints.rs:11:9
+ |
+LL | #![deny(non_autolinks)]
+ | ^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls`
+
+error: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls`
+ --> $DIR/unknown-renamed-lints.rs:13:9
+ |
+LL | #![deny(rustdoc::non_autolinks)]
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls`
+
+error: lint `private_doc_tests` has been renamed to `rustdoc::private_doc_tests`
+ --> $DIR/unknown-renamed-lints.rs:16:9
+ |
+LL | #![deny(private_doc_tests)]
+ | ^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::private_doc_tests`
+
+error: lint `rustdoc` has been removed: use `rustdoc::all` instead
+ --> $DIR/unknown-renamed-lints.rs:19:9
+ |
+LL | #![deny(rustdoc)]
+ | ^^^^^^^
+
+error: unknown lint: `rustdoc::intra_doc_link_resolution_failure`
+ --> $DIR/unknown-renamed-lints.rs:23:9
+ |
+LL | #![deny(rustdoc::intra_doc_link_resolution_failure)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/rustdoc-ui/lints/unused-braces-lint.rs b/tests/rustdoc-ui/lints/unused-braces-lint.rs
new file mode 100644
index 000000000..be0e31e4b
--- /dev/null
+++ b/tests/rustdoc-ui/lints/unused-braces-lint.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+// This tests the bug in #70814, where the unused_braces lint triggered on the following code
+// without providing a span.
+
+#![deny(unused_braces)]
+
+fn main() {
+ {
+ {
+ use std;
+ }
+ }
+}
diff --git a/tests/rustdoc-ui/lints/unused.rs b/tests/rustdoc-ui/lints/unused.rs
new file mode 100644
index 000000000..702b24c36
--- /dev/null
+++ b/tests/rustdoc-ui/lints/unused.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+// This test purpose is to check that unused_imports lint isn't fired
+// by rustdoc. Why would it? Because when rustdoc is running, it uses
+// "everybody-loops" which replaces parts of code with "loop {}" to get
+// huge performance improvements.
+
+#![deny(unused_imports)]
+
+use std::fs::File;
+
+pub fn f() {
+ let _: File;
+}