summaryrefslogtreecommitdiffstats
path: root/src/test/ui/did_you_mean
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/did_you_mean
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/did_you_mean')
-rw-r--r--src/test/ui/did_you_mean/E0178.rs13
-rw-r--r--src/test/ui/did_you_mean/E0178.stderr27
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-expr.rs36
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-expr.stderr61
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-pat.rs36
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-pat.stderr85
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-ty.rs85
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-ty.stderr243
-rw-r--r--src/test/ui/did_you_mean/brackets-to-braces-single-element.rs10
-rw-r--r--src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr38
-rw-r--r--src/test/ui/did_you_mean/compatible-variants-in-pat.rs41
-rw-r--r--src/test/ui/did_you_mean/compatible-variants-in-pat.stderr68
-rw-r--r--src/test/ui/did_you_mean/compatible-variants.rs89
-rw-r--r--src/test/ui/did_you_mean/compatible-variants.stderr221
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs26
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr13
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs30
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr17
-rw-r--r--src/test/ui/did_you_mean/issue-31424.rs21
-rw-r--r--src/test/ui/did_you_mean/issue-31424.stderr49
-rw-r--r--src/test/ui/did_you_mean/issue-34126.rs15
-rw-r--r--src/test/ui/did_you_mean/issue-34126.stderr31
-rw-r--r--src/test/ui/did_you_mean/issue-34337.rs8
-rw-r--r--src/test/ui/did_you_mean/issue-34337.stderr12
-rw-r--r--src/test/ui/did_you_mean/issue-35937.rs21
-rw-r--r--src/test/ui/did_you_mean/issue-35937.stderr28
-rw-r--r--src/test/ui/did_you_mean/issue-36798.rs8
-rw-r--r--src/test/ui/did_you_mean/issue-36798.stderr9
-rw-r--r--src/test/ui/did_you_mean/issue-36798_unknown_field.rs8
-rw-r--r--src/test/ui/did_you_mean/issue-36798_unknown_field.stderr11
-rw-r--r--src/test/ui/did_you_mean/issue-37139.rs16
-rw-r--r--src/test/ui/did_you_mean/issue-37139.stderr12
-rw-r--r--src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs5
-rw-r--r--src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr15
-rw-r--r--src/test/ui/did_you_mean/issue-38147-1.rs21
-rw-r--r--src/test/ui/did_you_mean/issue-38147-1.stderr11
-rw-r--r--src/test/ui/did_you_mean/issue-38147-2.rs17
-rw-r--r--src/test/ui/did_you_mean/issue-38147-2.stderr25
-rw-r--r--src/test/ui/did_you_mean/issue-38147-3.rs12
-rw-r--r--src/test/ui/did_you_mean/issue-38147-3.stderr14
-rw-r--r--src/test/ui/did_you_mean/issue-38147-4.rs9
-rw-r--r--src/test/ui/did_you_mean/issue-38147-4.stderr11
-rw-r--r--src/test/ui/did_you_mean/issue-39544.rs50
-rw-r--r--src/test/ui/did_you_mean/issue-39544.stderr102
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs27
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr57
-rw-r--r--src/test/ui/did_you_mean/issue-40006.rs39
-rw-r--r--src/test/ui/did_you_mean/issue-40006.stderr98
-rw-r--r--src/test/ui/did_you_mean/issue-40396.rs29
-rw-r--r--src/test/ui/did_you_mean/issue-40396.stderr112
-rw-r--r--src/test/ui/did_you_mean/issue-40823.rs4
-rw-r--r--src/test/ui/did_you_mean/issue-40823.stderr11
-rw-r--r--src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed5
-rw-r--r--src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs5
-rw-r--r--src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr8
-rw-r--r--src/test/ui/did_you_mean/issue-42599_available_fields_note.rs37
-rw-r--r--src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr32
-rw-r--r--src/test/ui/did_you_mean/issue-42764.rs30
-rw-r--r--src/test/ui/did_you_mean/issue-42764.stderr36
-rw-r--r--src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs36
-rw-r--r--src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr66
-rw-r--r--src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs17
-rw-r--r--src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.stderr8
-rw-r--r--src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs34
-rw-r--r--src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr56
-rw-r--r--src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs87
-rw-r--r--src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr74
-rw-r--r--src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs6
-rw-r--r--src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr38
-rw-r--r--src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs19
-rw-r--r--src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr49
-rw-r--r--src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs57
-rw-r--r--src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr75
-rw-r--r--src/test/ui/did_you_mean/issue-54109-without-witness.fixed61
-rw-r--r--src/test/ui/did_you_mean/issue-54109-without-witness.rs61
-rw-r--r--src/test/ui/did_you_mean/issue-54109-without-witness.stderr66
-rw-r--r--src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs15
-rw-r--r--src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr40
-rw-r--r--src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs18
-rw-r--r--src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.stderr48
-rw-r--r--src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs24
-rw-r--r--src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr19
-rw-r--r--src/test/ui/did_you_mean/pub-macro-rules.rs16
-rw-r--r--src/test/ui/did_you_mean/pub-macro-rules.stderr8
-rw-r--r--src/test/ui/did_you_mean/recursion_limit.rs35
-rw-r--r--src/test/ui/did_you_mean/recursion_limit.stderr66
-rw-r--r--src/test/ui/did_you_mean/recursion_limit_deref.rs53
-rw-r--r--src/test/ui/did_you_mean/recursion_limit_deref.stderr23
-rw-r--r--src/test/ui/did_you_mean/recursion_limit_macro.rs15
-rw-r--r--src/test/ui/did_you_mean/recursion_limit_macro.stderr14
-rw-r--r--src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed15
-rw-r--r--src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs15
-rw-r--r--src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr18
-rw-r--r--src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs7
-rw-r--r--src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr25
-rw-r--r--src/test/ui/did_you_mean/use_instead_of_import.fixed15
-rw-r--r--src/test/ui/did_you_mean/use_instead_of_import.rs15
-rw-r--r--src/test/ui/did_you_mean/use_instead_of_import.stderr14
98 files changed, 3538 insertions, 0 deletions
diff --git a/src/test/ui/did_you_mean/E0178.rs b/src/test/ui/did_you_mean/E0178.rs
new file mode 100644
index 000000000..095df640c
--- /dev/null
+++ b/src/test/ui/did_you_mean/E0178.rs
@@ -0,0 +1,13 @@
+#![allow(bare_trait_objects)]
+
+trait Foo {}
+
+struct Bar<'a> {
+ w: &'a Foo + Copy, //~ ERROR expected a path
+ x: &'a Foo + 'a, //~ ERROR expected a path
+ y: &'a mut Foo + 'a, //~ ERROR expected a path
+ z: fn() -> Foo + 'a, //~ ERROR expected a path
+}
+
+fn main() {
+}
diff --git a/src/test/ui/did_you_mean/E0178.stderr b/src/test/ui/did_you_mean/E0178.stderr
new file mode 100644
index 000000000..58ac6e908
--- /dev/null
+++ b/src/test/ui/did_you_mean/E0178.stderr
@@ -0,0 +1,27 @@
+error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
+ --> $DIR/E0178.rs:6:8
+ |
+LL | w: &'a Foo + Copy,
+ | ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Copy)`
+
+error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
+ --> $DIR/E0178.rs:7:8
+ |
+LL | x: &'a Foo + 'a,
+ | ^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + 'a)`
+
+error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo`
+ --> $DIR/E0178.rs:8:8
+ |
+LL | y: &'a mut Foo + 'a,
+ | ^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'a mut (Foo + 'a)`
+
+error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
+ --> $DIR/E0178.rs:9:8
+ |
+LL | z: fn() -> Foo + 'a,
+ | ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0178`.
diff --git a/src/test/ui/did_you_mean/bad-assoc-expr.rs b/src/test/ui/did_you_mean/bad-assoc-expr.rs
new file mode 100644
index 000000000..1d584757f
--- /dev/null
+++ b/src/test/ui/did_you_mean/bad-assoc-expr.rs
@@ -0,0 +1,36 @@
+fn main() {
+ let a = [1, 2, 3, 4];
+ [i32; 4]::clone(&a);
+ //~^ ERROR missing angle brackets in associated item path
+
+ [i32]::as_ref(&a);
+ //~^ ERROR missing angle brackets in associated item path
+
+ (u8)::clone(&0);
+ //~^ ERROR missing angle brackets in associated item path
+
+ (u8, u8)::clone(&(0, 0));
+ //~^ ERROR missing angle brackets in associated item path
+
+ &(u8)::clone(&0);
+ //~^ ERROR missing angle brackets in associated item path
+
+ 10 + (u8)::clone(&0);
+ //~^ ERROR missing angle brackets in associated item path
+}
+
+macro_rules! expr {
+ ($ty: ty) => ($ty::clone(&0))
+ //~^ ERROR missing angle brackets in associated item path
+}
+macro_rules! ty {
+ () => (u8)
+}
+
+fn check_macros() {
+ expr!(u8);
+ let _ = ty!()::clone(&0);
+ //~^ ERROR missing angle brackets in associated item path
+ ty!()::clone(&0);
+ //~^ ERROR missing angle brackets in associated item path
+}
diff --git a/src/test/ui/did_you_mean/bad-assoc-expr.stderr b/src/test/ui/did_you_mean/bad-assoc-expr.stderr
new file mode 100644
index 000000000..c295cac9a
--- /dev/null
+++ b/src/test/ui/did_you_mean/bad-assoc-expr.stderr
@@ -0,0 +1,61 @@
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:3:5
+ |
+LL | [i32; 4]::clone(&a);
+ | ^^^^^^^^^^^^^^^ help: try: `<[i32; 4]>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:6:5
+ |
+LL | [i32]::as_ref(&a);
+ | ^^^^^^^^^^^^^ help: try: `<[i32]>::as_ref`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:9:5
+ |
+LL | (u8)::clone(&0);
+ | ^^^^^^^^^^^ help: try: `<(u8)>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:12:5
+ |
+LL | (u8, u8)::clone(&(0, 0));
+ | ^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:15:6
+ |
+LL | &(u8)::clone(&0);
+ | ^^^^^^^^^^^ help: try: `<(u8)>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:18:10
+ |
+LL | 10 + (u8)::clone(&0);
+ | ^^^^^^^^^^^ help: try: `<(u8)>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:32:13
+ |
+LL | let _ = ty!()::clone(&0);
+ | ^^^^^^^^^^^^ help: try: `<ty!()>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:34:5
+ |
+LL | ty!()::clone(&0);
+ | ^^^^^^^^^^^^ help: try: `<ty!()>::clone`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-expr.rs:23:19
+ |
+LL | ($ty: ty) => ($ty::clone(&0))
+ | ^^^^^^^^^^ help: try: `<$ty>::clone`
+...
+LL | expr!(u8);
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.rs b/src/test/ui/did_you_mean/bad-assoc-pat.rs
new file mode 100644
index 000000000..3f912f7ff
--- /dev/null
+++ b/src/test/ui/did_you_mean/bad-assoc-pat.rs
@@ -0,0 +1,36 @@
+fn main() {
+ match 0u8 {
+ [u8]::AssocItem => {}
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR no associated item named `AssocItem` found
+ (u8, u8)::AssocItem => {}
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR no associated item named `AssocItem` found
+ _::AssocItem => {}
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR no associated item named `AssocItem` found
+ }
+ match &0u8 {
+ &(u8,)::AssocItem => {}
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR no associated item named `AssocItem` found
+ }
+}
+
+macro_rules! pat {
+ ($ty: ty) => ($ty::AssocItem)
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR no associated item named `AssocItem` found
+}
+macro_rules! ty {
+ () => (u8)
+}
+
+fn check_macros() {
+ match 0u8 {
+ pat!(u8) => {}
+ ty!()::AssocItem => {}
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR no associated item named `AssocItem` found
+ }
+}
diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.stderr b/src/test/ui/did_you_mean/bad-assoc-pat.stderr
new file mode 100644
index 000000000..19d173f1b
--- /dev/null
+++ b/src/test/ui/did_you_mean/bad-assoc-pat.stderr
@@ -0,0 +1,85 @@
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-pat.rs:3:9
+ |
+LL | [u8]::AssocItem => {}
+ | ^^^^^^^^^^^^^^^ help: try: `<[u8]>::AssocItem`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-pat.rs:6:9
+ |
+LL | (u8, u8)::AssocItem => {}
+ | ^^^^^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::AssocItem`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-pat.rs:9:9
+ |
+LL | _::AssocItem => {}
+ | ^^^^^^^^^^^^ help: try: `<_>::AssocItem`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-pat.rs:14:10
+ |
+LL | &(u8,)::AssocItem => {}
+ | ^^^^^^^^^^^^^^^^ help: try: `<(u8,)>::AssocItem`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-pat.rs:32:9
+ |
+LL | ty!()::AssocItem => {}
+ | ^^^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocItem`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-pat.rs:21:19
+ |
+LL | ($ty: ty) => ($ty::AssocItem)
+ | ^^^^^^^^^^^^^^ help: try: `<$ty>::AssocItem`
+...
+LL | pat!(u8) => {}
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `pat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0599]: no associated item named `AssocItem` found for slice `[u8]` in the current scope
+ --> $DIR/bad-assoc-pat.rs:3:15
+ |
+LL | [u8]::AssocItem => {}
+ | ^^^^^^^^^ associated item not found in `[u8]`
+
+error[E0599]: no associated item named `AssocItem` found for tuple `(u8, u8)` in the current scope
+ --> $DIR/bad-assoc-pat.rs:6:19
+ |
+LL | (u8, u8)::AssocItem => {}
+ | ^^^^^^^^^ associated item not found in `(u8, u8)`
+
+error[E0599]: no associated item named `AssocItem` found for type `_` in the current scope
+ --> $DIR/bad-assoc-pat.rs:9:12
+ |
+LL | _::AssocItem => {}
+ | ^^^^^^^^^ associated item not found in `_`
+
+error[E0599]: no associated item named `AssocItem` found for tuple `(u8,)` in the current scope
+ --> $DIR/bad-assoc-pat.rs:14:17
+ |
+LL | &(u8,)::AssocItem => {}
+ | ^^^^^^^^^ associated item not found in `(u8,)`
+
+error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope
+ --> $DIR/bad-assoc-pat.rs:21:24
+ |
+LL | ($ty: ty) => ($ty::AssocItem)
+ | ^^^^^^^^^ associated item not found in `u8`
+...
+LL | pat!(u8) => {}
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `pat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope
+ --> $DIR/bad-assoc-pat.rs:32:16
+ |
+LL | ty!()::AssocItem => {}
+ | ^^^^^^^^^ associated item not found in `u8`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.rs b/src/test/ui/did_you_mean/bad-assoc-ty.rs
new file mode 100644
index 000000000..f787c416c
--- /dev/null
+++ b/src/test/ui/did_you_mean/bad-assoc-ty.rs
@@ -0,0 +1,85 @@
+type A = [u8; 4]::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+type B = [u8]::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+type C = (u8)::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+type D = (u8, u8)::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+type E = _::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR the placeholder `_` is not allowed within types on item signatures for type aliases
+
+type F = &'static (u8)::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+// Qualified paths cannot appear in bounds, so the recovery
+// should apply to the whole sum and not `(Send)`.
+type G = dyn 'static + (Send)::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+// This is actually a legal path with fn-like generic arguments in the middle!
+// Recovery should not apply in this context.
+type H = Fn(u8) -> (u8)::Output;
+//~^ ERROR ambiguous associated type
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+macro_rules! ty {
+ ($ty: ty) => ($ty::AssocTy);
+ //~^ ERROR missing angle brackets in associated item path
+ //~| ERROR ambiguous associated type
+ () => (u8);
+}
+
+type J = ty!(u8);
+type I = ty!()::AssocTy;
+//~^ ERROR missing angle brackets in associated item path
+//~| ERROR ambiguous associated type
+
+trait K<A, B> {}
+fn foo<X: K<_, _>>(x: X) {}
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+
+fn bar<F>(_: F) where F: Fn() -> _ {}
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+
+fn baz<F: Fn() -> _>(_: F) {}
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+
+struct L<F>(F) where F: Fn() -> _;
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs
+struct M<F> where F: Fn() -> _ {
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs
+ a: F,
+}
+enum N<F> where F: Fn() -> _ {
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for enums
+ Foo(F),
+}
+
+union O<F> where F: Fn() -> _ {
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for unions
+ foo: F,
+}
+
+trait P<F> where F: Fn() -> _ {
+//~^ ERROR the placeholder `_` is not allowed within types on item signatures for traits
+}
+
+trait Q {
+ fn foo<F>(_: F) where F: Fn() -> _ {}
+ //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr
new file mode 100644
index 000000000..2326af934
--- /dev/null
+++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr
@@ -0,0 +1,243 @@
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:1:10
+ |
+LL | type A = [u8; 4]::AssocTy;
+ | ^^^^^^^^^^^^^^^^ help: try: `<[u8; 4]>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:5:10
+ |
+LL | type B = [u8]::AssocTy;
+ | ^^^^^^^^^^^^^ help: try: `<[u8]>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:9:10
+ |
+LL | type C = (u8)::AssocTy;
+ | ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:13:10
+ |
+LL | type D = (u8, u8)::AssocTy;
+ | ^^^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:17:10
+ |
+LL | type E = _::AssocTy;
+ | ^^^^^^^^^^ help: try: `<_>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:21:19
+ |
+LL | type F = &'static (u8)::AssocTy;
+ | ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:27:10
+ |
+LL | type G = dyn 'static + (Send)::AssocTy;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<dyn 'static + (Send)>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:46:10
+ |
+LL | type I = ty!()::AssocTy;
+ | ^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocTy`
+
+error: missing angle brackets in associated item path
+ --> $DIR/bad-assoc-ty.rs:39:19
+ |
+LL | ($ty: ty) => ($ty::AssocTy);
+ | ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy`
+...
+LL | type J = ty!(u8);
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:1:10
+ |
+LL | type A = [u8; 4]::AssocTy;
+ | ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; 4] as Trait>::AssocTy`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:5:10
+ |
+LL | type B = [u8]::AssocTy;
+ | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8] as Trait>::AssocTy`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:9:10
+ |
+LL | type C = (u8)::AssocTy;
+ | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:13:10
+ |
+LL | type D = (u8, u8)::AssocTy;
+ | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(u8, u8) as Trait>::AssocTy`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases
+ --> $DIR/bad-assoc-ty.rs:17:10
+ |
+LL | type E = _::AssocTy;
+ | ^ not allowed in type signatures
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:21:19
+ |
+LL | type F = &'static (u8)::AssocTy;
+ | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:27:10
+ |
+LL | type G = dyn 'static + (Send)::AssocTy;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Send + 'static) as Trait>::AssocTy`
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/bad-assoc-ty.rs:33:10
+ |
+LL | type H = Fn(u8) -> (u8)::Output;
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(bare_trait_objects)]` on by default
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | type H = <dyn Fn(u8) -> (u8)>::Output;
+ | ++++ +
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:33:10
+ |
+LL | type H = Fn(u8) -> (u8)::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as Trait>::Output`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:39:19
+ |
+LL | ($ty: ty) => ($ty::AssocTy);
+ | ^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
+...
+LL | type J = ty!(u8);
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bad-assoc-ty.rs:46:10
+ |
+LL | type I = ty!()::AssocTy;
+ | ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+ --> $DIR/bad-assoc-ty.rs:51:13
+ |
+LL | fn foo<X: K<_, _>>(x: X) {}
+ | ^ ^ not allowed in type signatures
+ | |
+ | not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | fn foo<X: K<T, T>, T>(x: X) {}
+ | ~ ~ +++
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+ --> $DIR/bad-assoc-ty.rs:54:34
+ |
+LL | fn bar<F>(_: F) where F: Fn() -> _ {}
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | fn bar<F, T>(_: F) where F: Fn() -> T {}
+ | +++ ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+ --> $DIR/bad-assoc-ty.rs:57:19
+ |
+LL | fn baz<F: Fn() -> _>(_: F) {}
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | fn baz<F: Fn() -> T, T>(_: F) {}
+ | ~+++
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
+ --> $DIR/bad-assoc-ty.rs:60:33
+ |
+LL | struct L<F>(F) where F: Fn() -> _;
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | struct L<F, T>(F) where F: Fn() -> T;
+ | +++ ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
+ --> $DIR/bad-assoc-ty.rs:62:30
+ |
+LL | struct M<F> where F: Fn() -> _ {
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | struct M<F, T> where F: Fn() -> T {
+ | +++ ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for enums
+ --> $DIR/bad-assoc-ty.rs:66:28
+ |
+LL | enum N<F> where F: Fn() -> _ {
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | enum N<F, T> where F: Fn() -> T {
+ | +++ ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for unions
+ --> $DIR/bad-assoc-ty.rs:71:29
+ |
+LL | union O<F> where F: Fn() -> _ {
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | union O<F, T> where F: Fn() -> T {
+ | +++ ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for traits
+ --> $DIR/bad-assoc-ty.rs:76:29
+ |
+LL | trait P<F> where F: Fn() -> _ {
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | trait P<F, T> where F: Fn() -> T {
+ | +++ ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+ --> $DIR/bad-assoc-ty.rs:81:38
+ |
+LL | fn foo<F>(_: F) where F: Fn() -> _ {}
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL | fn foo<F, T>(_: F) where F: Fn() -> T {}
+ | +++ ~
+
+error: aborting due to 28 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0121, E0223.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs b/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs
new file mode 100644
index 000000000..4d0109767
--- /dev/null
+++ b/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs
@@ -0,0 +1,10 @@
+const A: [&str; 1] = { "hello" };
+//~^ ERROR mismatched types
+
+const B: &[u32] = &{ 1 };
+//~^ ERROR mismatched types
+
+const C: &&[u32; 1] = &&{ 1 };
+//~^ ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr b/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr
new file mode 100644
index 000000000..6ded03e45
--- /dev/null
+++ b/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr
@@ -0,0 +1,38 @@
+error[E0308]: mismatched types
+ --> $DIR/brackets-to-braces-single-element.rs:1:24
+ |
+LL | const A: [&str; 1] = { "hello" };
+ | ^^^^^^^ expected array `[&'static str; 1]`, found `&str`
+ |
+help: to create an array, use square brackets instead of curly braces
+ |
+LL | const A: [&str; 1] = [ "hello" ];
+ | ~ ~
+
+error[E0308]: mismatched types
+ --> $DIR/brackets-to-braces-single-element.rs:4:19
+ |
+LL | const B: &[u32] = &{ 1 };
+ | ^^^^^^ expected slice `[u32]`, found integer
+ |
+ = note: expected reference `&'static [u32]`
+ found reference `&{integer}`
+help: to create an array, use square brackets instead of curly braces
+ |
+LL | const B: &[u32] = &[ 1 ];
+ | ~ ~
+
+error[E0308]: mismatched types
+ --> $DIR/brackets-to-braces-single-element.rs:7:27
+ |
+LL | const C: &&[u32; 1] = &&{ 1 };
+ | ^ expected array `[u32; 1]`, found integer
+ |
+help: to create an array, use square brackets instead of curly braces
+ |
+LL | const C: &&[u32; 1] = &&[ 1 ];
+ | ~ ~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/compatible-variants-in-pat.rs b/src/test/ui/did_you_mean/compatible-variants-in-pat.rs
new file mode 100644
index 000000000..09e12dab2
--- /dev/null
+++ b/src/test/ui/did_you_mean/compatible-variants-in-pat.rs
@@ -0,0 +1,41 @@
+enum Foo {
+ Bar(Bar),
+}
+struct Bar {
+ x: i32,
+}
+
+fn a(f: Foo) {
+ match f {
+ Bar { x } => {
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ }
+ }
+}
+
+struct S;
+
+fn b(s: Option<S>) {
+ match s {
+ S => {
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ //~| HELP introduce a new binding instead
+ }
+ _ => {}
+ }
+}
+
+fn c(s: Result<S, S>) {
+ match s {
+ S => {
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ //~| HELP introduce a new binding instead
+ }
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/compatible-variants-in-pat.stderr b/src/test/ui/did_you_mean/compatible-variants-in-pat.stderr
new file mode 100644
index 000000000..473468af6
--- /dev/null
+++ b/src/test/ui/did_you_mean/compatible-variants-in-pat.stderr
@@ -0,0 +1,68 @@
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants-in-pat.rs:10:9
+ |
+LL | match f {
+ | - this expression has type `Foo`
+LL | Bar { x } => {
+ | ^^^^^^^^^ expected enum `Foo`, found struct `Bar`
+ |
+help: try wrapping the pattern in `Foo::Bar`
+ |
+LL | Foo::Bar(Bar { x }) => {
+ | +++++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants-in-pat.rs:21:9
+ |
+LL | struct S;
+ | -------- unit struct defined here
+...
+LL | match s {
+ | - this expression has type `Option<S>`
+LL | S => {
+ | ^
+ | |
+ | expected enum `Option`, found struct `S`
+ | `S` is interpreted as a unit struct, not a new binding
+ |
+ = note: expected enum `Option<S>`
+ found struct `S`
+help: try wrapping the pattern in `Some`
+ |
+LL | Some(S) => {
+ | +++++ +
+help: introduce a new binding instead
+ |
+LL | other_s => {
+ | ~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants-in-pat.rs:32:9
+ |
+LL | struct S;
+ | -------- unit struct defined here
+...
+LL | match s {
+ | - this expression has type `Result<S, S>`
+LL | S => {
+ | ^
+ | |
+ | expected enum `Result`, found struct `S`
+ | `S` is interpreted as a unit struct, not a new binding
+ |
+ = note: expected enum `Result<S, S>`
+ found struct `S`
+help: try wrapping the pattern in a variant of `Result`
+ |
+LL | Ok(S) => {
+ | +++ +
+LL | Err(S) => {
+ | ++++ +
+help: introduce a new binding instead
+ |
+LL | other_s => {
+ | ~~~~~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/compatible-variants.rs b/src/test/ui/did_you_mean/compatible-variants.rs
new file mode 100644
index 000000000..b1c7dc2a7
--- /dev/null
+++ b/src/test/ui/did_you_mean/compatible-variants.rs
@@ -0,0 +1,89 @@
+enum Hey<A, B> {
+ A(A),
+ B(B),
+}
+
+struct Foo {
+ bar: Option<i32>,
+}
+
+fn f() {}
+
+fn a() -> Option<()> {
+ while false {
+ //~^ ERROR mismatched types
+ f();
+ }
+ //~^ HELP try adding an expression
+}
+
+fn b() -> Result<(), ()> {
+ f()
+ //~^ ERROR mismatched types
+ //~| HELP try adding an expression
+}
+
+fn c() -> Option<()> {
+ for _ in [1, 2] {
+ //~^ ERROR mismatched types
+ f();
+ }
+ //~^ HELP try adding an expression
+}
+
+fn d() -> Option<()> {
+ c()?
+ //~^ ERROR incompatible types
+ //~| HELP try removing this `?`
+ //~| HELP try adding an expression
+}
+
+fn main() {
+ let _: Option<()> = while false {};
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ let _: Option<()> = {
+ while false {}
+ //~^ ERROR mismatched types
+ //~| HELP try adding an expression
+ };
+ let _: Result<i32, i32> = 1;
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ let _: Option<i32> = 1;
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ let _: Hey<i32, i32> = 1;
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ let _: Hey<i32, bool> = false;
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+ let bar = 1i32;
+ let _ = Foo { bar };
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+}
+
+enum A {
+ B { b: B },
+}
+
+struct A2(B);
+
+enum B {
+ Fst,
+ Snd,
+}
+
+fn foo() {
+ let a: A = B::Fst;
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+}
+
+fn bar() {
+ let a: A2 = B::Fst;
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping
+}
diff --git a/src/test/ui/did_you_mean/compatible-variants.stderr b/src/test/ui/did_you_mean/compatible-variants.stderr
new file mode 100644
index 000000000..fe81da198
--- /dev/null
+++ b/src/test/ui/did_you_mean/compatible-variants.stderr
@@ -0,0 +1,221 @@
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:13:5
+ |
+LL | fn a() -> Option<()> {
+ | ---------- expected `Option<()>` because of return type
+LL | / while false {
+LL | |
+LL | | f();
+LL | | }
+ | |_____^ expected enum `Option`, found `()`
+ |
+ = note: expected enum `Option<()>`
+ found unit type `()`
+help: try adding an expression at the end of the block
+ |
+LL ~ }
+LL + None
+ |
+LL ~ }
+LL + Some(())
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:21:5
+ |
+LL | fn b() -> Result<(), ()> {
+ | -------------- expected `Result<(), ()>` because of return type
+LL | f()
+ | ^^^ expected enum `Result`, found `()`
+ |
+ = note: expected enum `Result<(), ()>`
+ found unit type `()`
+help: try adding an expression at the end of the block
+ |
+LL ~ f();
+LL + Ok(())
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:27:5
+ |
+LL | fn c() -> Option<()> {
+ | ---------- expected `Option<()>` because of return type
+LL | / for _ in [1, 2] {
+LL | |
+LL | | f();
+LL | | }
+ | |_____^ expected enum `Option`, found `()`
+ |
+ = note: expected enum `Option<()>`
+ found unit type `()`
+help: try adding an expression at the end of the block
+ |
+LL ~ }
+LL + None
+ |
+LL ~ }
+LL + Some(())
+ |
+
+error[E0308]: `?` operator has incompatible types
+ --> $DIR/compatible-variants.rs:35:5
+ |
+LL | c()?
+ | ^^^^ expected enum `Option`, found `()`
+ |
+ = note: `?` operator cannot convert from `()` to `Option<()>`
+ = note: expected enum `Option<()>`
+ found unit type `()`
+help: try removing this `?`
+ |
+LL - c()?
+LL + c()
+ |
+help: try adding an expression at the end of the block
+ |
+LL ~ c()?;
+LL + None
+ |
+LL ~ c()?;
+LL + Some(())
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:42:25
+ |
+LL | let _: Option<()> = while false {};
+ | ---------- ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
+ | |
+ | expected due to this
+ |
+ = note: expected enum `Option<()>`
+ found unit type `()`
+help: try wrapping the expression in `Some`
+ |
+LL | let _: Option<()> = Some(while false {});
+ | +++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:46:9
+ |
+LL | while false {}
+ | ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
+ |
+ = note: expected enum `Option<()>`
+ found unit type `()`
+help: try adding an expression at the end of the block
+ |
+LL ~ while false {}
+LL + None
+ |
+LL ~ while false {}
+LL + Some(())
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:50:31
+ |
+LL | let _: Result<i32, i32> = 1;
+ | ---------------- ^ expected enum `Result`, found integer
+ | |
+ | expected due to this
+ |
+ = note: expected enum `Result<i32, i32>`
+ found type `{integer}`
+help: try wrapping the expression in a variant of `Result`
+ |
+LL | let _: Result<i32, i32> = Ok(1);
+ | +++ +
+LL | let _: Result<i32, i32> = Err(1);
+ | ++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:53:26
+ |
+LL | let _: Option<i32> = 1;
+ | ----------- ^ expected enum `Option`, found integer
+ | |
+ | expected due to this
+ |
+ = note: expected enum `Option<i32>`
+ found type `{integer}`
+help: try wrapping the expression in `Some`
+ |
+LL | let _: Option<i32> = Some(1);
+ | +++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:56:28
+ |
+LL | let _: Hey<i32, i32> = 1;
+ | ------------- ^ expected enum `Hey`, found integer
+ | |
+ | expected due to this
+ |
+ = note: expected enum `Hey<i32, i32>`
+ found type `{integer}`
+help: try wrapping the expression in a variant of `Hey`
+ |
+LL | let _: Hey<i32, i32> = Hey::A(1);
+ | +++++++ +
+LL | let _: Hey<i32, i32> = Hey::B(1);
+ | +++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:59:29
+ |
+LL | let _: Hey<i32, bool> = false;
+ | -------------- ^^^^^ expected enum `Hey`, found `bool`
+ | |
+ | expected due to this
+ |
+ = note: expected enum `Hey<i32, bool>`
+ found type `bool`
+help: try wrapping the expression in `Hey::B`
+ |
+LL | let _: Hey<i32, bool> = Hey::B(false);
+ | +++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:63:19
+ |
+LL | let _ = Foo { bar };
+ | ^^^ expected enum `Option`, found `i32`
+ |
+ = note: expected enum `Option<i32>`
+ found type `i32`
+help: try wrapping the expression in `Some`
+ |
+LL | let _ = Foo { bar: Some(bar) };
+ | ++++++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:80:16
+ |
+LL | let a: A = B::Fst;
+ | - ^^^^^^ expected enum `A`, found enum `B`
+ | |
+ | expected due to this
+ |
+help: try wrapping the expression in `A::B`
+ |
+LL | let a: A = A::B { b: B::Fst };
+ | +++++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/compatible-variants.rs:86:17
+ |
+LL | let a: A2 = B::Fst;
+ | -- ^^^^^^ expected struct `A2`, found enum `B`
+ | |
+ | expected due to this
+ |
+help: try wrapping the expression in `A2`
+ |
+LL | let a: A2 = A2(B::Fst);
+ | +++ +
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs
new file mode 100644
index 000000000..1749137d4
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs
@@ -0,0 +1,26 @@
+trait Foo<A> {
+ fn foo(&self, a: A) -> A {
+ a
+ }
+}
+
+trait NotRelevant<A> {
+ fn nr(&self, a: A) -> A {
+ a
+ }
+}
+
+struct Bar;
+
+impl Foo<i32> for Bar {}
+
+impl Foo<u8> for Bar {}
+
+impl NotRelevant<usize> for Bar {}
+
+fn main() {
+ let f1 = Bar;
+
+ f1.foo(1usize);
+ //~^ error: the trait bound `Bar: Foo<usize>` is not satisfied
+}
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
new file mode 100644
index 000000000..26764bc0e
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
+ --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:8
+ |
+LL | f1.foo(1usize);
+ | ^^^ the trait `Foo<usize>` is not implemented for `Bar`
+ |
+ = help: the following other types implement trait `Foo<A>`:
+ <Bar as Foo<i32>>
+ <Bar as Foo<u8>>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs
new file mode 100644
index 000000000..e898b224e
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs
@@ -0,0 +1,30 @@
+trait Foo<A> {
+ fn foo(&self, a: A) -> A {
+ a
+ }
+}
+
+trait NotRelevant<A> {
+ fn nr(&self, a: A) -> A {
+ a
+ }
+}
+
+struct Bar;
+
+impl Foo<i8> for Bar {}
+impl Foo<i16> for Bar {}
+impl Foo<i32> for Bar {}
+
+impl Foo<u8> for Bar {}
+impl Foo<u16> for Bar {}
+impl Foo<u32> for Bar {}
+
+impl NotRelevant<usize> for Bar {}
+
+fn main() {
+ let f1 = Bar;
+
+ f1.foo(1usize);
+ //~^ error: the trait bound `Bar: Foo<usize>` is not satisfied
+}
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
new file mode 100644
index 000000000..bb175367e
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
+ --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:8
+ |
+LL | f1.foo(1usize);
+ | ^^^ the trait `Foo<usize>` is not implemented for `Bar`
+ |
+ = help: the following other types implement trait `Foo<A>`:
+ <Bar as Foo<i16>>
+ <Bar as Foo<i32>>
+ <Bar as Foo<i8>>
+ <Bar as Foo<u16>>
+ <Bar as Foo<u32>>
+ <Bar as Foo<u8>>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/did_you_mean/issue-31424.rs b/src/test/ui/did_you_mean/issue-31424.rs
new file mode 100644
index 000000000..95ccf2a4c
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-31424.rs
@@ -0,0 +1,21 @@
+// forbid-output: &mut mut self
+
+struct Struct;
+
+impl Struct {
+ fn foo(&mut self) {
+ (&mut self).bar(); //~ ERROR cannot borrow
+ //~^ HELP try removing `&mut` here
+ }
+
+ // In this case we could keep the suggestion, but to distinguish the
+ // two cases is pretty hard. It's an obscure case anyway.
+ fn bar(self: &mut Self) {
+ //~^ WARN function cannot return without recursing
+ //~^^ HELP a `loop` may express intention better if this is on purpose
+ (&mut self).bar(); //~ ERROR cannot borrow
+ //~^ HELP try removing `&mut` here
+ }
+}
+
+fn main () {}
diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr
new file mode 100644
index 000000000..886173812
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-31424.stderr
@@ -0,0 +1,49 @@
+error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
+ --> $DIR/issue-31424.rs:7:9
+ |
+LL | (&mut self).bar();
+ | ^^^^^^^^^^^ cannot borrow as mutable
+ |
+note: the binding is already a mutable borrow
+ --> $DIR/issue-31424.rs:6:12
+ |
+LL | fn foo(&mut self) {
+ | ^^^^^^^^^
+help: try removing `&mut` here
+ --> $DIR/issue-31424.rs:7:9
+ |
+LL | (&mut self).bar();
+ | ^^^^^^^^^^^
+
+warning: function cannot return without recursing
+ --> $DIR/issue-31424.rs:13:5
+ |
+LL | fn bar(self: &mut Self) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+...
+LL | (&mut self).bar();
+ | ----------------- recursive call site
+ |
+ = note: `#[warn(unconditional_recursion)]` on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
+ --> $DIR/issue-31424.rs:16:9
+ |
+LL | (&mut self).bar();
+ | ^^^^^^^^^^^ cannot borrow as mutable
+ |
+note: the binding is already a mutable borrow
+ --> $DIR/issue-31424.rs:13:18
+ |
+LL | fn bar(self: &mut Self) {
+ | ^^^^^^^^^
+help: try removing `&mut` here
+ --> $DIR/issue-31424.rs:16:9
+ |
+LL | (&mut self).bar();
+ | ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-34126.rs b/src/test/ui/did_you_mean/issue-34126.rs
new file mode 100644
index 000000000..53516f4f2
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-34126.rs
@@ -0,0 +1,15 @@
+struct Z { }
+
+impl Z {
+ fn run(&self, z: &mut Z) { }
+ fn start(&mut self) {
+ self.run(&mut self); //~ ERROR cannot borrow
+ //~| ERROR cannot borrow
+ //~| HELP try removing `&mut` here
+ }
+}
+
+fn main() {
+ let mut z = Z {};
+ z.start();
+}
diff --git a/src/test/ui/did_you_mean/issue-34126.stderr b/src/test/ui/did_you_mean/issue-34126.stderr
new file mode 100644
index 000000000..5343acea4
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-34126.stderr
@@ -0,0 +1,31 @@
+error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
+ --> $DIR/issue-34126.rs:6:18
+ |
+LL | self.run(&mut self);
+ | ^^^^^^^^^ cannot borrow as mutable
+ |
+note: the binding is already a mutable borrow
+ --> $DIR/issue-34126.rs:5:14
+ |
+LL | fn start(&mut self) {
+ | ^^^^^^^^^
+help: try removing `&mut` here
+ |
+LL - self.run(&mut self);
+LL + self.run(self);
+ |
+
+error[E0502]: cannot borrow `self` as mutable because it is also borrowed as immutable
+ --> $DIR/issue-34126.rs:6:18
+ |
+LL | self.run(&mut self);
+ | ---------^^^^^^^^^-
+ | | | |
+ | | | mutable borrow occurs here
+ | | immutable borrow later used by call
+ | immutable borrow occurs here
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0502, E0596.
+For more information about an error, try `rustc --explain E0502`.
diff --git a/src/test/ui/did_you_mean/issue-34337.rs b/src/test/ui/did_you_mean/issue-34337.rs
new file mode 100644
index 000000000..e89eda33f
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-34337.rs
@@ -0,0 +1,8 @@
+fn get(key: &mut String) { }
+
+fn main() {
+ let mut v: Vec<String> = Vec::new();
+ let ref mut key = v[0];
+ get(&mut key); //~ ERROR cannot borrow
+ //~| HELP try removing `&mut` here
+}
diff --git a/src/test/ui/did_you_mean/issue-34337.stderr b/src/test/ui/did_you_mean/issue-34337.stderr
new file mode 100644
index 000000000..1f18ea892
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-34337.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `key` as mutable, as it is not declared as mutable
+ --> $DIR/issue-34337.rs:6:9
+ |
+LL | get(&mut key);
+ | ^^^^^^^^
+ | |
+ | cannot borrow as mutable
+ | help: try removing `&mut` here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-35937.rs b/src/test/ui/did_you_mean/issue-35937.rs
new file mode 100644
index 000000000..ebeba74f1
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-35937.rs
@@ -0,0 +1,21 @@
+struct Foo {
+ pub v: Vec<String>
+}
+
+fn main() {
+ let f = Foo { v: Vec::new() };
+ f.v.push("cat".to_string()); //~ ERROR cannot borrow
+}
+
+
+struct S {
+ x: i32,
+}
+fn foo() {
+ let s = S { x: 42 };
+ s.x += 1; //~ ERROR cannot assign
+}
+
+fn bar(s: S) {
+ s.x += 1; //~ ERROR cannot assign
+}
diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr
new file mode 100644
index 000000000..9562d9450
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-35937.stderr
@@ -0,0 +1,28 @@
+error[E0596]: cannot borrow `f.v` as mutable, as `f` is not declared as mutable
+ --> $DIR/issue-35937.rs:7:5
+ |
+LL | let f = Foo { v: Vec::new() };
+ | - help: consider changing this to be mutable: `mut f`
+LL | f.v.push("cat".to_string());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
+
+error[E0594]: cannot assign to `s.x`, as `s` is not declared as mutable
+ --> $DIR/issue-35937.rs:16:5
+ |
+LL | let s = S { x: 42 };
+ | - help: consider changing this to be mutable: `mut s`
+LL | s.x += 1;
+ | ^^^^^^^^ cannot assign
+
+error[E0594]: cannot assign to `s.x`, as `s` is not declared as mutable
+ --> $DIR/issue-35937.rs:20:5
+ |
+LL | fn bar(s: S) {
+ | - help: consider changing this to be mutable: `mut s`
+LL | s.x += 1;
+ | ^^^^^^^^ cannot assign
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0594, E0596.
+For more information about an error, try `rustc --explain E0594`.
diff --git a/src/test/ui/did_you_mean/issue-36798.rs b/src/test/ui/did_you_mean/issue-36798.rs
new file mode 100644
index 000000000..89d71d831
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-36798.rs
@@ -0,0 +1,8 @@
+struct Foo {
+ bar: u8
+}
+
+fn main() {
+ let f = Foo { bar: 22 };
+ f.baz; //~ ERROR no field
+}
diff --git a/src/test/ui/did_you_mean/issue-36798.stderr b/src/test/ui/did_you_mean/issue-36798.stderr
new file mode 100644
index 000000000..98876e305
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-36798.stderr
@@ -0,0 +1,9 @@
+error[E0609]: no field `baz` on type `Foo`
+ --> $DIR/issue-36798.rs:7:7
+ |
+LL | f.baz;
+ | ^^^ help: a field with a similar name exists: `bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/did_you_mean/issue-36798_unknown_field.rs b/src/test/ui/did_you_mean/issue-36798_unknown_field.rs
new file mode 100644
index 000000000..ef9744b4a
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-36798_unknown_field.rs
@@ -0,0 +1,8 @@
+struct Foo {
+ bar: u8
+}
+
+fn main() {
+ let f = Foo { bar: 22 };
+ f.zz; //~ ERROR no field
+}
diff --git a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
new file mode 100644
index 000000000..2ed0a0924
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
@@ -0,0 +1,11 @@
+error[E0609]: no field `zz` on type `Foo`
+ --> $DIR/issue-36798_unknown_field.rs:7:7
+ |
+LL | f.zz;
+ | ^^ unknown field
+ |
+ = note: available fields are: `bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/did_you_mean/issue-37139.rs b/src/test/ui/did_you_mean/issue-37139.rs
new file mode 100644
index 000000000..6a19d85ff
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-37139.rs
@@ -0,0 +1,16 @@
+enum TestEnum {
+ Item(i32),
+}
+
+fn test(_: &mut i32) {
+}
+
+fn main() {
+ let mut x = TestEnum::Item(10);
+ match x {
+ TestEnum::Item(ref mut x) => {
+ test(&mut x); //~ ERROR cannot borrow `x` as mutable, as it is not declared as mutable
+ //~| HELP try removing `&mut` here
+ }
+ }
+}
diff --git a/src/test/ui/did_you_mean/issue-37139.stderr b/src/test/ui/did_you_mean/issue-37139.stderr
new file mode 100644
index 000000000..dc1bdfaae
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-37139.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/issue-37139.rs:12:18
+ |
+LL | test(&mut x);
+ | ^^^^^^
+ | |
+ | cannot borrow as mutable
+ | help: try removing `&mut` here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs
new file mode 100644
index 000000000..a1ef68ecf
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs
@@ -0,0 +1,5 @@
+use Foo; //~ ERROR unresolved
+
+use Foo1; //~ ERROR unresolved
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
new file mode 100644
index 000000000..852abaed7
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
@@ -0,0 +1,15 @@
+error[E0432]: unresolved import `Foo`
+ --> $DIR/issue-38054-do-not-show-unresolved-names.rs:1:5
+ |
+LL | use Foo;
+ | ^^^ no `Foo` in the root
+
+error[E0432]: unresolved import `Foo1`
+ --> $DIR/issue-38054-do-not-show-unresolved-names.rs:3:5
+ |
+LL | use Foo1;
+ | ^^^^ no `Foo1` in the root
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/ui/did_you_mean/issue-38147-1.rs b/src/test/ui/did_you_mean/issue-38147-1.rs
new file mode 100644
index 000000000..c068a1834
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-1.rs
@@ -0,0 +1,21 @@
+struct Pass<'a> {
+ s: &'a mut String
+}
+
+impl<'a> Pass<'a> {
+ fn f(&mut self) {
+ self.s.push('x');
+ }
+}
+
+struct Foo<'a> {
+ s: &'a mut String
+}
+
+impl<'a> Foo<'a> {
+ fn f(&self) {
+ self.s.push('x'); //~ cannot borrow `*self.s` as mutable, as it is behind a `&` reference
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-38147-1.stderr b/src/test/ui/did_you_mean/issue-38147-1.stderr
new file mode 100644
index 000000000..dd193458b
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-1.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-38147-1.rs:17:9
+ |
+LL | fn f(&self) {
+ | ----- help: consider changing this to be a mutable reference: `&mut self`
+LL | self.s.push('x');
+ | ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-38147-2.rs b/src/test/ui/did_you_mean/issue-38147-2.rs
new file mode 100644
index 000000000..154b149b7
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-2.rs
@@ -0,0 +1,17 @@
+struct Bar<'a> {
+ s: &'a String,
+ // use wonky spaces to ensure we are creating the span correctly
+ longer_name: & 'a Vec<u8>
+}
+
+impl<'a> Bar<'a> {
+ fn f(&mut self) {
+ self.s.push('x');
+ //~^ ERROR cannot borrow `*self.s` as mutable, as it is behind a `&` reference
+
+ self.longer_name.push(13);
+ //~^ ERROR cannot borrow `*self.longer_name` as mutable, as it is behind a `&` reference
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr
new file mode 100644
index 000000000..7c287a7db
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-2.stderr
@@ -0,0 +1,25 @@
+error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-38147-2.rs:9:9
+ |
+LL | self.s.push('x');
+ | ^^^^^^^^^^^^^^^^ cannot borrow as mutable
+ |
+help: consider changing this to be mutable
+ |
+LL | s: &'a mut String,
+ | +++
+
+error[E0596]: cannot borrow `*self.longer_name` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-38147-2.rs:12:9
+ |
+LL | self.longer_name.push(13);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
+ |
+help: consider changing this to be mutable
+ |
+LL | longer_name: & 'a mut Vec<u8>
+ | +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-38147-3.rs b/src/test/ui/did_you_mean/issue-38147-3.rs
new file mode 100644
index 000000000..40b8e0dba
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-3.rs
@@ -0,0 +1,12 @@
+struct Qux<'a> {
+ s: &'a String
+}
+
+impl<'a> Qux<'a> {
+ fn f(&self) {
+ self.s.push('x');
+ //~^ ERROR cannot borrow `*self.s` as mutable, as it is behind a `&` reference
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr
new file mode 100644
index 000000000..94ffe17f1
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-3.stderr
@@ -0,0 +1,14 @@
+error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-38147-3.rs:7:9
+ |
+LL | self.s.push('x');
+ | ^^^^^^^^^^^^^^^^ cannot borrow as mutable
+ |
+help: consider changing this to be mutable
+ |
+LL | s: &'a mut String
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-38147-4.rs b/src/test/ui/did_you_mean/issue-38147-4.rs
new file mode 100644
index 000000000..e2028a9e6
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-4.rs
@@ -0,0 +1,9 @@
+struct Foo<'a> {
+ s: &'a mut String
+}
+
+fn f(x: usize, f: &Foo) {
+ f.s.push('x'); //~ ERROR cannot borrow `*f.s` as mutable, as it is behind a `&` reference
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-38147-4.stderr b/src/test/ui/did_you_mean/issue-38147-4.stderr
new file mode 100644
index 000000000..a2d162f08
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-38147-4.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `*f.s` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-38147-4.rs:6:5
+ |
+LL | fn f(x: usize, f: &Foo) {
+ | ---- help: consider changing this to be a mutable reference: `&mut Foo<'_>`
+LL | f.s.push('x');
+ | ^^^^^^^^^^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-39544.rs b/src/test/ui/did_you_mean/issue-39544.rs
new file mode 100644
index 000000000..a19d3f704
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-39544.rs
@@ -0,0 +1,50 @@
+pub enum X {
+ Y
+}
+
+pub struct Z {
+ x: X
+}
+
+fn main() {
+ let z = Z { x: X::Y };
+ let _ = &mut z.x; //~ ERROR cannot borrow
+}
+
+impl Z {
+ fn foo<'z>(&'z self) {
+ let _ = &mut self.x; //~ ERROR cannot borrow
+ }
+
+ fn foo1(&self, other: &Z) {
+ let _ = &mut self.x; //~ ERROR cannot borrow
+ let _ = &mut other.x; //~ ERROR cannot borrow
+ }
+
+ fn foo2<'a>(&'a self, other: &Z) {
+ let _ = &mut self.x; //~ ERROR cannot borrow
+ let _ = &mut other.x; //~ ERROR cannot borrow
+ }
+
+ fn foo3<'a>(self: &'a Self, other: &Z) {
+ let _ = &mut self.x; //~ ERROR cannot borrow
+ let _ = &mut other.x; //~ ERROR cannot borrow
+ }
+
+ fn foo4(other: &Z) {
+ let _ = &mut other.x; //~ ERROR cannot borrow
+ }
+
+}
+
+pub fn with_arg(z: Z, w: &Z) {
+ let _ = &mut z.x; //~ ERROR cannot borrow
+ let _ = &mut w.x; //~ ERROR cannot borrow
+}
+
+pub fn with_tuple() {
+ let mut y = 0;
+ let x = (&y,);
+ *x.0 = 1;
+ //~^ ERROR cannot assign to `*x.0`, which is behind a `&` reference
+}
diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr
new file mode 100644
index 000000000..68180eaee
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-39544.stderr
@@ -0,0 +1,102 @@
+error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
+ --> $DIR/issue-39544.rs:11:13
+ |
+LL | let z = Z { x: X::Y };
+ | - help: consider changing this to be mutable: `mut z`
+LL | let _ = &mut z.x;
+ | ^^^^^^^^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:16:17
+ |
+LL | fn foo<'z>(&'z self) {
+ | -------- help: consider changing this to be a mutable reference: `&'z mut self`
+LL | let _ = &mut self.x;
+ | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:20:17
+ |
+LL | fn foo1(&self, other: &Z) {
+ | ----- help: consider changing this to be a mutable reference: `&mut self`
+LL | let _ = &mut self.x;
+ | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:21:17
+ |
+LL | fn foo1(&self, other: &Z) {
+ | -- help: consider changing this to be a mutable reference: `&mut Z`
+LL | let _ = &mut self.x;
+LL | let _ = &mut other.x;
+ | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:25:17
+ |
+LL | fn foo2<'a>(&'a self, other: &Z) {
+ | -------- help: consider changing this to be a mutable reference: `&'a mut self`
+LL | let _ = &mut self.x;
+ | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:26:17
+ |
+LL | fn foo2<'a>(&'a self, other: &Z) {
+ | -- help: consider changing this to be a mutable reference: `&mut Z`
+LL | let _ = &mut self.x;
+LL | let _ = &mut other.x;
+ | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:30:17
+ |
+LL | fn foo3<'a>(self: &'a Self, other: &Z) {
+ | -------- help: consider changing this to be a mutable reference: `&'a mut Self`
+LL | let _ = &mut self.x;
+ | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:31:17
+ |
+LL | fn foo3<'a>(self: &'a Self, other: &Z) {
+ | -- help: consider changing this to be a mutable reference: `&mut Z`
+LL | let _ = &mut self.x;
+LL | let _ = &mut other.x;
+ | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:35:17
+ |
+LL | fn foo4(other: &Z) {
+ | -- help: consider changing this to be a mutable reference: `&mut Z`
+LL | let _ = &mut other.x;
+ | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
+ --> $DIR/issue-39544.rs:41:13
+ |
+LL | pub fn with_arg(z: Z, w: &Z) {
+ | - help: consider changing this to be mutable: `mut z`
+LL | let _ = &mut z.x;
+ | ^^^^^^^^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `w.x` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-39544.rs:42:13
+ |
+LL | pub fn with_arg(z: Z, w: &Z) {
+ | -- help: consider changing this to be a mutable reference: `&mut Z`
+LL | let _ = &mut z.x;
+LL | let _ = &mut w.x;
+ | ^^^^^^^^ `w` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0594]: cannot assign to `*x.0`, which is behind a `&` reference
+ --> $DIR/issue-39544.rs:48:5
+ |
+LL | *x.0 = 1;
+ | ^^^^^^^^ cannot assign
+
+error: aborting due to 12 previous errors
+
+Some errors have detailed explanations: E0594, E0596.
+For more information about an error, try `rustc --explain E0594`.
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs
new file mode 100644
index 000000000..63a8c547c
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs
@@ -0,0 +1,27 @@
+trait Foo<B> {
+ fn bar(&self){}
+}
+
+impl Foo<u8> for i8 {}
+impl Foo<u16> for i8 {}
+impl Foo<u32> for i8 {}
+impl Foo<u64> for i8 {}
+impl Foo<bool> for i8 {}
+
+impl Foo<u16> for u8 {}
+impl Foo<u32> for u8 {}
+impl Foo<u64> for u8 {}
+impl Foo<bool> for u8 {}
+
+impl Foo<u8> for bool {}
+impl Foo<u16> for bool {}
+impl Foo<u32> for bool {}
+impl Foo<u64> for bool {}
+impl Foo<bool> for bool {}
+impl Foo<i8> for bool {}
+
+fn main() {
+ Foo::<i32>::bar(&1i8); //~ ERROR is not satisfied
+ Foo::<i32>::bar(&1u8); //~ ERROR is not satisfied
+ Foo::<i32>::bar(&true); //~ ERROR is not satisfied
+}
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
new file mode 100644
index 000000000..d27b05fe7
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -0,0 +1,57 @@
+error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
+ --> $DIR/issue-39802-show-5-trait-impls.rs:24:21
+ |
+LL | Foo::<i32>::bar(&1i8);
+ | --------------- ^^^^ the trait `Foo<i32>` is not implemented for `i8`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `Foo<B>`:
+ <i8 as Foo<bool>>
+ <i8 as Foo<u16>>
+ <i8 as Foo<u32>>
+ <i8 as Foo<u64>>
+ <i8 as Foo<u8>>
+ <u8 as Foo<bool>>
+ <u8 as Foo<u16>>
+ <u8 as Foo<u32>>
+ <u8 as Foo<u64>>
+
+error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
+ --> $DIR/issue-39802-show-5-trait-impls.rs:25:21
+ |
+LL | Foo::<i32>::bar(&1u8);
+ | --------------- ^^^^ the trait `Foo<i32>` is not implemented for `u8`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `Foo<B>`:
+ <i8 as Foo<bool>>
+ <i8 as Foo<u16>>
+ <i8 as Foo<u32>>
+ <i8 as Foo<u64>>
+ <i8 as Foo<u8>>
+ <u8 as Foo<bool>>
+ <u8 as Foo<u16>>
+ <u8 as Foo<u32>>
+ <u8 as Foo<u64>>
+
+error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
+ --> $DIR/issue-39802-show-5-trait-impls.rs:26:21
+ |
+LL | Foo::<i32>::bar(&true);
+ | --------------- ^^^^^ the trait `Foo<i32>` is not implemented for `bool`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `Foo<B>`:
+ <bool as Foo<bool>>
+ <bool as Foo<i8>>
+ <bool as Foo<u16>>
+ <bool as Foo<u32>>
+ <bool as Foo<u64>>
+ <bool as Foo<u8>>
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs
new file mode 100644
index 000000000..74f304d81
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40006.rs
@@ -0,0 +1,39 @@
+impl dyn A {
+ Y
+} //~ ERROR expected one of `!` or `::`, found `}`
+
+struct S;
+
+trait X {
+ X() {} //~ ERROR expected one of `!` or `::`, found `(`
+ fn xxx() { ### }
+ L = M;
+ Z = { 2 + 3 };
+ ::Y ();
+}
+
+trait A {
+ X() {} //~ ERROR expected one of `!` or `::`, found `(`
+}
+trait B {
+ fn xxx() { ### } //~ ERROR expected
+}
+trait C {
+ L = M; //~ ERROR expected one of `!` or `::`, found `=`
+}
+trait D {
+ Z = { 2 + 3 }; //~ ERROR expected one of `!` or `::`, found `=`
+}
+trait E {
+ ::Y (); //~ ERROR expected one of
+}
+
+impl S {
+ pub hello_method(&self) { //~ ERROR missing
+ println!("Hello");
+ }
+}
+
+fn main() {
+ S.hello_method(); //~ no method named `hello_method` found
+}
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
new file mode 100644
index 000000000..bdbfa4dd7
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -0,0 +1,98 @@
+error: expected one of `!` or `::`, found `}`
+ --> $DIR/issue-40006.rs:3:1
+ |
+LL | impl dyn A {
+ | - while parsing this item list starting here
+LL | Y
+ | - expected one of `!` or `::`
+LL | }
+ | ^
+ | |
+ | unexpected token
+ | the item list ends here
+
+error: expected one of `!` or `::`, found `(`
+ --> $DIR/issue-40006.rs:8:6
+ |
+LL | trait X {
+ | - while parsing this item list starting here
+LL | X() {}
+ | ^ expected one of `!` or `::`
+...
+LL | }
+ | - the item list ends here
+
+error: expected one of `!` or `::`, found `(`
+ --> $DIR/issue-40006.rs:16:6
+ |
+LL | trait A {
+ | - while parsing this item list starting here
+LL | X() {}
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error: expected one of `!` or `[`, found `#`
+ --> $DIR/issue-40006.rs:19:17
+ |
+LL | fn xxx() { ### }
+ | ^ expected one of `!` or `[`
+
+error: expected one of `!` or `::`, found `=`
+ --> $DIR/issue-40006.rs:22:7
+ |
+LL | trait C {
+ | - while parsing this item list starting here
+LL | L = M;
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error: expected one of `!` or `::`, found `=`
+ --> $DIR/issue-40006.rs:25:7
+ |
+LL | trait D {
+ | - while parsing this item list starting here
+LL | Z = { 2 + 3 };
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error: expected one of `!` or `::`, found `(`
+ --> $DIR/issue-40006.rs:28:9
+ |
+LL | trait E {
+ | - while parsing this item list starting here
+LL | ::Y ();
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error: missing `fn` for method definition
+ --> $DIR/issue-40006.rs:32:8
+ |
+LL | impl S {
+ | - while parsing this item list starting here
+LL | pub hello_method(&self) {
+ | ^
+...
+LL | }
+ | - the item list ends here
+ |
+help: add `fn` here to parse `hello_method` as a public method
+ |
+LL | pub fn hello_method(&self) {
+ | ++
+
+error[E0599]: no method named `hello_method` found for struct `S` in the current scope
+ --> $DIR/issue-40006.rs:38:7
+ |
+LL | struct S;
+ | -------- method `hello_method` not found for this struct
+...
+LL | S.hello_method();
+ | ^^^^^^^^^^^^ method not found in `S`
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/did_you_mean/issue-40396.rs b/src/test/ui/did_you_mean/issue-40396.rs
new file mode 100644
index 000000000..5497ba2e1
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40396.rs
@@ -0,0 +1,29 @@
+fn main() {
+ (0..13).collect<Vec<i32>>();
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP use `::<...>` instead
+ Vec<i32>::new();
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP use `::<...>` instead
+ (0..13).collect<Vec<i32>();
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP use `::<...>` instead
+ let x = std::collections::HashMap<i128, i128>::new(); //~ ERROR expected one of
+ //~^ HELP use `::<...>` instead
+ let x: () = 42; //~ ERROR mismatched types
+ let x = {
+ std::collections::HashMap<i128, i128>::new() //~ ERROR expected one of
+ //~^ HELP use `::<...>` instead
+ };
+ let x: () = 42; //~ ERROR mismatched types
+ let x = {
+ std::collections::HashMap<i128, i128>::new(); //~ ERROR expected one of
+ //~^ HELP use `::<...>` instead
+ let x: () = 42; //~ ERROR mismatched types
+ };
+ {
+ std::collections::HashMap<i128, i128>::new(1, 2); //~ ERROR expected one of
+ //~^ HELP use `::<...>` instead
+ let x: () = 32; //~ ERROR mismatched types
+ };
+}
diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr
new file mode 100644
index 000000000..d0249efd0
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40396.stderr
@@ -0,0 +1,112 @@
+error: comparison operators cannot be chained
+ --> $DIR/issue-40396.rs:2:20
+ |
+LL | (0..13).collect<Vec<i32>>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | (0..13).collect::<Vec<i32>>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/issue-40396.rs:5:8
+ |
+LL | Vec<i32>::new();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | Vec::<i32>::new();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/issue-40396.rs:8:20
+ |
+LL | (0..13).collect<Vec<i32>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | (0..13).collect::<Vec<i32>();
+ | ++
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ --> $DIR/issue-40396.rs:11:43
+ |
+LL | let x = std::collections::HashMap<i128, i128>::new();
+ | ^ expected one of 8 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | let x = std::collections::HashMap::<i128, i128>::new();
+ | ++
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `,`
+ --> $DIR/issue-40396.rs:15:39
+ |
+LL | std::collections::HashMap<i128, i128>::new()
+ | ^ expected one of 8 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | std::collections::HashMap::<i128, i128>::new()
+ | ++
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `,`
+ --> $DIR/issue-40396.rs:20:39
+ |
+LL | std::collections::HashMap<i128, i128>::new();
+ | ^ expected one of 8 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | std::collections::HashMap::<i128, i128>::new();
+ | ++
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `,`
+ --> $DIR/issue-40396.rs:25:39
+ |
+LL | std::collections::HashMap<i128, i128>::new(1, 2);
+ | ^ expected one of 8 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | std::collections::HashMap::<i128, i128>::new(1, 2);
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-40396.rs:13:17
+ |
+LL | let x: () = 42;
+ | -- ^^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-40396.rs:18:17
+ |
+LL | let x: () = 42;
+ | -- ^^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-40396.rs:22:21
+ |
+LL | let x: () = 42;
+ | -- ^^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-40396.rs:27:21
+ |
+LL | let x: () = 32;
+ | -- ^^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-40823.rs b/src/test/ui/did_you_mean/issue-40823.rs
new file mode 100644
index 000000000..0f8c74554
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40823.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let mut buf = &[1, 2, 3, 4];
+ buf.iter_mut(); //~ ERROR cannot borrow `*buf` as mutable, as it is behind a `&` reference
+}
diff --git a/src/test/ui/did_you_mean/issue-40823.stderr b/src/test/ui/did_you_mean/issue-40823.stderr
new file mode 100644
index 000000000..67703a149
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40823.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `*buf` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-40823.rs:3:5
+ |
+LL | let mut buf = &[1, 2, 3, 4];
+ | ------------- help: consider changing this to be a mutable reference: `&mut [1, 2, 3, 4]`
+LL | buf.iter_mut();
+ | ^^^^^^^^^^^^^^ `buf` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed
new file mode 100644
index 000000000..87debfece
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+ let _x = !1; //~ ERROR cannot be used as a unary operator
+}
diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs
new file mode 100644
index 000000000..015a8edce
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+ let _x = ~1; //~ ERROR cannot be used as a unary operator
+}
diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr
new file mode 100644
index 000000000..84b81d561
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr
@@ -0,0 +1,8 @@
+error: `~` cannot be used as a unary operator
+ --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:4:14
+ |
+LL | let _x = ~1;
+ | ^ help: use `!` to perform bitwise not
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs b/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs
new file mode 100644
index 000000000..c377dfc12
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs
@@ -0,0 +1,37 @@
+mod submodule {
+
+ #[derive(Default)]
+ pub struct Demo {
+ pub favorite_integer: isize,
+ secret_integer: isize,
+ pub innocently_misspellable: (),
+ another_field: bool,
+ yet_another_field: bool,
+ always_more_fields: bool,
+ and_ever: bool,
+ }
+
+ impl Demo {
+ fn new_with_secret_two() -> Self {
+ Self { secret_integer: 2, inocently_mispellable: () }
+ //~^ ERROR no field
+ }
+
+ fn new_with_secret_three() -> Self {
+ Self { secret_integer: 3, egregiously_nonexistent_field: () }
+ //~^ ERROR no field
+ }
+ }
+
+}
+
+fn main() {
+ use submodule::Demo;
+
+ let demo = Demo::default();
+ let innocent_field_misaccess = demo.inocently_mispellable;
+ //~^ ERROR no field
+ // note shouldn't suggest private fields
+ let egregious_field_misaccess = demo.egregiously_nonexistent_field;
+ //~^ ERROR no field
+}
diff --git a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr
new file mode 100644
index 000000000..dbd9dc1bc
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr
@@ -0,0 +1,32 @@
+error[E0560]: struct `Demo` has no field named `inocently_mispellable`
+ --> $DIR/issue-42599_available_fields_note.rs:16:39
+ |
+LL | Self { secret_integer: 2, inocently_mispellable: () }
+ | ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`
+
+error[E0560]: struct `Demo` has no field named `egregiously_nonexistent_field`
+ --> $DIR/issue-42599_available_fields_note.rs:21:39
+ |
+LL | Self { secret_integer: 3, egregiously_nonexistent_field: () }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Demo` does not have this field
+ |
+ = note: available fields are: `favorite_integer`, `secret_integer`, `innocently_misspellable`, `another_field`, `yet_another_field` ... and 2 others
+
+error[E0609]: no field `inocently_mispellable` on type `Demo`
+ --> $DIR/issue-42599_available_fields_note.rs:32:41
+ |
+LL | let innocent_field_misaccess = demo.inocently_mispellable;
+ | ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`
+
+error[E0609]: no field `egregiously_nonexistent_field` on type `Demo`
+ --> $DIR/issue-42599_available_fields_note.rs:35:42
+ |
+LL | let egregious_field_misaccess = demo.egregiously_nonexistent_field;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field
+ |
+ = note: available fields are: `favorite_integer`, `innocently_misspellable`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0560, E0609.
+For more information about an error, try `rustc --explain E0560`.
diff --git a/src/test/ui/did_you_mean/issue-42764.rs b/src/test/ui/did_you_mean/issue-42764.rs
new file mode 100644
index 000000000..eb96c2480
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-42764.rs
@@ -0,0 +1,30 @@
+enum DoubleOption<T> {
+ FirstSome(T),
+ AlternativeSome(T),
+ Nothing,
+}
+
+fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {}
+
+fn main() {
+ let n: usize = 42;
+ this_function_expects_a_double_option(n);
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping the expression in a variant of `DoubleOption`
+}
+
+
+// But don't issue the "try using a variant" help if the one-"variant" ADT is
+// actually a one-field struct.
+
+struct Payload;
+
+struct Wrapper { payload: Payload }
+
+struct Context { wrapper: Wrapper }
+
+fn overton() {
+ let _c = Context { wrapper: Payload{} };
+ //~^ ERROR mismatched types
+ //~| try wrapping the expression in `Wrapper`
+}
diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr
new file mode 100644
index 000000000..6a7fd8fe2
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-42764.stderr
@@ -0,0 +1,36 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-42764.rs:11:43
+ |
+LL | this_function_expects_a_double_option(n);
+ | ------------------------------------- ^ expected enum `DoubleOption`, found `usize`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected enum `DoubleOption<_>`
+ found type `usize`
+note: function defined here
+ --> $DIR/issue-42764.rs:7:4
+ |
+LL | fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------
+help: try wrapping the expression in a variant of `DoubleOption`
+ |
+LL | this_function_expects_a_double_option(DoubleOption::FirstSome(n));
+ | ++++++++++++++++++++++++ +
+LL | this_function_expects_a_double_option(DoubleOption::AlternativeSome(n));
+ | ++++++++++++++++++++++++++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/issue-42764.rs:27:33
+ |
+LL | let _c = Context { wrapper: Payload{} };
+ | ^^^^^^^^^ expected struct `Wrapper`, found struct `Payload`
+ |
+help: try wrapping the expression in `Wrapper`
+ |
+LL | let _c = Context { wrapper: Wrapper { payload: Payload{} } };
+ | ++++++++++++++++++ +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs
new file mode 100644
index 000000000..9602d2746
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs
@@ -0,0 +1,36 @@
+enum Example { Ex(String), NotEx }
+
+enum Void {}
+
+enum ManyVariants {
+ One,
+ Two,
+ Three,
+ Four,
+ Five,
+ Six,
+ Seven,
+ Eight,
+ Nine,
+ Ten,
+}
+
+fn result_test() {
+ let x = Option(1); //~ ERROR expected function, tuple struct or tuple variant, found enum
+
+ if let Option(_) = x { //~ ERROR expected tuple struct or tuple variant, found enum
+ println!("It is OK.");
+ }
+
+ let y = Example::Ex(String::from("test"));
+
+ if let Example(_) = y { //~ ERROR expected tuple struct or tuple variant, found enum
+ println!("It is OK.");
+ }
+
+ let y = Void(); //~ ERROR expected function, tuple struct or tuple variant, found enum
+
+ let z = ManyVariants(); //~ ERROR expected function, tuple struct or tuple variant, found enum
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
new file mode 100644
index 000000000..bca493e67
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
@@ -0,0 +1,66 @@
+error[E0423]: expected function, tuple struct or tuple variant, found enum `Option`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:19:13
+ |
+LL | let x = Option(1);
+ | ^^^^^^ help: try to construct one of the enum's variants: `std::option::Option::Some`
+ |
+ = help: you might have meant to construct the enum's non-tuple variant
+
+error[E0532]: expected tuple struct or tuple variant, found enum `Option`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:21:12
+ |
+LL | if let Option(_) = x {
+ | ^^^^^^ help: try to match against one of the enum's variants: `std::option::Option::Some`
+ |
+ = help: you might have meant to match against the enum's non-tuple variant
+
+error[E0532]: expected tuple struct or tuple variant, found enum `Example`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:27:12
+ |
+LL | if let Example(_) = y {
+ | ^^^^^^^ help: try to match against one of the enum's variants: `Example::Ex`
+ |
+ = help: you might have meant to match against the enum's non-tuple variant
+note: the enum is defined here
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:1:1
+ |
+LL | enum Example { Ex(String), NotEx }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0423]: expected function, tuple struct or tuple variant, found enum `Void`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:31:13
+ |
+LL | let y = Void();
+ | ^^^^
+ |
+ = help: the enum has no tuple variants to construct
+note: the enum is defined here
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:3:1
+ |
+LL | enum Void {}
+ | ^^^^^^^^^^^^
+
+error[E0423]: expected function, tuple struct or tuple variant, found enum `ManyVariants`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:33:13
+ |
+LL | let z = ManyVariants();
+ | ^^^^^^^^^^^^
+ |
+ = help: the enum has no tuple variants to construct
+ = help: you might have meant to construct one of the enum's non-tuple variants
+note: the enum is defined here
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:5:1
+ |
+LL | / enum ManyVariants {
+LL | | One,
+LL | | Two,
+LL | | Three,
+... |
+LL | | Ten,
+LL | | }
+ | |_^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0423, E0532.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs b/src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs
new file mode 100644
index 000000000..63e8b2ba0
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs
@@ -0,0 +1,17 @@
+#![allow(unused)]
+
+struct PersonalityInventory {
+ expressivity: f32,
+ instrumentality: f32
+}
+
+impl PersonalityInventory {
+ fn expressivity(&self) -> f32 {
+ match *self {
+ PersonalityInventory { expressivity: exp, ... } => exp
+ //~^ ERROR expected field pattern, found `...`
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.stderr b/src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.stderr
new file mode 100644
index 000000000..bfe1ed328
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.stderr
@@ -0,0 +1,8 @@
+error: expected field pattern, found `...`
+ --> $DIR/issue-46718-struct-pattern-dotdotdot.rs:11:55
+ |
+LL | PersonalityInventory { expressivity: exp, ... } => exp
+ | ^^^ help: to omit remaining fields, use one fewer `.`: `..`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs
new file mode 100644
index 000000000..df697ccb6
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs
@@ -0,0 +1,34 @@
+fn gratitude() {
+ let for_you = false;
+ if not for_you {
+ //~^ ERROR unexpected `for_you` after identifier
+ println!("I couldn't");
+ }
+}
+
+fn qualification() {
+ let the_worst = true;
+ while not the_worst {
+ //~^ ERROR unexpected `the_worst` after identifier
+ println!("still pretty bad");
+ }
+}
+
+fn should_we() {
+ let not = true;
+ if not // lack of braces is [sic]
+ println!("Then when?");
+ //~^ ERROR expected `{`, found `;
+ //~| ERROR unexpected `println` after identifier
+}
+
+fn sleepy() {
+ let resource = not 2;
+ //~^ ERROR unexpected `2` after identifier
+}
+
+fn main() {
+ let be_smothered_out_before = true;
+ let young_souls = not be_smothered_out_before;
+ //~^ ERROR unexpected `be_smothered_out_before` after identifier
+}
diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
new file mode 100644
index 000000000..3ccc14bba
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
@@ -0,0 +1,56 @@
+error: unexpected `for_you` after identifier
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:3:12
+ |
+LL | if not for_you {
+ | ----^^^^^^^
+ | |
+ | help: use `!` to perform logical negation
+
+error: unexpected `the_worst` after identifier
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:11:15
+ |
+LL | while not the_worst {
+ | ----^^^^^^^^^
+ | |
+ | help: use `!` to perform logical negation
+
+error: unexpected `println` after identifier
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:9
+ |
+LL | if not // lack of braces is [sic]
+ | ----- help: use `!` to perform logical negation
+LL | println!("Then when?");
+ | ^^^^^^^
+
+error: expected `{`, found `;`
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:31
+ |
+LL | println!("Then when?");
+ | ^ expected `{`
+ |
+note: the `if` expression is missing a block after this condition
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:19:8
+ |
+LL | if not // lack of braces is [sic]
+ | ________^
+LL | | println!("Then when?");
+ | |______________________________^
+
+error: unexpected `2` after identifier
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:26:24
+ |
+LL | let resource = not 2;
+ | ----^
+ | |
+ | help: use `!` to perform logical negation
+
+error: unexpected `be_smothered_out_before` after identifier
+ --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:32:27
+ |
+LL | let young_souls = not be_smothered_out_before;
+ | ----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: use `!` to perform logical negation
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs
new file mode 100644
index 000000000..43b5f6d54
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs
@@ -0,0 +1,87 @@
+#![allow(unused)]
+
+#[derive(Copy, Clone)]
+enum Nucleotide {
+ Adenine,
+ Thymine,
+ Cytosine,
+ Guanine
+}
+
+#[derive(Clone)]
+struct Autosome;
+
+#[derive(Clone)]
+enum Allosome {
+ X(Vec<Nucleotide>),
+ Y(Vec<Nucleotide>)
+}
+
+impl Allosome {
+ fn is_x(&self) -> bool {
+ match *self {
+ Allosome::X(_) => true,
+ Allosome::Y(_) => false,
+ }
+ }
+}
+
+#[derive(Clone)]
+struct Genome {
+ autosomes: [Autosome; 22],
+ allosomes: (Allosome, Allosome)
+}
+
+fn find_start_codon(strand: &[Nucleotide]) -> Option<usize> {
+ let mut reading_frame = strand.windows(3);
+ // (missing parentheses in `while let` tuple pattern)
+ while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") {
+ //~^ ERROR unexpected `,` in pattern
+ // ...
+ }
+ None
+}
+
+fn find_thr(strand: &[Nucleotide]) -> Option<usize> {
+ let mut reading_frame = strand.windows(3);
+ let mut i = 0;
+ // (missing parentheses in `if let` tuple pattern)
+ if let b1, b2, b3 = reading_frame.next().unwrap() {
+ //~^ ERROR unexpected `,` in pattern
+ // ...
+ }
+ None
+}
+
+fn is_thr(codon: (Nucleotide, Nucleotide, Nucleotide)) -> bool {
+ match codon {
+ // (missing parentheses in match arm tuple pattern)
+ Nucleotide::Adenine, Nucleotide::Cytosine, _ => true
+ //~^ ERROR unexpected `,` in pattern
+ _ => false
+ }
+}
+
+fn analyze_female_sex_chromosomes(women: &[Genome]) {
+ // (missing parentheses in `for` tuple pattern)
+ for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) {
+ //~^ ERROR unexpected `,` in pattern
+ // ...
+ }
+}
+
+fn analyze_male_sex_chromosomes(men: &[Genome]) {
+ // (missing parentheses in pattern with `@` binding)
+ for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) {
+ //~^ ERROR unexpected `,` in pattern
+ // ...
+ }
+}
+
+fn main() {
+ let genomes = Vec::new();
+ // (missing parentheses in `let` pattern)
+ let women, men: (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned()
+ //~^ ERROR unexpected `,` in pattern
+ .partition(|g: &Genome| g.allosomes.0.is_x() && g.allosomes.1.is_x());
+}
diff --git a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr
new file mode 100644
index 000000000..a3c607b59
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr
@@ -0,0 +1,74 @@
+error: unexpected `,` in pattern
+ --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:38:17
+ |
+LL | while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") {
+ | ----- ^
+ | |
+ | while parsing the condition of this `while` expression
+ |
+help: try adding parentheses to match on a tuple
+ |
+LL | while let (b1, b2, b3) = reading_frame.next().expect("there should be a start codon") {
+ | + +
+
+error: unexpected `,` in pattern
+ --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:49:14
+ |
+LL | if let b1, b2, b3 = reading_frame.next().unwrap() {
+ | ^
+ |
+help: try adding parentheses to match on a tuple
+ |
+LL | if let (b1, b2, b3) = reading_frame.next().unwrap() {
+ | + +
+
+error: unexpected `,` in pattern
+ --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:59:28
+ |
+LL | Nucleotide::Adenine, Nucleotide::Cytosine, _ => true
+ | ^
+ |
+help: try adding parentheses to match on a tuple...
+ |
+LL | (Nucleotide::Adenine, Nucleotide::Cytosine, _) => true
+ | + +
+help: ...or a vertical bar to match on multiple alternatives
+ |
+LL | Nucleotide::Adenine | Nucleotide::Cytosine | _ => true
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: unexpected `,` in pattern
+ --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:67:10
+ |
+LL | for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) {
+ | ^
+ |
+help: try adding parentheses to match on a tuple
+ |
+LL | for (x, _barr_body) in women.iter().map(|woman| woman.allosomes.clone()) {
+ | + +
+
+error: unexpected `,` in pattern
+ --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:75:10
+ |
+LL | for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) {
+ | ^
+ |
+help: try adding parentheses to match on a tuple
+ |
+LL | for (x, y @ Allosome::Y(_)) in men.iter().map(|man| man.allosomes.clone()) {
+ | + +
+
+error: unexpected `,` in pattern
+ --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:84:14
+ |
+LL | let women, men: (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned()
+ | ^
+ |
+help: try adding parentheses to match on a tuple
+ |
+LL | let (women, men): (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned()
+ | + +
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs
new file mode 100644
index 000000000..66d562d2e
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs
@@ -0,0 +1,6 @@
+const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
+//~^ ERROR expected at least one digit in exponent
+//~| ERROR unknown start of token: \u{2212}
+//~| ERROR cannot subtract `{integer}` from `{float}`
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
new file mode 100644
index 000000000..26986684f
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
@@ -0,0 +1,38 @@
+error: expected at least one digit in exponent
+ --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:47
+ |
+LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
+ | ^^^^^^
+
+error: unknown start of token: \u{2212}
+ --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
+ |
+LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
+ | ^
+ |
+help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it is not
+ |
+LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻²
+ | ~
+
+error[E0277]: cannot subtract `{integer}` from `{float}`
+ --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
+ |
+LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
+ | ^ no implementation for `{float} - {integer}`
+ |
+ = help: the trait `Sub<{integer}>` is not implemented for `{float}`
+ = help: the following other types implement trait `Sub<Rhs>`:
+ <&'a f32 as Sub<f32>>
+ <&'a f64 as Sub<f64>>
+ <&'a i128 as Sub<i128>>
+ <&'a i16 as Sub<i16>>
+ <&'a i32 as Sub<i32>>
+ <&'a i64 as Sub<i64>>
+ <&'a i8 as Sub<i8>>
+ <&'a isize as Sub<isize>>
+ and 48 others
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs b/src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs
new file mode 100644
index 000000000..73f1856ca
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs
@@ -0,0 +1,19 @@
+fn main() {
+ let sixteen: f32 = 16;
+ //~^ ERROR mismatched types
+ //~| HELP use a float literal
+ let a_million_and_seventy: f64 = 1_000_070;
+ //~^ ERROR mismatched types
+ //~| HELP use a float literal
+ let negative_nine: f32 = -9;
+ //~^ ERROR mismatched types
+ //~| HELP use a float literal
+
+
+ // only base-10 literals get the suggestion
+
+ let sixteen_again: f64 = 0x10;
+ //~^ ERROR mismatched types
+ let and_once_more: f32 = 0o20;
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr b/src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr
new file mode 100644
index 000000000..6f853ccab
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr
@@ -0,0 +1,49 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-53280-expected-float-found-integer-literal.rs:2:24
+ |
+LL | let sixteen: f32 = 16;
+ | --- ^^
+ | | |
+ | | expected `f32`, found integer
+ | | help: use a float literal: `16.0`
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-53280-expected-float-found-integer-literal.rs:5:38
+ |
+LL | let a_million_and_seventy: f64 = 1_000_070;
+ | --- ^^^^^^^^^
+ | | |
+ | | expected `f64`, found integer
+ | | help: use a float literal: `1_000_070.0`
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-53280-expected-float-found-integer-literal.rs:8:30
+ |
+LL | let negative_nine: f32 = -9;
+ | --- ^^
+ | | |
+ | | expected `f32`, found integer
+ | | help: use a float literal: `-9.0`
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-53280-expected-float-found-integer-literal.rs:15:30
+ |
+LL | let sixteen_again: f64 = 0x10;
+ | --- ^^^^ expected `f64`, found integer
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/issue-53280-expected-float-found-integer-literal.rs:17:30
+ |
+LL | let and_once_more: f32 = 0o20;
+ | --- ^^^^ expected `f32`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs
new file mode 100644
index 000000000..44421b077
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs
@@ -0,0 +1,57 @@
+fn main() {}
+
+fn test_and() {
+ let a = true;
+ let b = false;
+
+ let _ = a and b; //~ ERROR `and` is not a logical operator
+
+ if a and b { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
+
+fn test_or() {
+ let a = true;
+ let b = false;
+
+ let _ = a or b; //~ ERROR `or` is not a logical operator
+
+ if a or b { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_and_par() {
+ let a = true;
+ let b = false;
+ if (a and b) { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_or_par() {
+ let a = true;
+ let b = false;
+ if (a or b) { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_while_and() {
+ let a = true;
+ let b = false;
+ while a and b { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_while_or() {
+ let a = true;
+ let b = false;
+ while a or b { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
new file mode 100644
index 000000000..528c62f50
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
@@ -0,0 +1,75 @@
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15
+ |
+LL | let _ = a and b;
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10
+ |
+LL | if a and b {
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15
+ |
+LL | let _ = a or b;
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10
+ |
+LL | if a or b {
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11
+ |
+LL | if (a and b) {
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11
+ |
+LL | if (a or b) {
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13
+ |
+LL | while a and b {
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13
+ |
+LL | while a or b {
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error[E0308]: mismatched types
+ --> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.fixed b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
new file mode 100644
index 000000000..5079a37f4
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
@@ -0,0 +1,61 @@
+// run-rustfix
+
+// This test is to check if suggestions can be applied automatically.
+
+#![allow(dead_code, unused_parens)]
+
+fn main() {}
+
+fn test_and() {
+ let a = true;
+ let b = false;
+
+ let _ = a && b; //~ ERROR `and` is not a logical operator
+
+ if a && b { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_or() {
+ let a = true;
+ let b = false;
+
+ let _ = a || b; //~ ERROR `or` is not a logical operator
+
+ if a || b { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_and_par() {
+ let a = true;
+ let b = false;
+ if (a && b) { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_or_par() {
+ let a = true;
+ let b = false;
+ if (a || b) { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_while_and() {
+ let a = true;
+ let b = false;
+ while a && b { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_while_or() {
+ let a = true;
+ let b = false;
+ while a || b { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.rs b/src/test/ui/did_you_mean/issue-54109-without-witness.rs
new file mode 100644
index 000000000..00660a938
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.rs
@@ -0,0 +1,61 @@
+// run-rustfix
+
+// This test is to check if suggestions can be applied automatically.
+
+#![allow(dead_code, unused_parens)]
+
+fn main() {}
+
+fn test_and() {
+ let a = true;
+ let b = false;
+
+ let _ = a and b; //~ ERROR `and` is not a logical operator
+
+ if a and b { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_or() {
+ let a = true;
+ let b = false;
+
+ let _ = a or b; //~ ERROR `or` is not a logical operator
+
+ if a or b { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_and_par() {
+ let a = true;
+ let b = false;
+ if (a and b) { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_or_par() {
+ let a = true;
+ let b = false;
+ if (a or b) { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_while_and() {
+ let a = true;
+ let b = false;
+ while a and b { //~ ERROR `and` is not a logical operator
+ println!("both");
+ }
+}
+
+fn test_while_or() {
+ let a = true;
+ let b = false;
+ while a or b { //~ ERROR `or` is not a logical operator
+ println!("both");
+ }
+}
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
new file mode 100644
index 000000000..0350890c1
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
@@ -0,0 +1,66 @@
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:13:15
+ |
+LL | let _ = a and b;
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:15:10
+ |
+LL | if a and b {
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:24:15
+ |
+LL | let _ = a or b;
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:26:10
+ |
+LL | if a or b {
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:34:11
+ |
+LL | if (a and b) {
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:42:11
+ |
+LL | if (a or b) {
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:50:13
+ |
+LL | while a and b {
+ | ^^^ help: use `&&` to perform logical conjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+ --> $DIR/issue-54109-without-witness.rs:58:13
+ |
+LL | while a or b {
+ | ^^ help: use `||` to perform logical disjunction
+ |
+ = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs
new file mode 100644
index 000000000..264cfa449
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs
@@ -0,0 +1,15 @@
+enum PutDown { Set }
+enum AffixHeart { Set }
+enum CauseToBe { Set }
+enum Determine { Set }
+enum TableDishesAction { Set }
+enum Solidify { Set }
+enum UnorderedCollection { Set }
+
+fn setup() -> Set { Set }
+//~^ ERROR cannot find type `Set` in this scope
+//~| ERROR cannot find value `Set` in this scope
+
+fn main() {
+ setup();
+}
diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
new file mode 100644
index 000000000..abc040c05
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
@@ -0,0 +1,40 @@
+error[E0412]: cannot find type `Set` in this scope
+ --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:15
+ |
+LL | fn setup() -> Set { Set }
+ | ^^^ not found in this scope
+ |
+help: there is an enum variant `AffixHeart::Set` and 7 others; try using the variant's enum
+ |
+LL | fn setup() -> AffixHeart { Set }
+ | ~~~~~~~~~~
+LL | fn setup() -> CauseToBe { Set }
+ | ~~~~~~~~~
+LL | fn setup() -> Determine { Set }
+ | ~~~~~~~~~
+LL | fn setup() -> PutDown { Set }
+ | ~~~~~~~
+ and 3 other candidates
+
+error[E0425]: cannot find value `Set` in this scope
+ --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21
+ |
+LL | fn setup() -> Set { Set }
+ | ^^^ not found in this scope
+ |
+help: consider importing one of these items
+ |
+LL | use AffixHeart::Set;
+ |
+LL | use CauseToBe::Set;
+ |
+LL | use Determine::Set;
+ |
+LL | use PutDown::Set;
+ |
+ and 3 other candidates
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs b/src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs
new file mode 100644
index 000000000..070ffaa1e
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs
@@ -0,0 +1,18 @@
+fn main() {}
+
+const FOO: [u8; 3] = {
+ //~^ ERROR this is a block expression, not an array
+ 1, 2, 3
+};
+
+const BAR: [&str; 3] = {"one", "two", "three"};
+//~^ ERROR this is a block expression, not an array
+
+fn foo() {
+ {1, 2, 3};
+ //~^ ERROR this is a block expression, not an array
+}
+
+fn bar() {
+ 1, 2, 3 //~ ERROR expected one of
+}
diff --git a/src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.stderr b/src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.stderr
new file mode 100644
index 000000000..d5ad1a72b
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-87830-try-brackets-for-arrays.stderr
@@ -0,0 +1,48 @@
+error: this is a block expression, not an array
+ --> $DIR/issue-87830-try-brackets-for-arrays.rs:3:22
+ |
+LL | const FOO: [u8; 3] = {
+ | ______________________^
+LL | |
+LL | | 1, 2, 3
+LL | | };
+ | |_^
+ |
+help: to make an array, use square brackets instead of curly braces
+ |
+LL ~ const FOO: [u8; 3] = [
+LL |
+LL | 1, 2, 3
+LL ~ ];
+ |
+
+error: this is a block expression, not an array
+ --> $DIR/issue-87830-try-brackets-for-arrays.rs:8:24
+ |
+LL | const BAR: [&str; 3] = {"one", "two", "three"};
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to make an array, use square brackets instead of curly braces
+ |
+LL | const BAR: [&str; 3] = ["one", "two", "three"];
+ | ~ ~
+
+error: this is a block expression, not an array
+ --> $DIR/issue-87830-try-brackets-for-arrays.rs:12:5
+ |
+LL | {1, 2, 3};
+ | ^^^^^^^^^
+ |
+help: to make an array, use square brackets instead of curly braces
+ |
+LL | [1, 2, 3];
+ | ~ ~
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+ --> $DIR/issue-87830-try-brackets-for-arrays.rs:17:6
+ |
+LL | 1, 2, 3
+ | ^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs b/src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs
new file mode 100644
index 000000000..0efc7daa3
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs
@@ -0,0 +1,24 @@
+#[derive(Default)]
+pub struct A {
+ #[doc(hidden)]
+ pub hello: i32,
+ pub bye: i32,
+}
+
+#[derive(Default)]
+pub struct B {
+ pub hello: i32,
+ pub bye: i32,
+}
+
+fn main() {
+ A::default().hey;
+ //~^ ERROR no field `hey` on type `A`
+ //~| NOTE unknown field
+ //~| NOTE available fields are: `bye`
+
+ B::default().hey;
+ //~^ ERROR no field `hey` on type `B`
+ //~| NOTE unknown field
+ //~| NOTE available fields are: `hello`, `bye`
+}
diff --git a/src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr b/src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr
new file mode 100644
index 000000000..784986d3b
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr
@@ -0,0 +1,19 @@
+error[E0609]: no field `hey` on type `A`
+ --> $DIR/issue-93210-ignore-doc-hidden.rs:15:18
+ |
+LL | A::default().hey;
+ | ^^^ unknown field
+ |
+ = note: available fields are: `bye`
+
+error[E0609]: no field `hey` on type `B`
+ --> $DIR/issue-93210-ignore-doc-hidden.rs:20:18
+ |
+LL | B::default().hey;
+ | ^^^ unknown field
+ |
+ = note: available fields are: `hello`, `bye`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/did_you_mean/pub-macro-rules.rs b/src/test/ui/did_you_mean/pub-macro-rules.rs
new file mode 100644
index 000000000..c5393703f
--- /dev/null
+++ b/src/test/ui/did_you_mean/pub-macro-rules.rs
@@ -0,0 +1,16 @@
+#[macro_use] mod bleh {
+ pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation
+ ($n:ident) => (
+ fn $n () -> i32 {
+ 1
+ }
+ )
+ }
+
+}
+
+foo!(meh);
+
+fn main() {
+ println!("{}", meh());
+}
diff --git a/src/test/ui/did_you_mean/pub-macro-rules.stderr b/src/test/ui/did_you_mean/pub-macro-rules.stderr
new file mode 100644
index 000000000..0bde5783b
--- /dev/null
+++ b/src/test/ui/did_you_mean/pub-macro-rules.stderr
@@ -0,0 +1,8 @@
+error: can't qualify macro_rules invocation with `pub`
+ --> $DIR/pub-macro-rules.rs:2:5
+ |
+LL | pub macro_rules! foo {
+ | ^^^ help: try exporting the macro: `#[macro_export]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/did_you_mean/recursion_limit.rs b/src/test/ui/did_you_mean/recursion_limit.rs
new file mode 100644
index 000000000..38db12960
--- /dev/null
+++ b/src/test/ui/did_you_mean/recursion_limit.rs
@@ -0,0 +1,35 @@
+// Test that the recursion limit can be changed and that the compiler
+// suggests a fix. In this case, we have deeply nested types that will
+// fail the `Send` check by overflow when the recursion limit is set
+// very low.
+
+#![allow(dead_code)]
+#![recursion_limit="10"]
+
+macro_rules! link {
+ ($id:ident, $t:ty) => {
+ enum $id { $id($t) }
+ }
+}
+
+link! { A, B }
+link! { B, C }
+link! { C, D }
+link! { D, E }
+link! { E, F }
+link! { F, G }
+link! { G, H }
+link! { H, I }
+link! { I, J }
+link! { J, K }
+link! { K, L }
+link! { L, M }
+link! { M, N }
+
+enum N { N(usize) }
+
+fn is_send<T:Send>() { }
+
+fn main() {
+ is_send::<A>(); //~ ERROR overflow evaluating the requirement
+}
diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr
new file mode 100644
index 000000000..247fe4b5b
--- /dev/null
+++ b/src/test/ui/did_you_mean/recursion_limit.stderr
@@ -0,0 +1,66 @@
+error[E0275]: overflow evaluating the requirement `K: Send`
+ --> $DIR/recursion_limit.rs:34:5
+ |
+LL | is_send::<A>();
+ | ^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`recursion_limit`)
+note: required because it appears within the type `J`
+ --> $DIR/recursion_limit.rs:24:9
+ |
+LL | link! { J, K }
+ | ^
+note: required because it appears within the type `I`
+ --> $DIR/recursion_limit.rs:23:9
+ |
+LL | link! { I, J }
+ | ^
+note: required because it appears within the type `H`
+ --> $DIR/recursion_limit.rs:22:9
+ |
+LL | link! { H, I }
+ | ^
+note: required because it appears within the type `G`
+ --> $DIR/recursion_limit.rs:21:9
+ |
+LL | link! { G, H }
+ | ^
+note: required because it appears within the type `F`
+ --> $DIR/recursion_limit.rs:20:9
+ |
+LL | link! { F, G }
+ | ^
+note: required because it appears within the type `E`
+ --> $DIR/recursion_limit.rs:19:9
+ |
+LL | link! { E, F }
+ | ^
+note: required because it appears within the type `D`
+ --> $DIR/recursion_limit.rs:18:9
+ |
+LL | link! { D, E }
+ | ^
+note: required because it appears within the type `C`
+ --> $DIR/recursion_limit.rs:17:9
+ |
+LL | link! { C, D }
+ | ^
+note: required because it appears within the type `B`
+ --> $DIR/recursion_limit.rs:16:9
+ |
+LL | link! { B, C }
+ | ^
+note: required because it appears within the type `A`
+ --> $DIR/recursion_limit.rs:15:9
+ |
+LL | link! { A, B }
+ | ^
+note: required by a bound in `is_send`
+ --> $DIR/recursion_limit.rs:31:14
+ |
+LL | fn is_send<T:Send>() { }
+ | ^^^^ required by this bound in `is_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.rs b/src/test/ui/did_you_mean/recursion_limit_deref.rs
new file mode 100644
index 000000000..41bbca661
--- /dev/null
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.rs
@@ -0,0 +1,53 @@
+// Test that the recursion limit can be changed and that the compiler
+// suggests a fix. In this case, we have a long chain of Deref impls
+// which will cause an overflow during the autoderef loop.
+// compile-flags: -Zdeduplicate-diagnostics=yes
+
+#![allow(dead_code)]
+#![recursion_limit="10"]
+
+macro_rules! link {
+ ($outer:ident, $inner:ident) => {
+ struct $outer($inner);
+
+ impl $outer {
+ fn new() -> $outer {
+ $outer($inner::new())
+ }
+ }
+
+ impl std::ops::Deref for $outer {
+ type Target = $inner;
+
+ fn deref(&self) -> &$inner {
+ &self.0
+ }
+ }
+ }
+}
+
+struct Bottom;
+impl Bottom {
+ fn new() -> Bottom {
+ Bottom
+ }
+}
+
+link!(Top, A);
+link!(A, B);
+link!(B, C);
+link!(C, D);
+link!(D, E);
+link!(E, F);
+link!(F, G);
+link!(G, H);
+link!(H, I);
+link!(I, J);
+link!(J, K);
+link!(K, Bottom);
+
+fn main() {
+ let t = Top::new();
+ let x: &Bottom = &t; //~ ERROR mismatched types
+ //~^ error recursion limit
+}
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
new file mode 100644
index 000000000..a6b5681a6
--- /dev/null
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -0,0 +1,23 @@
+error[E0055]: reached the recursion limit while auto-dereferencing `J`
+ --> $DIR/recursion_limit_deref.rs:51:22
+ |
+LL | let x: &Bottom = &t;
+ | ^^ deref recursion limit reached
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`recursion_limit_deref`)
+
+error[E0308]: mismatched types
+ --> $DIR/recursion_limit_deref.rs:51:22
+ |
+LL | let x: &Bottom = &t;
+ | ------- ^^ expected struct `Bottom`, found struct `Top`
+ | |
+ | expected due to this
+ |
+ = note: expected reference `&Bottom`
+ found reference `&Top`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0055, E0308.
+For more information about an error, try `rustc --explain E0055`.
diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.rs b/src/test/ui/did_you_mean/recursion_limit_macro.rs
new file mode 100644
index 000000000..a68a5ece7
--- /dev/null
+++ b/src/test/ui/did_you_mean/recursion_limit_macro.rs
@@ -0,0 +1,15 @@
+// Test that the recursion limit can be changed and that the compiler
+// suggests a fix. In this case, we have a recursing macro that will
+// overflow if the number of arguments surpasses the recursion limit.
+
+#![allow(dead_code)]
+#![recursion_limit="10"]
+
+macro_rules! recurse {
+ () => { };
+ ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; //~ ERROR recursion limit
+}
+
+fn main() {
+ recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9);
+}
diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr
new file mode 100644
index 000000000..71855cf1e
--- /dev/null
+++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr
@@ -0,0 +1,14 @@
+error: recursion limit reached while expanding `recurse!`
+ --> $DIR/recursion_limit_macro.rs:10:31
+ |
+LL | ($t:tt $($tail:tt)*) => { recurse!($($tail)*) };
+ | ^^^^^^^^^^^^^^^^^^^
+...
+LL | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9);
+ | ------------------------------------------------- in this macro invocation
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`recursion_limit_macro`)
+ = note: this error originates in the macro `recurse` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed
new file mode 100644
index 000000000..4963790c3
--- /dev/null
+++ b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused)]
+
+trait Foo<T>: Sized {
+ fn bar(i: i32, t: T, s: &Self) -> (T, i32);
+}
+
+impl Foo<usize> for () {
+ fn bar(i: i32, t: usize, s: &()) -> (usize, i32) {
+ //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+ (1, 2)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs
new file mode 100644
index 000000000..ddf39c9c8
--- /dev/null
+++ b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused)]
+
+trait Foo<T>: Sized {
+ fn bar(i: i32, t: T, s: &Self) -> (T, i32);
+}
+
+impl Foo<usize> for () {
+ fn bar(i: _, t: _, s: _) -> _ {
+ //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+ (1, 2)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr
new file mode 100644
index 000000000..730836a40
--- /dev/null
+++ b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr
@@ -0,0 +1,18 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+ --> $DIR/replace-impl-infer-ty-from-trait.rs:9:15
+ |
+LL | fn bar(i: _, t: _, s: _) -> _ {
+ | ^ ^ ^ ^ not allowed in type signatures
+ | | | |
+ | | | not allowed in type signatures
+ | | not allowed in type signatures
+ | not allowed in type signatures
+ |
+help: try replacing `_` with the types in the corresponding trait method signature
+ |
+LL | fn bar(i: i32, t: usize, s: &()) -> (usize, i32) {
+ | ~~~ ~~~~~ ~~~ ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs
new file mode 100644
index 000000000..c9a097d36
--- /dev/null
+++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs
@@ -0,0 +1,7 @@
+#![allow(bare_trait_objects)]
+
+fn main() {
+ let _: &Copy + 'static; //~ ERROR expected a path
+ //~^ ERROR cannot be made into an object
+ let _: &'static Copy + 'static; //~ ERROR expected a path
+}
diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
new file mode 100644
index 000000000..68734cd4c
--- /dev/null
+++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
@@ -0,0 +1,25 @@
+error[E0178]: expected a path on the left-hand side of `+`, not `&Copy`
+ --> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
+ |
+LL | let _: &Copy + 'static;
+ | ^^^^^^^^^^^^^^^ help: try adding parentheses: `&(Copy + 'static)`
+
+error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy`
+ --> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12
+ |
+LL | let _: &'static Copy + 'static;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'static (Copy + 'static)`
+
+error[E0038]: the trait `Copy` cannot be made into an object
+ --> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
+ |
+LL | let _: &Copy + 'static;
+ | ^^^^^ `Copy` cannot be made into an object
+ |
+ = note: the trait cannot be made into an object because it requires `Self: Sized`
+ = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0178.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/src/test/ui/did_you_mean/use_instead_of_import.fixed b/src/test/ui/did_you_mean/use_instead_of_import.fixed
new file mode 100644
index 000000000..87d453e15
--- /dev/null
+++ b/src/test/ui/did_you_mean/use_instead_of_import.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+use std::{
+ //~^ ERROR expected item, found `import`
+ io::Write,
+ rc::Rc,
+};
+
+pub use std::io;
+//~^ ERROR expected item, found `using`
+
+fn main() {
+ let x = Rc::new(1);
+ let _ = write!(io::stdout(), "{:?}", x);
+}
diff --git a/src/test/ui/did_you_mean/use_instead_of_import.rs b/src/test/ui/did_you_mean/use_instead_of_import.rs
new file mode 100644
index 000000000..59e837323
--- /dev/null
+++ b/src/test/ui/did_you_mean/use_instead_of_import.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+
+import std::{
+ //~^ ERROR expected item, found `import`
+ io::Write,
+ rc::Rc,
+};
+
+pub using std::io;
+//~^ ERROR expected item, found `using`
+
+fn main() {
+ let x = Rc::new(1);
+ let _ = write!(io::stdout(), "{:?}", x);
+}
diff --git a/src/test/ui/did_you_mean/use_instead_of_import.stderr b/src/test/ui/did_you_mean/use_instead_of_import.stderr
new file mode 100644
index 000000000..b22954af8
--- /dev/null
+++ b/src/test/ui/did_you_mean/use_instead_of_import.stderr
@@ -0,0 +1,14 @@
+error: expected item, found `import`
+ --> $DIR/use_instead_of_import.rs:3:1
+ |
+LL | import std::{
+ | ^^^^^^ help: items are imported using the `use` keyword
+
+error: expected item, found `using`
+ --> $DIR/use_instead_of_import.rs:9:5
+ |
+LL | pub using std::io;
+ | ^^^^^ help: items are imported using the `use` keyword
+
+error: aborting due to 2 previous errors
+