about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-20 02:58:08 +0000
committerbors <bors@rust-lang.org>2024-01-20 02:58:08 +0000
commit128148d4cf742c3056e9bfc65e7cc9531cb0f815 (patch)
tree0eedeffb6a188f3dd18f99d070ba66e814779213 /tests
parent0547c41f906760ce117a55ca690820b44d8e7eef (diff)
parentee126973b0075060d9d95e401533181c5e8c5864 (diff)
Auto merge of #120136 - matthiaskrgr:rollup-3zzb0z9, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #117561 (Stabilize `slice_first_last_chunk`)
 - #117662 ([rustdoc] Allows links in headings)
 - #119815 (Format sources into the error message when loading codegen backends)
 - #119835 (Exhaustiveness: simplify empty pattern logic)
 - #119984 (Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`.)
 - #120009 (never_patterns: typecheck never patterns)
 - #120122 (Don't add needs-triage to A-diagnostics)
 - #120126 (Suggest `.swap()` when encountering conflicting borrows from `mem::swap` on a slice)
 - #120134 (Restrict access to the private field of newtype indexes)

Failed merges:

 - #119968 (Remove unused/unnecessary features)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'tests')
-rw-r--r--tests/coverage/async.coverage3
-rw-r--r--tests/coverage/async.rs3
-rw-r--r--tests/coverage/async2.coverage3
-rw-r--r--tests/coverage/async2.rs3
-rw-r--r--tests/coverage/async_block.coverage3
-rw-r--r--tests/coverage/async_block.rs3
-rw-r--r--tests/coverage/closure_macro_async.coverage3
-rw-r--r--tests/coverage/closure_macro_async.rs3
-rw-r--r--tests/rustdoc-gui/docblock-details.goml2
-rw-r--r--tests/rustdoc-gui/headers-color.goml8
-rw-r--r--tests/rustdoc-gui/headings-anchor.goml32
-rw-r--r--tests/rustdoc/disambiguate-anchors-header-29449.rs15
-rw-r--r--tests/rustdoc/links-in-headings.rs14
-rw-r--r--tests/rustdoc/remove-url-from-headings.rs11
-rw-r--r--tests/rustdoc/short-docblock.rs6
-rw-r--r--tests/ui/async-await/for-await-passthrough.rs3
-rw-r--r--tests/ui/async-await/for-await.rs3
-rw-r--r--tests/ui/async-await/in-trait/async-default-fn-overridden.rs3
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs3
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr2
-rw-r--r--tests/ui/coroutine/async-gen-yield-ty-is-unit.rs3
-rw-r--r--tests/ui/coroutine/async_gen_fn_iter.rs3
-rw-r--r--tests/ui/dyn-star/dispatch-on-pin-mut.rs5
-rw-r--r--tests/ui/pattern/never_patterns.rs73
-rw-r--r--tests/ui/pattern/never_patterns.stderr17
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/typeck.fail.stderr66
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs125
-rw-r--r--tests/ui/suggestions/suggest-slice-swap.fixed9
-rw-r--r--tests/ui/suggestions/suggest-slice-swap.rs9
-rw-r--r--tests/ui/suggestions/suggest-slice-swap.stderr17
30 files changed, 315 insertions, 138 deletions
diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage
index 015e03d5165..23161458850 100644
--- a/tests/coverage/async.coverage
+++ b/tests/coverage/async.coverage
@@ -117,8 +117,7 @@
    LL|       |    #[coverage(off)]
    LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
    LL|       |        let mut future = pin!(future);
-   LL|       |        let waker = Waker::noop();
-   LL|       |        let mut context = Context::from_waker(&waker);
+   LL|       |        let mut context = Context::from_waker(Waker::noop());
    LL|       |
    LL|       |        loop {
    LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs
index abc9e5f7f64..df29682968d 100644
--- a/tests/coverage/async.rs
+++ b/tests/coverage/async.rs
@@ -110,8 +110,7 @@ mod executor {
     #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
         let mut future = pin!(future);
-        let waker = Waker::noop();
-        let mut context = Context::from_waker(&waker);
+        let mut context = Context::from_waker(Waker::noop());
 
         loop {
             if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage
index acd83de9493..a69eefe72cb 100644
--- a/tests/coverage/async2.coverage
+++ b/tests/coverage/async2.coverage
@@ -41,8 +41,7 @@
    LL|       |    #[coverage(off)]
    LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
    LL|       |        let mut future = pin!(future);
-   LL|       |        let waker = Waker::noop();
-   LL|       |        let mut context = Context::from_waker(&waker);
+   LL|       |        let mut context = Context::from_waker(Waker::noop());
    LL|       |
    LL|       |        loop {
    LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/async2.rs b/tests/coverage/async2.rs
index 393573f7dc9..ae83f0103e6 100644
--- a/tests/coverage/async2.rs
+++ b/tests/coverage/async2.rs
@@ -39,8 +39,7 @@ mod executor {
     #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
         let mut future = pin!(future);
-        let waker = Waker::noop();
-        let mut context = Context::from_waker(&waker);
+        let mut context = Context::from_waker(Waker::noop());
 
         loop {
             if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/async_block.coverage b/tests/coverage/async_block.coverage
index 297397ca26c..0e24b80124f 100644
--- a/tests/coverage/async_block.coverage
+++ b/tests/coverage/async_block.coverage
@@ -24,8 +24,7 @@
    LL|       |    #[coverage(off)]
    LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
    LL|       |        let mut future = pin!(future);
-   LL|       |        let waker = Waker::noop();
-   LL|       |        let mut context = Context::from_waker(&waker);
+   LL|       |        let mut context = Context::from_waker(Waker::noop());
    LL|       |
    LL|       |        loop {
    LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/async_block.rs b/tests/coverage/async_block.rs
index 9d8647bf1f2..f94bcfe3193 100644
--- a/tests/coverage/async_block.rs
+++ b/tests/coverage/async_block.rs
@@ -23,8 +23,7 @@ mod executor {
     #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
         let mut future = pin!(future);
-        let waker = Waker::noop();
-        let mut context = Context::from_waker(&waker);
+        let mut context = Context::from_waker(Waker::noop());
 
         loop {
             if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage
index 2c9bd4ac97a..2336d4d0528 100644
--- a/tests/coverage/closure_macro_async.coverage
+++ b/tests/coverage/closure_macro_async.coverage
@@ -54,8 +54,7 @@
    LL|       |    #[coverage(off)]
    LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
    LL|       |        let mut future = pin!(future);
-   LL|       |        let waker = Waker::noop();
-   LL|       |        let mut context = Context::from_waker(&waker);
+   LL|       |        let mut context = Context::from_waker(Waker::noop());
    LL|       |
    LL|       |        loop {
    LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/coverage/closure_macro_async.rs b/tests/coverage/closure_macro_async.rs
index a7f0cabb4c2..9f5721b5e26 100644
--- a/tests/coverage/closure_macro_async.rs
+++ b/tests/coverage/closure_macro_async.rs
@@ -53,8 +53,7 @@ mod executor {
     #[coverage(off)]
     pub fn block_on<F: Future>(mut future: F) -> F::Output {
         let mut future = pin!(future);
-        let waker = Waker::noop();
-        let mut context = Context::from_waker(&waker);
+        let mut context = Context::from_waker(Waker::noop());
 
         loop {
             if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
diff --git a/tests/rustdoc-gui/docblock-details.goml b/tests/rustdoc-gui/docblock-details.goml
index 8e6d2ba824f..4b8f5b54fac 100644
--- a/tests/rustdoc-gui/docblock-details.goml
+++ b/tests/rustdoc-gui/docblock-details.goml
@@ -6,7 +6,7 @@ reload:
 
 // We first check that the headers in the `.top-doc` doc block still have their
 // bottom border.
-assert-text: (".top-doc .docblock > h3", "Hello")
+assert-text: (".top-doc .docblock > h3", "§Hello")
 assert-css: (
     ".top-doc .docblock > h3",
     {"border-bottom": "1px solid #d2d2d2"},
diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml
index 19185818f40..80d11c9c849 100644
--- a/tests/rustdoc-gui/headers-color.goml
+++ b/tests/rustdoc-gui/headers-color.goml
@@ -1,4 +1,4 @@
-// This test check for headers text and background colors for the different themes.
+// This test check for headings text and background colors for the different themes.
 
 define-function: (
     "check-colors",
@@ -45,7 +45,7 @@ call-function: (
         "color": "#c5c5c5",
         "code_header_color": "#e6e1cf",
         "focus_background_color": "rgba(255, 236, 164, 0.06)",
-        "headings_color": "#39afd7",
+        "headings_color": "#c5c5c5",
     },
 )
 call-function: (
@@ -55,7 +55,7 @@ call-function: (
         "color": "#ddd",
         "code_header_color": "#ddd",
         "focus_background_color": "#494a3d",
-        "headings_color": "#d2991d",
+        "headings_color": "#ddd",
     },
 )
 call-function: (
@@ -65,6 +65,6 @@ call-function: (
         "color": "black",
         "code_header_color": "black",
         "focus_background_color": "#fdffd3",
-        "headings_color": "#3873ad",
+        "headings_color": "black",
     },
 )
diff --git a/tests/rustdoc-gui/headings-anchor.goml b/tests/rustdoc-gui/headings-anchor.goml
new file mode 100644
index 00000000000..f568caa3b07
--- /dev/null
+++ b/tests/rustdoc-gui/headings-anchor.goml
@@ -0,0 +1,32 @@
+// Test to ensure that the headings anchor behave as expected.
+go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
+show-text: true
+
+define-function: (
+    "check-heading-anchor",
+    (heading_id),
+    block {
+        // The anchor should not be displayed by default.
+        assert-css: ("#" + |heading_id| + " .doc-anchor", { "display": "none" })
+        // We ensure that hovering the heading makes the anchor visible.
+        move-cursor-to: "#" + |heading_id|
+        assert-css: ("#" + |heading_id| + ":hover .doc-anchor", { "display": "block" })
+        // We then ensure that moving from the heading to the anchor doesn't make the anchor
+        // disappear.
+        move-cursor-to: "#" + |heading_id| + " .doc-anchor"
+        assert-css: ("#" + |heading_id| + " .doc-anchor:hover", {
+            "display": "block",
+            // We also ensure that there is no underline decoration.
+            "text-decoration-line": "none",
+        })
+    }
+)
+
+move-cursor-to: "#top-doc-prose-title"
+// If the top documentation block first element is a heading, we should never display its anchor
+// to prevent it from overlapping with the `[-]` element.
+assert-css: ("#top-doc-prose-title:hover .doc-anchor", { "display": "none" })
+
+call-function: ("check-heading-anchor", ("top-doc-prose-sub-heading"))
+call-function: ("check-heading-anchor", ("top-doc-prose-sub-sub-heading"))
+call-function: ("check-heading-anchor", ("you-know-the-drill"))
diff --git a/tests/rustdoc/disambiguate-anchors-header-29449.rs b/tests/rustdoc/disambiguate-anchors-header-29449.rs
index 38a4954fc13..1388af7df4b 100644
--- a/tests/rustdoc/disambiguate-anchors-header-29449.rs
+++ b/tests/rustdoc/disambiguate-anchors-header-29449.rs
@@ -5,18 +5,23 @@
 pub struct Foo;
 
 impl Foo {
-    // @has - '//*[@id="examples"]//a' 'Examples'
-    // @has - '//*[@id="panics"]//a' 'Panics'
+    // @has - '//*[@id="examples"]' 'Examples'
+    // @has - '//*[@id="examples"]/a[@href="#examples"]' '§'
+    // @has - '//*[@id="panics"]' 'Panics'
+    // @has - '//*[@id="panics"]/a[@href="#panics"]' '§'
     /// # Examples
     /// # Panics
     pub fn bar() {}
 
-    // @has - '//*[@id="examples-1"]//a' 'Examples'
+    // @has - '//*[@id="examples-1"]' 'Examples'
+    // @has - '//*[@id="examples-1"]/a[@href="#examples-1"]' '§'
     /// # Examples
     pub fn bar_1() {}
 
-    // @has - '//*[@id="examples-2"]//a' 'Examples'
-    // @has - '//*[@id="panics-1"]//a' 'Panics'
+    // @has - '//*[@id="examples-2"]' 'Examples'
+    // @has - '//*[@id="examples-2"]/a[@href="#examples-2"]' '§'
+    // @has - '//*[@id="panics-1"]' 'Panics'
+    // @has - '//*[@id="panics-1"]/a[@href="#panics-1"]' '§'
     /// # Examples
     /// # Panics
     pub fn bar_2() {}
diff --git a/tests/rustdoc/links-in-headings.rs b/tests/rustdoc/links-in-headings.rs
new file mode 100644
index 00000000000..c5bee1a7975
--- /dev/null
+++ b/tests/rustdoc/links-in-headings.rs
@@ -0,0 +1,14 @@
+#![crate_name = "foo"]
+
+//! # Heading with [a link](https://a.com) inside
+//!
+//! And even with
+//!
+//! ## [multiple](https://b.com) [links](https://c.com)
+//!
+//! !
+
+// @has 'foo/index.html'
+// @has - '//h2/a[@href="https://a.com"]' 'a link'
+// @has - '//h3/a[@href="https://b.com"]' 'multiple'
+// @has - '//h3/a[@href="https://c.com"]' 'links'
diff --git a/tests/rustdoc/remove-url-from-headings.rs b/tests/rustdoc/remove-url-from-headings.rs
index 599c429a6e1..8f477028619 100644
--- a/tests/rustdoc/remove-url-from-headings.rs
+++ b/tests/rustdoc/remove-url-from-headings.rs
@@ -1,9 +1,12 @@
+// It actually checks that the link is kept in the headings as expected now.
+
 #![crate_name = "foo"]
 
 // @has foo/fn.foo.html
-// @!has - '//a[@href="http://a.a"]' ''
-// @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere'
-// @has - '//a[@href="#another-one-urg"]' 'Another one urg'
+// @has - '//a[@href="http://a.a"]' 'stuff'
+// @has - '//*[@id="implementing-stuff-somewhere"]' 'Implementing stuff somewhere'
+// @has - '//a[@href="http://b.b"]' 'one'
+// @has - '//*[@id="another-one-urg"]' 'Another one urg'
 
 /// fooo
 ///
@@ -13,5 +16,5 @@
 ///
 /// # Another [one][two] urg
 ///
-/// [two]: http://a.a
+/// [two]: http://b.b
 pub fn foo() {}
diff --git a/tests/rustdoc/short-docblock.rs b/tests/rustdoc/short-docblock.rs
index 791d3547c9f..151a42a9c9e 100644
--- a/tests/rustdoc/short-docblock.rs
+++ b/tests/rustdoc/short-docblock.rs
@@ -2,8 +2,9 @@
 
 // @has foo/index.html '//*[@class="desc docblock-short"]' 'fooo'
 // @!has foo/index.html '//*[@class="desc docblock-short"]/h1' 'fooo'
-// @has foo/fn.foo.html '//h2[@id="fooo"]/a[@href="#fooo"]' 'fooo'
 
+// @has foo/fn.foo.html '//h2[@id="fooo"]' 'fooo'
+// @has foo/fn.foo.html '//h2[@id="fooo"]/a[@href="#fooo"]' '§'
 /// # fooo
 ///
 /// foo
@@ -11,8 +12,9 @@ pub fn foo() {}
 
 // @has foo/index.html '//*[@class="desc docblock-short"]' 'mooood'
 // @!has foo/index.html '//*[@class="desc docblock-short"]/h2' 'mooood'
-// @has foo/foo/index.html '//h3[@id="mooood"]/a[@href="#mooood"]' 'mooood'
 
+// @has foo/foo/index.html '//h3[@id="mooood"]' 'mooood'
+// @has foo/foo/index.html '//h3[@id="mooood"]/a[@href="#mooood"]' '§'
 /// ## mooood
 ///
 /// foo mod
diff --git a/tests/ui/async-await/for-await-passthrough.rs b/tests/ui/async-await/for-await-passthrough.rs
index 7fa133aaedc..b1a382958a1 100644
--- a/tests/ui/async-await/for-await-passthrough.rs
+++ b/tests/ui/async-await/for-await-passthrough.rs
@@ -25,8 +25,7 @@ async fn real_main() {
 
 fn main() {
     let future = real_main();
-    let waker = std::task::Waker::noop();
-    let mut cx = &mut core::task::Context::from_waker(&waker);
+    let mut cx = &mut core::task::Context::from_waker(std::task::Waker::noop());
     let mut future = core::pin::pin!(future);
     while let core::task::Poll::Pending = future.as_mut().poll(&mut cx) {}
 }
diff --git a/tests/ui/async-await/for-await.rs b/tests/ui/async-await/for-await.rs
index 6345ceb0c27..00dbdfb2389 100644
--- a/tests/ui/async-await/for-await.rs
+++ b/tests/ui/async-await/for-await.rs
@@ -17,8 +17,7 @@ async fn real_main() {
 
 fn main() {
     let future = real_main();
-    let waker = std::task::Waker::noop();
-    let mut cx = &mut core::task::Context::from_waker(&waker);
+    let mut cx = &mut core::task::Context::from_waker(std::task::Waker::noop());
     let mut future = core::pin::pin!(future);
     while let core::task::Poll::Pending = future.as_mut().poll(&mut cx) {}
 }
diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
index 491dfcc6ae0..8c01f1bddef 100644
--- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
+++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
@@ -40,8 +40,7 @@ fn main() {
     let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = Waker::noop();
-    let ctx = &mut Context::from_waker(&waker);
+    let ctx = &mut Context::from_waker(Waker::noop());
 
     loop {
         match fut.as_mut().poll(ctx) {
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
index f21abf012ba..e2fd9f9dfea 100644
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
+++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
@@ -43,8 +43,7 @@ fn main() {
     let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = Waker::noop();
-    let ctx = &mut Context::from_waker(&waker);
+    let ctx = &mut Context::from_waker(Waker::noop());
 
     loop {
         match fut.as_mut().poll(ctx) {
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
index 0560cd9c5fe..b7336485eb8 100644
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
+++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
@@ -21,7 +21,7 @@ LL |     default async fn foo(_: T) -> &'static str {
    = note: specialization behaves in inconsistent and surprising ways with async functions in traits, and for now is disallowed
 
 error[E0599]: no method named `poll` found for struct `Pin<&mut impl Future<Output = ()>>` in the current scope
-  --> $DIR/dont-project-to-specializable-projection.rs:50:28
+  --> $DIR/dont-project-to-specializable-projection.rs:49:28
    |
 LL |         match fut.as_mut().poll(ctx) {
    |                            ^^^^ method not found in `Pin<&mut impl Future<Output = ()>>`
diff --git a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs
index aac74d3eacb..80c0b69a6f7 100644
--- a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs
+++ b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs
@@ -11,7 +11,6 @@ async gen fn gen_fn() -> &'static str {
 
 pub fn main() {
     let async_iterator = pin!(gen_fn());
-    let waker = Waker::noop();
-    let ctx = &mut Context::from_waker(&waker);
+    let ctx = &mut Context::from_waker(Waker::noop());
     async_iterator.poll_next(ctx);
 }
diff --git a/tests/ui/coroutine/async_gen_fn_iter.rs b/tests/ui/coroutine/async_gen_fn_iter.rs
index ec6464d0048..604156b4d37 100644
--- a/tests/ui/coroutine/async_gen_fn_iter.rs
+++ b/tests/ui/coroutine/async_gen_fn_iter.rs
@@ -74,8 +74,7 @@ fn main() {
     let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = Waker::noop();
-    let ctx = &mut Context::from_waker(&waker);
+    let ctx = &mut Context::from_waker(Waker::noop());
 
     loop {
         match fut.as_mut().poll(ctx) {
diff --git a/tests/ui/dyn-star/dispatch-on-pin-mut.rs b/tests/ui/dyn-star/dispatch-on-pin-mut.rs
index c4ae279e6c1..151aa9092fb 100644
--- a/tests/ui/dyn-star/dispatch-on-pin-mut.rs
+++ b/tests/ui/dyn-star/dispatch-on-pin-mut.rs
@@ -19,15 +19,14 @@ async fn async_main() {
 // ------------------------------------------------------------------------- //
 // Implementation Details Below...
 
-use std::task::*;
 use std::pin::pin;
+use std::task::*;
 
 fn main() {
     let mut fut = pin!(async_main());
 
     // Poll loop, just to test the future...
-    let waker = Waker::noop();
-    let ctx = &mut Context::from_waker(&waker);
+    let ctx = &mut Context::from_waker(Waker::noop());
 
     loop {
         match fut.as_mut().poll(ctx) {
diff --git a/tests/ui/pattern/never_patterns.rs b/tests/ui/pattern/never_patterns.rs
deleted file mode 100644
index 8f44f8a6559..00000000000
--- a/tests/ui/pattern/never_patterns.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-#![feature(never_patterns)]
-#![allow(incomplete_features)]
-
-enum Void {}
-
-fn main() {}
-
-// The classic use for empty types.
-fn safe_unwrap_result<T>(res: Result<T, Void>) {
-    let Ok(_x) = res; //~ ERROR refutable pattern in local binding
-    let (Ok(_x) | Err(!)) = &res;
-    let (Ok(_x) | Err(&!)) = res.as_ref();
-}
-
-// Check we only accept `!` where we want to.
-fn never_pattern_location(void: Void) {
-    // FIXME(never_patterns): Don't accept on a non-empty type.
-    match Some(0) {
-        None => {}
-        Some(!),
-    }
-    // FIXME(never_patterns): Don't accept on an arbitrary type, even if there are no more branches.
-    match () {
-        () => {}
-        !,
-    }
-    // FIXME(never_patterns): Don't accept even on an empty branch.
-    match None::<Void> {
-        None => {}
-        !,
-    }
-    // FIXME(never_patterns): Let alone if the emptiness is behind a reference.
-    match None::<&Void> {
-        None => {}
-        !,
-    }
-    // Participate in match ergonomics.
-    match &void {
-        !
-    }
-    match &&void {
-        !
-    }
-    match &&void {
-        &!
-    }
-    match &None::<Void> {
-        None => {}
-        Some(!)
-    }
-    match None::<&Void> {
-        None => {}
-        Some(!),
-    }
-    // Accept on a composite empty type.
-    match None::<&(u32, Void)> {
-        None => {}
-        Some(&!),
-    }
-    // Accept on an simple empty type.
-    match None::<Void> {
-        None => {}
-        Some(!),
-    }
-    match None::<&Void> {
-        None => {}
-        Some(&!),
-    }
-    match None::<&(u32, Void)> {
-        None => {}
-        Some(&(_, !)),
-    }
-}
diff --git a/tests/ui/pattern/never_patterns.stderr b/tests/ui/pattern/never_patterns.stderr
deleted file mode 100644
index 20eeb01cf71..00000000000
--- a/tests/ui/pattern/never_patterns.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0005]: refutable pattern in local binding
-  --> $DIR/never_patterns.rs:10:9
-   |
-LL |     let Ok(_x) = res;
-   |         ^^^^^^ pattern `Err(_)` not covered
-   |
-   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
-   = note: the matched value is of type `Result<T, Void>`
-help: you might want to use `let else` to handle the variant that isn't matched
-   |
-LL |     let Ok(_x) = res else { todo!() };
-   |                      ++++++++++++++++
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/typeck.fail.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/typeck.fail.stderr
new file mode 100644
index 00000000000..013a8b53a55
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/typeck.fail.stderr
@@ -0,0 +1,66 @@
+error: mismatched types
+  --> $DIR/typeck.rs:25:9
+   |
+LL |         !,
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `()`
+
+error: mismatched types
+  --> $DIR/typeck.rs:29:9
+   |
+LL |         !,
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `(i32, bool)`
+
+error: mismatched types
+  --> $DIR/typeck.rs:33:13
+   |
+LL |         (_, !),
+   |             ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `bool`
+
+error: mismatched types
+  --> $DIR/typeck.rs:38:14
+   |
+LL |         Some(!),
+   |              ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `i32`
+
+error: mismatched types
+  --> $DIR/typeck.rs:45:9
+   |
+LL |         !,
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `()`
+
+error: mismatched types
+  --> $DIR/typeck.rs:52:9
+   |
+LL |         !,
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `Option<Void>`
+
+error: mismatched types
+  --> $DIR/typeck.rs:57:9
+   |
+LL |         !,
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `[Void]`
+
+error: mismatched types
+  --> $DIR/typeck.rs:63:9
+   |
+LL |         !,
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `Option<&Void>`
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs b/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs
new file mode 100644
index 00000000000..31a23fa002c
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs
@@ -0,0 +1,125 @@
+// revisions: pass fail
+//[pass] check-pass
+//[fail] check-fail
+#![feature(never_patterns)]
+#![feature(exhaustive_patterns)]
+#![allow(incomplete_features)]
+
+#[derive(Copy, Clone)]
+enum Void {}
+
+fn main() {}
+
+// The classic use for empty types.
+fn safe_unwrap_result<T: Copy>(res: Result<T, Void>) {
+    let Ok(_x) = res;
+    let (Ok(_x) | Err(!)) = &res;
+    let (Ok(_x) | Err(!)) = res.as_ref();
+}
+
+// Check we only accept `!` where we want to.
+#[cfg(fail)]
+fn never_pattern_typeck_fail(void: Void) {
+    // Don't accept on a non-empty type.
+    match () {
+        !,
+        //[fail]~^ ERROR: mismatched types
+    }
+    match (0, false) {
+        !,
+        //[fail]~^ ERROR: mismatched types
+    }
+    match (0, false) {
+        (_, !),
+        //[fail]~^ ERROR: mismatched types
+    }
+    match Some(0) {
+        None => {}
+        Some(!),
+        //[fail]~^ ERROR: mismatched types
+    }
+
+    // Don't accept on an arbitrary type, even if there are no more branches.
+    match () {
+        () => {}
+        !,
+        //[fail]~^ ERROR: mismatched types
+    }
+
+    // Don't accept even on an empty branch.
+    match None::<Void> {
+        None => {}
+        !,
+        //[fail]~^ ERROR: mismatched types
+    }
+    match (&[] as &[Void]) {
+        [] => {}
+        !,
+        //[fail]~^ ERROR: mismatched types
+    }
+    // Let alone if the emptiness is behind a reference.
+    match None::<&Void> {
+        None => {}
+        !,
+        //[fail]~^ ERROR: mismatched types
+    }
+}
+
+#[cfg(pass)]
+fn never_pattern_typeck_pass(void: Void) {
+    // Participate in match ergonomics.
+    match &void {
+        !,
+    }
+    match &&void {
+        !,
+    }
+    match &&void {
+        &!,
+    }
+    match &None::<Void> {
+        None => {}
+        Some(!),
+    }
+    match None::<&Void> {
+        None => {}
+        Some(!),
+    }
+
+    // Accept on a directly empty type.
+    match void {
+        !,
+    }
+    match &void {
+        &!,
+    }
+    match None::<Void> {
+        None => {}
+        Some(!),
+    }
+    match None::<&Void> {
+        None => {}
+        Some(&!),
+    }
+    match None::<&(u32, Void)> {
+        None => {}
+        Some(&(_, !)),
+    }
+    match (&[] as &[Void]) {
+        [] => {}
+        [!],
+    }
+    // Accept on a composite empty type.
+    match None::<&(u32, Void)> {
+        None => {}
+        Some(&!),
+    }
+    match None::<&(u32, Void)> {
+        None => {}
+        Some(!),
+    }
+    match None::<&Result<Void, Void>> {
+        None => {}
+        Some(!),
+    }
+}
diff --git a/tests/ui/suggestions/suggest-slice-swap.fixed b/tests/ui/suggestions/suggest-slice-swap.fixed
new file mode 100644
index 00000000000..05b7ec26379
--- /dev/null
+++ b/tests/ui/suggestions/suggest-slice-swap.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn swap(arr: &mut [u32; 2]) {
+    arr.swap(1, 0);
+    //~^ ERROR cannot borrow `arr[_]` as mutable more than once at a time
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/suggest-slice-swap.rs b/tests/ui/suggestions/suggest-slice-swap.rs
new file mode 100644
index 00000000000..9f3659aac16
--- /dev/null
+++ b/tests/ui/suggestions/suggest-slice-swap.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn swap(arr: &mut [u32; 2]) {
+    std::mem::swap(&mut arr[0], &mut arr[1]);
+    //~^ ERROR cannot borrow `arr[_]` as mutable more than once at a time
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/suggest-slice-swap.stderr b/tests/ui/suggestions/suggest-slice-swap.stderr
new file mode 100644
index 00000000000..2840fc0a761
--- /dev/null
+++ b/tests/ui/suggestions/suggest-slice-swap.stderr
@@ -0,0 +1,17 @@
+error[E0499]: cannot borrow `arr[_]` as mutable more than once at a time
+  --> $DIR/suggest-slice-swap.rs:5:33
+   |
+LL |     std::mem::swap(&mut arr[0], &mut arr[1]);
+   |     -------------- -----------  ^^^^^^^^^^^ second mutable borrow occurs here
+   |     |              |
+   |     |              first mutable borrow occurs here
+   |     first borrow later used by call
+   |
+help: use `.swap()` to swap elements at the specified indices instead
+   |
+LL |     arr.swap(1, 0);
+   |     ~~~~~~~~~~~~~~
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0499`.