about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/crashes/117877.rs13
-rw-r--r--tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr19
-rw-r--r--tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr19
-rw-r--r--tests/ui/asm/const-resolve-error.rs10
-rw-r--r--tests/ui/asm/const-resolve-error.stderr14
-rw-r--r--tests/ui/asm/fail-const-eval-issue-121099.rs4
-rw-r--r--tests/ui/asm/fail-const-eval-issue-121099.stderr4
-rw-r--r--tests/ui/asm/invalid-const-operand.stderr2
-rw-r--r--tests/ui/consts/const-fn-in-vec.rs11
-rw-r--r--tests/ui/consts/const-fn-in-vec.stderr2
-rw-r--r--tests/ui/never_type/unused_trait_in_never_pattern_body.rs12
-rw-r--r--tests/ui/never_type/unused_trait_in_never_pattern_body.stderr36
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs37
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr14
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs59
-rw-r--r--tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr17
-rw-r--r--tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs25
-rw-r--r--tests/ui/repeat-expr/copy-inference-side-effects.rs (renamed from tests/ui/repeat-expr/infer.rs)0
-rw-r--r--tests/ui/repeat-expr/dont-require-copy-on-infer.rs6
-rw-r--r--tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs20
-rw-r--r--tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr14
-rw-r--r--tests/ui/suggestions/abi-typo.stderr10
-rw-r--r--tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs11
-rw-r--r--tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr24
24 files changed, 341 insertions, 42 deletions
diff --git a/tests/crashes/117877.rs b/tests/crashes/117877.rs
deleted file mode 100644
index b1effc0cbcb..00000000000
--- a/tests/crashes/117877.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #117877
-//@ edition:2021
-//@ needs-rustc-debug-assertions
-//@ only-x86_64
-#![feature(asm_const)]
-
-use std::arch::asm;
-
-async unsafe fn foo<'a>() {
-    asm!("/* {0} */", const N);
-}
-
-fn main() {}
diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr
index 02620da3a21..c71797b500d 100644
--- a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr
+++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr
@@ -2,23 +2,26 @@ error[E0703]: invalid ABI: found `riscv-interrupt`
   --> $DIR/riscv-discoverability-guidance.rs:15:8
    |
 LL | extern "riscv-interrupt" fn isr() {}
-   |        ^^^^^^^^^^^^^^^^^
-   |        |
-   |        invalid ABI
-   |        help: did you mean: `"riscv-interrupt-m"`
+   |        ^^^^^^^^^^^^^^^^^ invalid ABI
    |
    = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+help: there's a similarly named valid ABI `riscv-interrupt-m`
+   |
+LL | extern "riscv-interrupt-m" fn isr() {}
+   |                        ++
 
 error[E0703]: invalid ABI: found `riscv-interrupt-u`
   --> $DIR/riscv-discoverability-guidance.rs:20:8
    |
 LL | extern "riscv-interrupt-u" fn isr_U() {}
-   |        ^^^^^^^^^^^^^^^^^^^
-   |        |
-   |        invalid ABI
-   |        help: did you mean: `"riscv-interrupt-m"`
+   |        ^^^^^^^^^^^^^^^^^^^ invalid ABI
    |
    = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+help: there's a similarly named valid ABI `riscv-interrupt-m`
+   |
+LL - extern "riscv-interrupt-u" fn isr_U() {}
+LL + extern "riscv-interrupt-m" fn isr_U() {}
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr
index 02620da3a21..c71797b500d 100644
--- a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr
+++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr
@@ -2,23 +2,26 @@ error[E0703]: invalid ABI: found `riscv-interrupt`
   --> $DIR/riscv-discoverability-guidance.rs:15:8
    |
 LL | extern "riscv-interrupt" fn isr() {}
-   |        ^^^^^^^^^^^^^^^^^
-   |        |
-   |        invalid ABI
-   |        help: did you mean: `"riscv-interrupt-m"`
+   |        ^^^^^^^^^^^^^^^^^ invalid ABI
    |
    = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+help: there's a similarly named valid ABI `riscv-interrupt-m`
+   |
+LL | extern "riscv-interrupt-m" fn isr() {}
+   |                        ++
 
 error[E0703]: invalid ABI: found `riscv-interrupt-u`
   --> $DIR/riscv-discoverability-guidance.rs:20:8
    |
 LL | extern "riscv-interrupt-u" fn isr_U() {}
-   |        ^^^^^^^^^^^^^^^^^^^
-   |        |
-   |        invalid ABI
-   |        help: did you mean: `"riscv-interrupt-m"`
+   |        ^^^^^^^^^^^^^^^^^^^ invalid ABI
    |
    = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+help: there's a similarly named valid ABI `riscv-interrupt-m`
+   |
+LL - extern "riscv-interrupt-u" fn isr_U() {}
+LL + extern "riscv-interrupt-m" fn isr_U() {}
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/asm/const-resolve-error.rs b/tests/ui/asm/const-resolve-error.rs
new file mode 100644
index 00000000000..19c8af0d542
--- /dev/null
+++ b/tests/ui/asm/const-resolve-error.rs
@@ -0,0 +1,10 @@
+//@ edition:2021
+//@ needs-asm-support
+
+use std::arch::asm;
+
+async unsafe fn foo<'a>() {
+    asm!("/* {0} */", const N); //~ ERROR E0425
+}
+
+fn main() {}
diff --git a/tests/ui/asm/const-resolve-error.stderr b/tests/ui/asm/const-resolve-error.stderr
new file mode 100644
index 00000000000..f02a7f0a6b1
--- /dev/null
+++ b/tests/ui/asm/const-resolve-error.stderr
@@ -0,0 +1,14 @@
+error[E0425]: cannot find value `N` in this scope
+  --> $DIR/const-resolve-error.rs:7:29
+   |
+LL |     asm!("/* {0} */", const N);
+   |                             ^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | async unsafe fn foo<'a, const N: /* Type */>() {
+   |                       +++++++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/asm/fail-const-eval-issue-121099.rs b/tests/ui/asm/fail-const-eval-issue-121099.rs
index 36d00b1e5d2..c91bbfd1b73 100644
--- a/tests/ui/asm/fail-const-eval-issue-121099.rs
+++ b/tests/ui/asm/fail-const-eval-issue-121099.rs
@@ -5,6 +5,6 @@ use std::arch::global_asm;
 
 fn main() {}
 
-global_asm!("/* {} */", const 1 << 500); //~ ERROR evaluation of constant value failed [E0080]
+global_asm!("/* {} */", const 1 << 500); //~ ERROR E0080
 
-global_asm!("/* {} */", const 1 / 0); //~ ERROR evaluation of constant value failed [E0080]
+global_asm!("/* {} */", const 1 / 0); //~ ERROR E0080
diff --git a/tests/ui/asm/fail-const-eval-issue-121099.stderr b/tests/ui/asm/fail-const-eval-issue-121099.stderr
index 5d86c3a5f7b..eb662dadffb 100644
--- a/tests/ui/asm/fail-const-eval-issue-121099.stderr
+++ b/tests/ui/asm/fail-const-eval-issue-121099.stderr
@@ -1,10 +1,10 @@
-error[E0080]: evaluation of constant value failed
+error[E0080]: evaluation of `{global_asm#0}::{constant#0}` failed
   --> $DIR/fail-const-eval-issue-121099.rs:8:31
    |
 LL | global_asm!("/* {} */", const 1 << 500);
    |                               ^^^^^^^^ attempt to shift left by `500_i32`, which would overflow
 
-error[E0080]: evaluation of constant value failed
+error[E0080]: evaluation of `{global_asm#1}::{constant#0}` failed
   --> $DIR/fail-const-eval-issue-121099.rs:10:31
    |
 LL | global_asm!("/* {} */", const 1 / 0);
diff --git a/tests/ui/asm/invalid-const-operand.stderr b/tests/ui/asm/invalid-const-operand.stderr
index 13bb10e84a5..1cedabeef28 100644
--- a/tests/ui/asm/invalid-const-operand.stderr
+++ b/tests/ui/asm/invalid-const-operand.stderr
@@ -80,7 +80,7 @@ error: invalid type for `const` operand
 LL |         asm!("{}", const &0);
    |                    ^^^^^^--
    |                          |
-   |                          is a `&i32`
+   |                          is a `&{integer}`
    |
    = help: `const` operands must be of an integer type
 
diff --git a/tests/ui/consts/const-fn-in-vec.rs b/tests/ui/consts/const-fn-in-vec.rs
index 0483800efef..d1430bc8e00 100644
--- a/tests/ui/consts/const-fn-in-vec.rs
+++ b/tests/ui/consts/const-fn-in-vec.rs
@@ -1,11 +1,16 @@
 static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
 //~^ ERROR the trait bound `String: Copy` is not satisfied
 
-fn main() {
-    // should hint to create an inline `const` block
-    // or to create a new `const` item
+// should hint to create an inline `const` block
+// or to create a new `const` item
+fn foo() {
     let _strings: [String; 5] = [String::new(); 5];
     //~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn bar() {
     let _maybe_strings: [Option<String>; 5] = [None; 5];
     //~^ ERROR the trait bound `String: Copy` is not satisfied
 }
+
+fn main() {}
diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr
index b31e180fea2..5be26d7c121 100644
--- a/tests/ui/consts/const-fn-in-vec.stderr
+++ b/tests/ui/consts/const-fn-in-vec.stderr
@@ -22,7 +22,7 @@ LL |     let _strings: [String; 5] = [String::new(); 5];
    = note: the `Copy` trait is required because this value will be copied for each element of the array
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/const-fn-in-vec.rs:9:48
+  --> $DIR/const-fn-in-vec.rs:12:48
    |
 LL |     let _maybe_strings: [Option<String>; 5] = [None; 5];
    |                                                ^^^^
diff --git a/tests/ui/never_type/unused_trait_in_never_pattern_body.rs b/tests/ui/never_type/unused_trait_in_never_pattern_body.rs
new file mode 100644
index 00000000000..8179c94b72b
--- /dev/null
+++ b/tests/ui/never_type/unused_trait_in_never_pattern_body.rs
@@ -0,0 +1,12 @@
+fn a() {
+    match 0 {
+        ! => || { //~ ERROR `!` patterns are experimental
+        //~^ ERROR a never pattern is always unreachable
+        //~^^ ERROR mismatched types
+            use std::ops::Add;
+            0.add(1)
+        },
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr b/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr
new file mode 100644
index 00000000000..18ca9f12b7e
--- /dev/null
+++ b/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr
@@ -0,0 +1,36 @@
+error[E0658]: `!` patterns are experimental
+  --> $DIR/unused_trait_in_never_pattern_body.rs:3:9
+   |
+LL |         ! => || {
+   |         ^
+   |
+   = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
+   = help: add `#![feature(never_patterns)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: a never pattern is always unreachable
+  --> $DIR/unused_trait_in_never_pattern_body.rs:3:14
+   |
+LL |           ! => || {
+   |  ______________^
+LL | |
+LL | |
+LL | |             use std::ops::Add;
+LL | |             0.add(1)
+LL | |         },
+   | |         ^
+   | |         |
+   | |_________this will never be executed
+   |           help: remove this expression
+
+error: mismatched types
+  --> $DIR/unused_trait_in_never_pattern_body.rs:3:9
+   |
+LL |         ! => || {
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `i32`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs
new file mode 100644
index 00000000000..d9ad93541ec
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs
@@ -0,0 +1,37 @@
+#![feature(generic_arg_infer)]
+
+// Test that would start passing if we defer repeat expr copy checks to end of
+// typechecking and they're checked after integer fallback occurs. We accomplish
+// this by contriving a situation where integer fallback allows progress to be
+// made on a trait goal that infers the length of a repeat expr.
+
+use std::marker::PhantomData;
+
+struct NotCopy;
+
+trait Trait<const N: usize> {}
+
+impl Trait<2> for u32 {}
+impl Trait<1> for i32 {}
+
+fn make_goal<T: Trait<N>, const N: usize>(_: &T, _: [NotCopy; N]) {}
+
+fn main() {
+    let a = 1;
+    let b = [NotCopy; _];
+    //~^ ERROR: type annotations needed
+
+    // a is of type `?y`
+    // b is of type `[NotCopy; ?x]`
+    // there is a goal ?y: Trait<?x>` with two candidates:
+    // - `i32: Trait<1>`, ?y=i32 ?x=1 which doesnt require `NotCopy: Copy`
+    // - `u32: Trait<2>` ?y=u32 ?x=2 which requires `NotCopy: Copy`
+    make_goal(&a, b);
+
+    // final repeat expr checks:
+    //
+    // `NotCopy; ?x`
+    // - succeeds if fallback happens before repeat exprs as `i32: Trait<?x>` infers `?x=1`
+    // - fails if repeat expr checks happen first as `?x` is unconstrained so cannot be
+    //    structurally resolved
+}
diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr
new file mode 100644
index 00000000000..2a0cb3fb7a3
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `[NotCopy; _]`
+  --> $DIR/copy-check-deferred-after-fallback.rs:21:9
+   |
+LL |     let b = [NotCopy; _];
+   |         ^    ------- type must be known at this point
+   |
+help: consider giving `b` an explicit type, where the value of const parameter `N` is specified
+   |
+LL |     let b: [_; N] = [NotCopy; _];
+   |          ++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
new file mode 100644
index 00000000000..4654d7483a6
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
@@ -0,0 +1,59 @@
+//@ check-pass
+
+#![feature(generic_arg_infer)]
+
+// Test that if we defer repeat expr copy checks to end of typechecking they're
+// checked before integer fallback occurs. We accomplish this by contriving a
+// situation where we have a goal that can be proven either via another repeat expr
+// check or by integer fallback. In the integer fallback case an array length would
+// be inferred to `2` requiring `NotCopy: Copy`, and in the repeat expr case it would
+// be inferred to `1`.
+
+use std::marker::PhantomData;
+
+struct NotCopy;
+
+struct Foo<T>(PhantomData<T>);
+
+impl Clone for Foo<u32> {
+    fn clone(&self) -> Self {
+        Foo(PhantomData)
+    }
+}
+
+impl Copy for Foo<u32> {}
+
+fn tie<T>(_: &T, _: [Foo<T>; 2]) {}
+
+trait Trait<const N: usize> {}
+
+impl Trait<2> for i32 {}
+impl Trait<1> for u32 {}
+
+fn make_goal<T: Trait<N>, const N: usize>(_: &T, _: [NotCopy; N]) {}
+
+fn main() {
+    let a = 1;
+    let b: [Foo<_>; 2] = [Foo(PhantomData); _];
+    tie(&a, b);
+    let c = [NotCopy; _];
+
+    // a is of type `?y`
+    // b is of type `[Foo<?y>; 2]`
+    // c is of type `[NotCopy; ?x]`
+    // there is a goal ?y: Trait<?x>` with two candidates:
+    // - `i32: Trait<2>`, ?y=i32 ?x=2 which requires `NotCopy: Copy` when expr checks happen
+    // - `u32: Trait<1>` ?y=u32 ?x=1 which doesnt require `NotCopy: Copy`
+    make_goal(&a, c);
+
+    // final repeat expr checks:
+    //
+    // `Foo<?y>; 2`
+    // - Foo<?y>: Copy
+    // - requires ?y=u32
+    //
+    // `NotCopy; ?x`
+    // - fails if fallback happens before repeat exprs as `i32: Trait<?x>` infers `?x=2`
+    // - succeeds if repeat expr checks happen first as `?y=u32` means `u32: Trait<?x>`
+    //    infers `?x=1`
+}
diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr
new file mode 100644
index 00000000000..de38476c82b
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed for `[Foo<_>; 2]`
+  --> $DIR/copy-inference-side-effects-are-lazy.rs:22:9
+   |
+LL |     let x = [Foo(PhantomData); 2];
+   |         ^
+LL |
+LL |     _ = extract(x).max(2);
+   |         ---------- type must be known at this point
+   |
+help: consider giving `x` an explicit type, where the type for type parameter `T` is specified
+   |
+LL |     let x: [Foo<T>; 2] = [Foo(PhantomData); 2];
+   |          +++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs
new file mode 100644
index 00000000000..0b0672d9c2b
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs
@@ -0,0 +1,25 @@
+//@revisions: current gai
+//@[current] check-pass
+
+#![cfg_attr(gai, feature(generic_arg_infer))]
+
+use std::marker::PhantomData;
+
+struct Foo<T>(PhantomData<T>);
+
+impl Clone for Foo<u8> {
+    fn clone(&self) -> Self {
+        Foo(PhantomData)
+    }
+}
+impl Copy for Foo<u8> {}
+
+fn extract<T, const N: usize>(_: [Foo<T>; N]) -> T {
+    loop {}
+}
+
+fn main() {
+    let x = [Foo(PhantomData); 2];
+    //[gai]~^ ERROR: type annotations needed
+    _ = extract(x).max(2);
+}
diff --git a/tests/ui/repeat-expr/infer.rs b/tests/ui/repeat-expr/copy-inference-side-effects.rs
index eb47b5f462f..eb47b5f462f 100644
--- a/tests/ui/repeat-expr/infer.rs
+++ b/tests/ui/repeat-expr/copy-inference-side-effects.rs
diff --git a/tests/ui/repeat-expr/dont-require-copy-on-infer.rs b/tests/ui/repeat-expr/dont-require-copy-on-infer.rs
new file mode 100644
index 00000000000..e81bf1595be
--- /dev/null
+++ b/tests/ui/repeat-expr/dont-require-copy-on-infer.rs
@@ -0,0 +1,6 @@
+//@ check-pass
+#![feature(generic_arg_infer)]
+
+fn main() {
+    let a: [_; 1] = [String::new(); _];
+}
diff --git a/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs
new file mode 100644
index 00000000000..eb70df62996
--- /dev/null
+++ b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs
@@ -0,0 +1,20 @@
+#![feature(generic_arg_infer)]
+
+struct Foo<const N: usize>;
+
+impl Clone for Foo<1> {
+    fn clone(&self) -> Self {
+        Foo
+    }
+}
+impl Copy for Foo<1> {}
+
+fn unify<const N: usize>(_: &[Foo<N>; N]) {
+    loop {}
+}
+
+fn main() {
+    let x = &[Foo::<_>; _];
+    //~^ ERROR: type annotations needed for `&[Foo<_>; _]`
+    _ = unify(x);
+}
diff --git a/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr
new file mode 100644
index 00000000000..04f8ff33fda
--- /dev/null
+++ b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `&[Foo<_>; _]`
+  --> $DIR/no-conservative-copy-impl-requirement.rs:17:9
+   |
+LL |     let x = &[Foo::<_>; _];
+   |         ^     -------- type must be known at this point
+   |
+help: consider giving `x` an explicit type, where the value of const parameter `N` is specified
+   |
+LL |     let x: &[Foo<N>; N] = &[Foo::<_>; _];
+   |          ++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/suggestions/abi-typo.stderr b/tests/ui/suggestions/abi-typo.stderr
index 5195c43220b..4d89ac16570 100644
--- a/tests/ui/suggestions/abi-typo.stderr
+++ b/tests/ui/suggestions/abi-typo.stderr
@@ -2,12 +2,14 @@ error[E0703]: invalid ABI: found `cdedl`
   --> $DIR/abi-typo.rs:2:8
    |
 LL | extern "cdedl" fn cdedl() {}
-   |        ^^^^^^^
-   |        |
-   |        invalid ABI
-   |        help: did you mean: `"cdecl"`
+   |        ^^^^^^^ invalid ABI
    |
    = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+help: there's a similarly named valid ABI `cdecl`
+   |
+LL - extern "cdedl" fn cdedl() {}
+LL + extern "cdecl" fn cdedl() {}
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs
new file mode 100644
index 00000000000..2ebbed3c740
--- /dev/null
+++ b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs
@@ -0,0 +1,11 @@
+struct T(String);
+
+impl PartialEq<String> for T {
+    fn eq(&self, other: &String) -> bool {
+        &self.0 == other
+    }
+}
+
+fn main() {
+    String::from("Girls Band Cry") == T(String::from("Girls Band Cry")); //~ can't compare `String` with `T` [E0277]
+}
diff --git a/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr
new file mode 100644
index 00000000000..ebe103ef19a
--- /dev/null
+++ b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr
@@ -0,0 +1,24 @@
+error[E0277]: can't compare `String` with `T`
+  --> $DIR/partialeq_suggest_swap_on_e0277.rs:10:36
+   |
+LL |     String::from("Girls Band Cry") == T(String::from("Girls Band Cry"));
+   |                                    ^^ no implementation for `String == T`
+   |
+   = help: the trait `PartialEq<T>` is not implemented for `String`
+   = help: the following other types implement trait `PartialEq<Rhs>`:
+             `String` implements `PartialEq<&str>`
+             `String` implements `PartialEq<ByteStr>`
+             `String` implements `PartialEq<ByteString>`
+             `String` implements `PartialEq<Cow<'_, str>>`
+             `String` implements `PartialEq<str>`
+             `String` implements `PartialEq`
+   = note: `T` implements `PartialEq<String>`
+help: consider swapping the equality
+   |
+LL -     String::from("Girls Band Cry") == T(String::from("Girls Band Cry"));
+LL +     T(String::from("Girls Band Cry")) == String::from("Girls Band Cry");
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.