summaryrefslogtreecommitdiffstats
path: root/tests/ui/mismatched_types
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
commita4b7ed7a42c716ab9f05e351f003d589124fd55d (patch)
treeb620cd3f223850b28716e474e80c58059dca5dd4 /tests/ui/mismatched_types
parentAdding upstream version 1.67.1+dfsg1. (diff)
downloadrustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.tar.xz
rustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.zip
Adding upstream version 1.68.2+dfsg1.upstream/1.68.2+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/mismatched_types')
-rw-r--r--tests/ui/mismatched_types/E0053.rs16
-rw-r--r--tests/ui/mismatched_types/E0053.stderr37
-rw-r--r--tests/ui/mismatched_types/E0409.rs9
-rw-r--r--tests/ui/mismatched_types/E0409.stderr28
-rw-r--r--tests/ui/mismatched_types/E0631.rs11
-rw-r--r--tests/ui/mismatched_types/E0631.stderr73
-rw-r--r--tests/ui/mismatched_types/abridged.rs62
-rw-r--r--tests/ui/mismatched_types/abridged.stderr105
-rw-r--r--tests/ui/mismatched_types/assignment-operator-unimplemented.rs7
-rw-r--r--tests/ui/mismatched_types/assignment-operator-unimplemented.stderr19
-rw-r--r--tests/ui/mismatched_types/binops.rs8
-rw-r--r--tests/ui/mismatched_types/binops.stderr106
-rw-r--r--tests/ui/mismatched_types/cast-rfc0401.rs72
-rw-r--r--tests/ui/mismatched_types/cast-rfc0401.stderr256
-rw-r--r--tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.fixed20
-rw-r--r--tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs20
-rw-r--r--tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr16
-rw-r--r--tests/ui/mismatched_types/closure-arg-count.rs43
-rw-r--r--tests/ui/mismatched_types/closure-arg-count.stderr189
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed5
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs5
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr38
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch.rs11
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch.stderr46
-rw-r--r--tests/ui/mismatched_types/closure-mismatch.rs11
-rw-r--r--tests/ui/mismatched_types/closure-mismatch.stderr31
-rw-r--r--tests/ui/mismatched_types/const-fn-in-trait.rs11
-rw-r--r--tests/ui/mismatched_types/const-fn-in-trait.stderr15
-rw-r--r--tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs23
-rw-r--r--tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr26
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.rs18
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.stderr19
-rw-r--r--tests/ui/mismatched_types/float-literal-inference-restrictions.rs4
-rw-r--r--tests/ui/mismatched_types/float-literal-inference-restrictions.stderr26
-rw-r--r--tests/ui/mismatched_types/fn-variance-1.rs17
-rw-r--r--tests/ui/mismatched_types/fn-variance-1.stderr41
-rw-r--r--tests/ui/mismatched_types/for-loop-has-unit-body.rs5
-rw-r--r--tests/ui/mismatched_types/for-loop-has-unit-body.stderr9
-rw-r--r--tests/ui/mismatched_types/issue-106182.fixed14
-rw-r--r--tests/ui/mismatched_types/issue-106182.rs14
-rw-r--r--tests/ui/mismatched_types/issue-106182.stderr18
-rw-r--r--tests/ui/mismatched_types/issue-19109.rs8
-rw-r--r--tests/ui/mismatched_types/issue-19109.stderr14
-rw-r--r--tests/ui/mismatched_types/issue-26480.rs29
-rw-r--r--tests/ui/mismatched_types/issue-26480.stderr37
-rw-r--r--tests/ui/mismatched_types/issue-35030.rs15
-rw-r--r--tests/ui/mismatched_types/issue-35030.stderr26
-rw-r--r--tests/ui/mismatched_types/issue-36053-2.rs10
-rw-r--r--tests/ui/mismatched_types/issue-36053-2.stderr41
-rw-r--r--tests/ui/mismatched_types/issue-38371-unfixable.rs5
-rw-r--r--tests/ui/mismatched_types/issue-38371-unfixable.stderr21
-rw-r--r--tests/ui/mismatched_types/issue-38371.fixed18
-rw-r--r--tests/ui/mismatched_types/issue-38371.rs18
-rw-r--r--tests/ui/mismatched_types/issue-38371.stderr35
-rw-r--r--tests/ui/mismatched_types/issue-47706-trait.rs8
-rw-r--r--tests/ui/mismatched_types/issue-47706-trait.stderr16
-rw-r--r--tests/ui/mismatched_types/issue-47706.rs29
-rw-r--r--tests/ui/mismatched_types/issue-47706.stderr37
-rw-r--r--tests/ui/mismatched_types/issue-74918-missing-lifetime.rs29
-rw-r--r--tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr28
-rw-r--r--tests/ui/mismatched_types/issue-75361-mismatched-impl.rs24
-rw-r--r--tests/ui/mismatched_types/issue-75361-mismatched-impl.stderr19
-rw-r--r--tests/ui/mismatched_types/issue-84976.rs25
-rw-r--r--tests/ui/mismatched_types/issue-84976.stderr38
-rw-r--r--tests/ui/mismatched_types/main.rs4
-rw-r--r--tests/ui/mismatched_types/main.stderr13
-rw-r--r--tests/ui/mismatched_types/method-help-unsatisfied-bound.rs7
-rw-r--r--tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr18
-rw-r--r--tests/ui/mismatched_types/non_zero_assigned_something.rs9
-rw-r--r--tests/ui/mismatched_types/non_zero_assigned_something.stderr31
-rw-r--r--tests/ui/mismatched_types/normalize-fn-sig.rs16
-rw-r--r--tests/ui/mismatched_types/normalize-fn-sig.stderr19
-rw-r--r--tests/ui/mismatched_types/numeric-literal-cast.rs12
-rw-r--r--tests/ui/mismatched_types/numeric-literal-cast.stderr57
-rw-r--r--tests/ui/mismatched_types/overloaded-calls-bad.rs42
-rw-r--r--tests/ui/mismatched_types/overloaded-calls-bad.stderr66
-rw-r--r--tests/ui/mismatched_types/recovered-block.rs21
-rw-r--r--tests/ui/mismatched_types/recovered-block.stderr19
-rw-r--r--tests/ui/mismatched_types/ref-pat-suggestions.fixed37
-rw-r--r--tests/ui/mismatched_types/ref-pat-suggestions.rs37
-rw-r--r--tests/ui/mismatched_types/ref-pat-suggestions.stderr386
-rw-r--r--tests/ui/mismatched_types/show_module.rs18
-rw-r--r--tests/ui/mismatched_types/show_module.stderr23
-rw-r--r--tests/ui/mismatched_types/similar_paths.rs11
-rw-r--r--tests/ui/mismatched_types/similar_paths.stderr20
-rw-r--r--tests/ui/mismatched_types/similar_paths_primitive.rs10
-rw-r--r--tests/ui/mismatched_types/similar_paths_primitive.stderr24
-rw-r--r--tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed21
-rw-r--r--tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs21
-rw-r--r--tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr49
-rw-r--r--tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed28
-rw-r--r--tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs28
-rw-r--r--tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr47
-rw-r--r--tests/ui/mismatched_types/suggest-removing-tuple-struct-field.fixed17
-rw-r--r--tests/ui/mismatched_types/suggest-removing-tuple-struct-field.rs17
-rw-r--r--tests/ui/mismatched_types/suggest-removing-tuple-struct-field.stderr41
-rw-r--r--tests/ui/mismatched_types/trait-bounds-cant-coerce.rs16
-rw-r--r--tests/ui/mismatched_types/trait-bounds-cant-coerce.stderr19
-rw-r--r--tests/ui/mismatched_types/trait-impl-fn-incompatibility.rs14
-rw-r--r--tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr37
-rw-r--r--tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs22
-rw-r--r--tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr22
-rw-r--r--tests/ui/mismatched_types/wrap-suggestion-privacy.rs24
-rw-r--r--tests/ui/mismatched_types/wrap-suggestion-privacy.stderr59
104 files changed, 3416 insertions, 0 deletions
diff --git a/tests/ui/mismatched_types/E0053.rs b/tests/ui/mismatched_types/E0053.rs
new file mode 100644
index 000000000..d3146ce54
--- /dev/null
+++ b/tests/ui/mismatched_types/E0053.rs
@@ -0,0 +1,16 @@
+trait Foo {
+ fn foo(x: u16);
+ fn bar(&self);
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ fn foo(x: i16) { }
+ //~^ ERROR method `foo` has an incompatible type for trait
+ fn bar(&mut self) { }
+ //~^ ERROR method `bar` has an incompatible type for trait
+}
+
+fn main() {
+}
diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr
new file mode 100644
index 000000000..154f2fcbe
--- /dev/null
+++ b/tests/ui/mismatched_types/E0053.stderr
@@ -0,0 +1,37 @@
+error[E0053]: method `foo` has an incompatible type for trait
+ --> $DIR/E0053.rs:9:15
+ |
+LL | fn foo(x: i16) { }
+ | ^^^
+ | |
+ | expected `u16`, found `i16`
+ | help: change the parameter type to match the trait: `u16`
+ |
+note: type in trait
+ --> $DIR/E0053.rs:2:15
+ |
+LL | fn foo(x: u16);
+ | ^^^
+ = note: expected signature `fn(u16)`
+ found signature `fn(i16)`
+
+error[E0053]: method `bar` has an incompatible type for trait
+ --> $DIR/E0053.rs:11:12
+ |
+LL | fn bar(&mut self) { }
+ | ^^^^^^^^^
+ | |
+ | types differ in mutability
+ | help: change the self-receiver type to match the trait: `self: &Bar`
+ |
+note: type in trait
+ --> $DIR/E0053.rs:3:12
+ |
+LL | fn bar(&self);
+ | ^^^^^
+ = note: expected signature `fn(&Bar)`
+ found signature `fn(&mut Bar)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/mismatched_types/E0409.rs b/tests/ui/mismatched_types/E0409.rs
new file mode 100644
index 000000000..3710534cc
--- /dev/null
+++ b/tests/ui/mismatched_types/E0409.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let x = (0, 2);
+
+ match x {
+ (0, ref y) | (y, 0) => {} //~ ERROR E0409
+ //~| ERROR E0308
+ _ => ()
+ }
+}
diff --git a/tests/ui/mismatched_types/E0409.stderr b/tests/ui/mismatched_types/E0409.stderr
new file mode 100644
index 000000000..7fec6ecd7
--- /dev/null
+++ b/tests/ui/mismatched_types/E0409.stderr
@@ -0,0 +1,28 @@
+error[E0409]: variable `y` is bound inconsistently across alternatives separated by `|`
+ --> $DIR/E0409.rs:5:23
+ |
+LL | (0, ref y) | (y, 0) => {}
+ | - ^ bound in different ways
+ | |
+ | first binding
+
+error[E0308]: mismatched types
+ --> $DIR/E0409.rs:5:23
+ |
+LL | match x {
+ | - this expression has type `({integer}, {integer})`
+LL | (0, ref y) | (y, 0) => {}
+ | ----- ^ expected `&{integer}`, found integer
+ | |
+ | first introduced with type `&{integer}` here
+ |
+ = note: in the same arm, a binding must have the same type in all alternatives
+help: consider adding `ref`
+ |
+LL | (0, ref y) | (ref y, 0) => {}
+ | +++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0409.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/E0631.rs b/tests/ui/mismatched_types/E0631.rs
new file mode 100644
index 000000000..83dbdb77a
--- /dev/null
+++ b/tests/ui/mismatched_types/E0631.rs
@@ -0,0 +1,11 @@
+#![feature(unboxed_closures)]
+
+fn foo<F: Fn(usize)>(_: F) {}
+fn bar<F: Fn<(usize,)>>(_: F) {}
+fn main() {
+ fn f(_: u64) {}
+ foo(|_: isize| {}); //~ ERROR type mismatch
+ bar(|_: isize| {}); //~ ERROR type mismatch
+ foo(f); //~ ERROR type mismatch
+ bar(f); //~ ERROR type mismatch
+}
diff --git a/tests/ui/mismatched_types/E0631.stderr b/tests/ui/mismatched_types/E0631.stderr
new file mode 100644
index 000000000..410ea4b0b
--- /dev/null
+++ b/tests/ui/mismatched_types/E0631.stderr
@@ -0,0 +1,73 @@
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/E0631.rs:7:5
+ |
+LL | foo(|_: isize| {});
+ | ^^^ ---------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `fn(usize) -> _`
+ found closure signature `fn(isize) -> _`
+note: required by a bound in `foo`
+ --> $DIR/E0631.rs:3:11
+ |
+LL | fn foo<F: Fn(usize)>(_: F) {}
+ | ^^^^^^^^^ required by this bound in `foo`
+
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/E0631.rs:8:5
+ |
+LL | bar(|_: isize| {});
+ | ^^^ ---------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `fn(usize) -> _`
+ found closure signature `fn(isize) -> _`
+note: required by a bound in `bar`
+ --> $DIR/E0631.rs:4:11
+ |
+LL | fn bar<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `bar`
+
+error[E0631]: type mismatch in function arguments
+ --> $DIR/E0631.rs:9:9
+ |
+LL | fn f(_: u64) {}
+ | ------------ found signature defined here
+...
+LL | foo(f);
+ | --- ^ expected due to this
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected function signature `fn(usize) -> _`
+ found function signature `fn(u64) -> _`
+note: required by a bound in `foo`
+ --> $DIR/E0631.rs:3:11
+ |
+LL | fn foo<F: Fn(usize)>(_: F) {}
+ | ^^^^^^^^^ required by this bound in `foo`
+
+error[E0631]: type mismatch in function arguments
+ --> $DIR/E0631.rs:10:9
+ |
+LL | fn f(_: u64) {}
+ | ------------ found signature defined here
+...
+LL | bar(f);
+ | --- ^ expected due to this
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected function signature `fn(usize) -> _`
+ found function signature `fn(u64) -> _`
+note: required by a bound in `bar`
+ --> $DIR/E0631.rs:4:11
+ |
+LL | fn bar<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `bar`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/mismatched_types/abridged.rs b/tests/ui/mismatched_types/abridged.rs
new file mode 100644
index 000000000..9a5c183ca
--- /dev/null
+++ b/tests/ui/mismatched_types/abridged.rs
@@ -0,0 +1,62 @@
+enum Bar {
+ Qux,
+ Zar,
+}
+
+struct Foo {
+ bar: usize,
+}
+
+struct X<T1, T2> {
+ x: T1,
+ y: T2,
+}
+
+fn a() -> Foo {
+ Some(Foo { bar: 1 }) //~ ERROR mismatched types
+}
+
+fn a2() -> Foo {
+ Ok(Foo { bar: 1}) //~ ERROR mismatched types
+}
+
+fn b() -> Option<Foo> {
+ Foo { bar: 1 } //~ ERROR mismatched types
+}
+
+fn c() -> Result<Foo, Bar> {
+ Foo { bar: 1 } //~ ERROR mismatched types
+}
+
+fn d() -> X<X<String, String>, String> {
+ let x = X {
+ x: X {
+ x: "".to_string(),
+ y: 2,
+ },
+ y: 3,
+ };
+ x //~ ERROR mismatched types
+}
+
+fn e() -> X<X<String, String>, String> {
+ let x = X {
+ x: X {
+ x: "".to_string(),
+ y: 2,
+ },
+ y: "".to_string(),
+ };
+ x //~ ERROR mismatched types
+}
+
+fn f() -> String {
+ 1+2 //~ ERROR mismatched types
+}
+
+
+fn g() -> String {
+ -2 //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/abridged.stderr b/tests/ui/mismatched_types/abridged.stderr
new file mode 100644
index 000000000..ff1a836c9
--- /dev/null
+++ b/tests/ui/mismatched_types/abridged.stderr
@@ -0,0 +1,105 @@
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:16:5
+ |
+LL | fn a() -> Foo {
+ | --- expected `Foo` because of return type
+LL | Some(Foo { bar: 1 })
+ | ^^^^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `Option`
+ |
+ = note: expected struct `Foo`
+ found enum `Option<Foo>`
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:20:5
+ |
+LL | fn a2() -> Foo {
+ | --- expected `Foo` because of return type
+LL | Ok(Foo { bar: 1})
+ | ^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `Result`
+ |
+ = note: expected struct `Foo`
+ found enum `Result<Foo, _>`
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:24:5
+ |
+LL | fn b() -> Option<Foo> {
+ | ----------- expected `Option<Foo>` because of return type
+LL | Foo { bar: 1 }
+ | ^^^^^^^^^^^^^^ expected enum `Option`, found struct `Foo`
+ |
+ = note: expected enum `Option<Foo>`
+ found struct `Foo`
+help: try wrapping the expression in `Some`
+ |
+LL | Some(Foo { bar: 1 })
+ | +++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:28:5
+ |
+LL | fn c() -> Result<Foo, Bar> {
+ | ---------------- expected `Result<Foo, Bar>` because of return type
+LL | Foo { bar: 1 }
+ | ^^^^^^^^^^^^^^ expected enum `Result`, found struct `Foo`
+ |
+ = note: expected enum `Result<Foo, Bar>`
+ found struct `Foo`
+help: try wrapping the expression in `Ok`
+ |
+LL | Ok(Foo { bar: 1 })
+ | +++ +
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:39:5
+ |
+LL | fn d() -> X<X<String, String>, String> {
+ | ---------------------------- expected `X<X<String, String>, String>` because of return type
+...
+LL | x
+ | ^ expected struct `String`, found integer
+ |
+ = note: expected struct `X<X<_, String>, String>`
+ found struct `X<X<_, {integer}>, {integer}>`
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:50:5
+ |
+LL | fn e() -> X<X<String, String>, String> {
+ | ---------------------------- expected `X<X<String, String>, String>` because of return type
+...
+LL | x
+ | ^ expected struct `String`, found integer
+ |
+ = note: expected struct `X<X<_, String>, _>`
+ found struct `X<X<_, {integer}>, _>`
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:54:5
+ |
+LL | fn f() -> String {
+ | ------ expected `String` because of return type
+LL | 1+2
+ | ^^^ expected struct `String`, found integer
+ |
+help: try using a conversion method
+ |
+LL | (1+2).to_string()
+ | + +++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/abridged.rs:59:5
+ |
+LL | fn g() -> String {
+ | ------ expected `String` because of return type
+LL | -2
+ | ^^ expected struct `String`, found integer
+ |
+help: try using a conversion method
+ |
+LL | (-2).to_string()
+ | + +++++++++++++
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/assignment-operator-unimplemented.rs b/tests/ui/mismatched_types/assignment-operator-unimplemented.rs
new file mode 100644
index 000000000..21df464d5
--- /dev/null
+++ b/tests/ui/mismatched_types/assignment-operator-unimplemented.rs
@@ -0,0 +1,7 @@
+struct Foo;
+
+fn main() {
+ let mut a = Foo;
+ let ref b = Foo;
+ a += *b; //~ Error: binary assignment operation `+=` cannot be applied to type `Foo`
+}
diff --git a/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr b/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr
new file mode 100644
index 000000000..2393791a9
--- /dev/null
+++ b/tests/ui/mismatched_types/assignment-operator-unimplemented.stderr
@@ -0,0 +1,19 @@
+error[E0368]: binary assignment operation `+=` cannot be applied to type `Foo`
+ --> $DIR/assignment-operator-unimplemented.rs:6:3
+ |
+LL | a += *b;
+ | -^^^^^^
+ | |
+ | cannot use `+=` on type `Foo`
+ |
+note: an implementation of `AddAssign<_>` might be missing for `Foo`
+ --> $DIR/assignment-operator-unimplemented.rs:1:1
+ |
+LL | struct Foo;
+ | ^^^^^^^^^^ must implement `AddAssign<_>`
+note: the trait `AddAssign` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0368`.
diff --git a/tests/ui/mismatched_types/binops.rs b/tests/ui/mismatched_types/binops.rs
new file mode 100644
index 000000000..f359451df
--- /dev/null
+++ b/tests/ui/mismatched_types/binops.rs
@@ -0,0 +1,8 @@
+fn main() {
+ 1 + Some(1); //~ ERROR cannot add `Option<{integer}>` to `{integer}`
+ 2 as usize - Some(1); //~ ERROR cannot subtract `Option<{integer}>` from `usize`
+ 3 * (); //~ ERROR cannot multiply `{integer}` by `()`
+ 4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
+ 5 < String::new(); //~ ERROR can't compare `{integer}` with `String`
+ 6 == Ok(1); //~ ERROR can't compare `{integer}` with `Result<{integer}, _>`
+}
diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr
new file mode 100644
index 000000000..3585587ed
--- /dev/null
+++ b/tests/ui/mismatched_types/binops.stderr
@@ -0,0 +1,106 @@
+error[E0277]: cannot add `Option<{integer}>` to `{integer}`
+ --> $DIR/binops.rs:2:7
+ |
+LL | 1 + Some(1);
+ | ^ no implementation for `{integer} + Option<{integer}>`
+ |
+ = help: the trait `Add<Option<{integer}>>` is not implemented for `{integer}`
+ = help: the following other types implement trait `Add<Rhs>`:
+ <&'a f32 as Add<f32>>
+ <&'a f64 as Add<f64>>
+ <&'a i128 as Add<i128>>
+ <&'a i16 as Add<i16>>
+ <&'a i32 as Add<i32>>
+ <&'a i64 as Add<i64>>
+ <&'a i8 as Add<i8>>
+ <&'a isize as Add<isize>>
+ and 48 others
+
+error[E0277]: cannot subtract `Option<{integer}>` from `usize`
+ --> $DIR/binops.rs:3:16
+ |
+LL | 2 as usize - Some(1);
+ | ^ no implementation for `usize - Option<{integer}>`
+ |
+ = help: the trait `Sub<Option<{integer}>>` is not implemented for `usize`
+ = help: the following other types implement trait `Sub<Rhs>`:
+ <&'a usize as Sub<usize>>
+ <&usize as Sub<&usize>>
+ <usize as Sub<&usize>>
+ <usize as Sub>
+
+error[E0277]: cannot multiply `{integer}` by `()`
+ --> $DIR/binops.rs:4:7
+ |
+LL | 3 * ();
+ | ^ no implementation for `{integer} * ()`
+ |
+ = help: the trait `Mul<()>` is not implemented for `{integer}`
+ = help: the following other types implement trait `Mul<Rhs>`:
+ <&'a f32 as Mul<f32>>
+ <&'a f64 as Mul<f64>>
+ <&'a i128 as Mul<i128>>
+ <&'a i16 as Mul<i16>>
+ <&'a i32 as Mul<i32>>
+ <&'a i64 as Mul<i64>>
+ <&'a i8 as Mul<i8>>
+ <&'a isize as Mul<isize>>
+ and 49 others
+
+error[E0277]: cannot divide `{integer}` by `&str`
+ --> $DIR/binops.rs:5:7
+ |
+LL | 4 / "";
+ | ^ no implementation for `{integer} / &str`
+ |
+ = help: the trait `Div<&str>` is not implemented for `{integer}`
+ = help: the following other types implement trait `Div<Rhs>`:
+ <&'a f32 as Div<f32>>
+ <&'a f64 as Div<f64>>
+ <&'a i128 as Div<i128>>
+ <&'a i16 as Div<i16>>
+ <&'a i32 as Div<i32>>
+ <&'a i64 as Div<i64>>
+ <&'a i8 as Div<i8>>
+ <&'a isize as Div<isize>>
+ and 54 others
+
+error[E0277]: can't compare `{integer}` with `String`
+ --> $DIR/binops.rs:6:7
+ |
+LL | 5 < String::new();
+ | ^ no implementation for `{integer} < String` and `{integer} > String`
+ |
+ = help: the trait `PartialOrd<String>` is not implemented for `{integer}`
+ = help: the following other types implement trait `PartialOrd<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error[E0277]: can't compare `{integer}` with `Result<{integer}, _>`
+ --> $DIR/binops.rs:7:7
+ |
+LL | 6 == Ok(1);
+ | ^^ no implementation for `{integer} == Result<{integer}, _>`
+ |
+ = help: the trait `PartialEq<Result<{integer}, _>>` is not implemented for `{integer}`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/mismatched_types/cast-rfc0401.rs b/tests/ui/mismatched_types/cast-rfc0401.rs
new file mode 100644
index 000000000..57222f459
--- /dev/null
+++ b/tests/ui/mismatched_types/cast-rfc0401.rs
@@ -0,0 +1,72 @@
+fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
+{
+ u as *const V //~ ERROR is invalid
+}
+
+fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
+{
+ u as *const str //~ ERROR is invalid
+}
+
+trait Foo { fn foo(&self) {} }
+impl<T> Foo for T {}
+
+trait Bar { fn foo(&self) {} }
+impl<T> Bar for T {}
+
+enum E {
+ A, B
+}
+
+fn main()
+{
+ let f: f32 = 1.2;
+ let v = core::ptr::null::<u8>();
+ let fat_v : *const [u8] = unsafe { &*core::ptr::null::<[u8; 1]>()};
+ let fat_sv : *const [i8] = unsafe { &*core::ptr::null::<[i8; 1]>()};
+ let foo: &dyn Foo = &f;
+
+ let _ = v as &u8; //~ ERROR non-primitive cast
+ let _ = v as E; //~ ERROR non-primitive cast
+ let _ = v as fn(); //~ ERROR non-primitive cast
+ let _ = v as (u32,); //~ ERROR non-primitive cast
+ let _ = Some(&v) as *const u8; //~ ERROR non-primitive cast
+
+ let _ = v as f32; //~ ERROR is invalid
+ let _ = main as f64; //~ ERROR is invalid
+ let _ = &v as usize; //~ ERROR is invalid
+ let _ = f as *const u8; //~ ERROR is invalid
+ let _ = 3_i32 as bool; //~ ERROR cannot cast
+ let _ = E::A as bool; //~ ERROR cannot cast
+ let _ = 0x61u32 as char; //~ ERROR can be cast as
+
+ let _ = false as f32; //~ ERROR is invalid
+ let _ = E::A as f32; //~ ERROR is invalid
+ let _ = 'a' as f32; //~ ERROR is invalid
+
+ let _ = false as *const u8; //~ ERROR is invalid
+ let _ = E::A as *const u8; //~ ERROR is invalid
+ let _ = 'a' as *const u8; //~ ERROR is invalid
+
+ let _ = 42usize as *const [u8]; //~ ERROR cannot cast `usize` to a pointer that is wide
+ let _ = v as *const [u8]; //~ ERROR cannot cast
+ let _ = fat_v as *const dyn Foo; //~ ERROR the size for values of type
+ let _ = foo as *const str; //~ ERROR is invalid
+ let _ = foo as *mut str; //~ ERROR is invalid
+ let _ = main as *mut str; //~ ERROR is invalid
+ let _ = &f as *mut f32; //~ ERROR is invalid
+ let _ = &f as *const f64; //~ ERROR is invalid
+ let _ = fat_sv as usize; //~ ERROR is invalid
+
+ let a : *const str = "hello";
+ let _ = a as *const dyn Foo; //~ ERROR the size for values of type
+
+ // check no error cascade
+ let _ = main.f as *const u32; //~ ERROR no field
+
+ let cf: *const dyn Foo = &0;
+ let _ = cf as *const [u16]; //~ ERROR is invalid
+ let _ = cf as *const dyn Bar; //~ ERROR is invalid
+
+ vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid
+}
diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr
new file mode 100644
index 000000000..2a36a352c
--- /dev/null
+++ b/tests/ui/mismatched_types/cast-rfc0401.stderr
@@ -0,0 +1,256 @@
+error[E0606]: casting `*const U` as `*const V` is invalid
+ --> $DIR/cast-rfc0401.rs:3:5
+ |
+LL | u as *const V
+ | ^^^^^^^^^^^^^
+ |
+ = note: vtable kinds may not match
+
+error[E0606]: casting `*const U` as `*const str` is invalid
+ --> $DIR/cast-rfc0401.rs:8:5
+ |
+LL | u as *const str
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: vtable kinds may not match
+
+error[E0609]: no field `f` on type `fn() {main}`
+ --> $DIR/cast-rfc0401.rs:65:18
+ |
+LL | let _ = main.f as *const u32;
+ | ^
+
+error[E0605]: non-primitive cast: `*const u8` as `&u8`
+ --> $DIR/cast-rfc0401.rs:29:13
+ |
+LL | let _ = v as &u8;
+ | ^^^^^^^^ invalid cast
+ |
+help: consider borrowing the value
+ |
+LL - let _ = v as &u8;
+LL + let _ = &*v;
+ |
+
+error[E0605]: non-primitive cast: `*const u8` as `E`
+ --> $DIR/cast-rfc0401.rs:30:13
+ |
+LL | let _ = v as E;
+ | ^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error[E0605]: non-primitive cast: `*const u8` as `fn()`
+ --> $DIR/cast-rfc0401.rs:31:13
+ |
+LL | let _ = v as fn();
+ | ^^^^^^^^^ invalid cast
+
+error[E0605]: non-primitive cast: `*const u8` as `(u32,)`
+ --> $DIR/cast-rfc0401.rs:32:13
+ |
+LL | let _ = v as (u32,);
+ | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error[E0605]: non-primitive cast: `Option<&*const u8>` as `*const u8`
+ --> $DIR/cast-rfc0401.rs:33:13
+ |
+LL | let _ = Some(&v) as *const u8;
+ | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error[E0606]: casting `*const u8` as `f32` is invalid
+ --> $DIR/cast-rfc0401.rs:35:13
+ |
+LL | let _ = v as f32;
+ | ^^^^^^^^
+
+error[E0606]: casting `fn() {main}` as `f64` is invalid
+ --> $DIR/cast-rfc0401.rs:36:13
+ |
+LL | let _ = main as f64;
+ | ^^^^^^^^^^^
+
+error[E0606]: casting `&*const u8` as `usize` is invalid
+ --> $DIR/cast-rfc0401.rs:37:13
+ |
+LL | let _ = &v as usize;
+ | ^^^^^^^^^^^
+ |
+ = help: cast through a raw pointer first
+
+error[E0606]: casting `f32` as `*const u8` is invalid
+ --> $DIR/cast-rfc0401.rs:38:13
+ |
+LL | let _ = f as *const u8;
+ | ^^^^^^^^^^^^^^
+
+error[E0054]: cannot cast as `bool`
+ --> $DIR/cast-rfc0401.rs:39:13
+ |
+LL | let _ = 3_i32 as bool;
+ | ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0`
+
+error[E0054]: cannot cast as `bool`
+ --> $DIR/cast-rfc0401.rs:40:13
+ |
+LL | let _ = E::A as bool;
+ | ^^^^^^^^^^^^ unsupported cast
+
+error[E0604]: only `u8` can be cast as `char`, not `u32`
+ --> $DIR/cast-rfc0401.rs:41:13
+ |
+LL | let _ = 0x61u32 as char;
+ | ^^^^^^^^^^^^^^^
+ | |
+ | invalid cast
+ | help: try `char::from_u32` instead: `char::from_u32(0x61u32)`
+
+error[E0606]: casting `bool` as `f32` is invalid
+ --> $DIR/cast-rfc0401.rs:43:13
+ |
+LL | let _ = false as f32;
+ | ^^^^^^^^^^^^
+ |
+ = help: cast through an integer first
+
+error[E0606]: casting `E` as `f32` is invalid
+ --> $DIR/cast-rfc0401.rs:44:13
+ |
+LL | let _ = E::A as f32;
+ | ^^^^^^^^^^^
+ |
+ = help: cast through an integer first
+
+error[E0606]: casting `char` as `f32` is invalid
+ --> $DIR/cast-rfc0401.rs:45:13
+ |
+LL | let _ = 'a' as f32;
+ | ^^^^^^^^^^
+ |
+ = help: cast through an integer first
+
+error[E0606]: casting `bool` as `*const u8` is invalid
+ --> $DIR/cast-rfc0401.rs:47:13
+ |
+LL | let _ = false as *const u8;
+ | ^^^^^^^^^^^^^^^^^^
+
+error[E0606]: casting `E` as `*const u8` is invalid
+ --> $DIR/cast-rfc0401.rs:48:13
+ |
+LL | let _ = E::A as *const u8;
+ | ^^^^^^^^^^^^^^^^^
+
+error[E0606]: casting `char` as `*const u8` is invalid
+ --> $DIR/cast-rfc0401.rs:49:13
+ |
+LL | let _ = 'a' as *const u8;
+ | ^^^^^^^^^^^^^^^^
+
+error[E0606]: cannot cast `usize` to a pointer that is wide
+ --> $DIR/cast-rfc0401.rs:51:24
+ |
+LL | let _ = 42usize as *const [u8];
+ | ------- ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length
+ | |
+ | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+
+error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
+ --> $DIR/cast-rfc0401.rs:52:13
+ |
+LL | let _ = v as *const [u8];
+ | ^^^^^^^^^^^^^^^^
+
+error[E0606]: casting `&dyn Foo` as `*const str` is invalid
+ --> $DIR/cast-rfc0401.rs:54:13
+ |
+LL | let _ = foo as *const str;
+ | ^^^^^^^^^^^^^^^^^
+
+error[E0606]: casting `&dyn Foo` as `*mut str` is invalid
+ --> $DIR/cast-rfc0401.rs:55:13
+ |
+LL | let _ = foo as *mut str;
+ | ^^^^^^^^^^^^^^^
+
+error[E0606]: casting `fn() {main}` as `*mut str` is invalid
+ --> $DIR/cast-rfc0401.rs:56:13
+ |
+LL | let _ = main as *mut str;
+ | ^^^^^^^^^^^^^^^^
+
+error[E0606]: casting `&f32` as `*mut f32` is invalid
+ --> $DIR/cast-rfc0401.rs:57:13
+ |
+LL | let _ = &f as *mut f32;
+ | ^^^^^^^^^^^^^^
+
+error[E0606]: casting `&f32` as `*const f64` is invalid
+ --> $DIR/cast-rfc0401.rs:58:13
+ |
+LL | let _ = &f as *const f64;
+ | ^^^^^^^^^^^^^^^^
+
+error[E0606]: casting `*const [i8]` as `usize` is invalid
+ --> $DIR/cast-rfc0401.rs:59:13
+ |
+LL | let _ = fat_sv as usize;
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: cast through a thin pointer first
+
+error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid
+ --> $DIR/cast-rfc0401.rs:68:13
+ |
+LL | let _ = cf as *const [u16];
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: vtable kinds may not match
+
+error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid
+ --> $DIR/cast-rfc0401.rs:69:13
+ |
+LL | let _ = cf as *const dyn Bar;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: vtable kinds may not match
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/cast-rfc0401.rs:53:13
+ |
+LL | let _ = fat_v as *const dyn Foo;
+ | ^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: required for the cast from `[u8]` to the object type `dyn Foo`
+help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo`
+ |
+LL | let _ = &fat_v as *const dyn Foo;
+ | +
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+ --> $DIR/cast-rfc0401.rs:62:13
+ |
+LL | let _ = a as *const dyn Foo;
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `str`
+ = note: required for the cast from `str` to the object type `dyn Foo`
+help: consider borrowing the value, since `&str` can be coerced into `dyn Foo`
+ |
+LL | let _ = &a as *const dyn Foo;
+ | +
+
+error[E0606]: casting `&{float}` as `f32` is invalid
+ --> $DIR/cast-rfc0401.rs:71:30
+ |
+LL | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
+ | ^^^^^^^^
+ |
+help: dereference the expression
+ |
+LL | vec![0.0].iter().map(|s| *s as f32).collect::<Vec<f32>>();
+ | +
+
+error: aborting due to 34 previous errors
+
+Some errors have detailed explanations: E0054, E0277, E0604, E0605, E0606, E0607, E0609.
+For more information about an error, try `rustc --explain E0054`.
diff --git a/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.fixed b/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.fixed
new file mode 100644
index 000000000..efba0543b
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.fixed
@@ -0,0 +1,20 @@
+// Regression test for #47244: in this specific scenario, when the
+// expected type indicated 1 argument but the closure takes two, we
+// would (early on) create type variables for the type of `b`. If the
+// user then attempts to invoke a method on `b`, we would get an error
+// saying that the type of `b` must be known, which was not very
+// helpful.
+
+// run-rustfix
+
+use std::collections::HashMap;
+
+fn main() {
+ let mut m = HashMap::new();
+ m.insert("foo", "bar");
+
+ let _n = m.iter().map(|(_, b)| {
+ //~^ ERROR closure is expected to take a single 2-tuple
+ b.to_string()
+ });
+}
diff --git a/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs b/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs
new file mode 100644
index 000000000..3ddb93d12
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs
@@ -0,0 +1,20 @@
+// Regression test for #47244: in this specific scenario, when the
+// expected type indicated 1 argument but the closure takes two, we
+// would (early on) create type variables for the type of `b`. If the
+// user then attempts to invoke a method on `b`, we would get an error
+// saying that the type of `b` must be known, which was not very
+// helpful.
+
+// run-rustfix
+
+use std::collections::HashMap;
+
+fn main() {
+ let mut m = HashMap::new();
+ m.insert("foo", "bar");
+
+ let _n = m.iter().map(|_, b| {
+ //~^ ERROR closure is expected to take a single 2-tuple
+ b.to_string()
+ });
+}
diff --git a/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr b/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr
new file mode 100644
index 000000000..d7db90e50
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr
@@ -0,0 +1,16 @@
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
+ --> $DIR/closure-arg-count-expected-type-issue-47244.rs:16:23
+ |
+LL | let _n = m.iter().map(|_, b| {
+ | ^^^ ------ takes 2 distinct arguments
+ | |
+ | expected closure that takes a single 2-tuple as argument
+ |
+help: change the closure to accept a tuple instead of individual arguments
+ |
+LL | let _n = m.iter().map(|(_, b)| {
+ | ~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0593`.
diff --git a/tests/ui/mismatched_types/closure-arg-count.rs b/tests/ui/mismatched_types/closure-arg-count.rs
new file mode 100644
index 000000000..65c8d6a7e
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-count.rs
@@ -0,0 +1,43 @@
+#![feature(unboxed_closures)]
+
+fn f<F: Fn<(usize,)>>(_: F) {}
+fn main() {
+ [1, 2, 3].sort_by(|| panic!());
+ //~^ ERROR closure is expected to take
+ [1, 2, 3].sort_by(|tuple| panic!());
+ //~^ ERROR closure is expected to take
+ [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
+ //~^ ERROR closure is expected to take
+ [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!());
+ //~^ ERROR closure is expected to take
+ f(|| panic!());
+ //~^ ERROR closure is expected to take
+ f( move || panic!());
+ //~^ ERROR closure is expected to take
+
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i);
+ //~^ ERROR closure is expected to take
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i);
+ //~^ ERROR closure is expected to take
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i);
+ //~^ ERROR closure is expected to take
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
+ //~^ ERROR function is expected to take
+ let bar = |i, x, y| i;
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
+ //~^ ERROR closure is expected to take
+ let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
+ //~^ ERROR function is expected to take
+
+ let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
+ //~^ ERROR function is expected to take
+
+ call(Foo);
+ //~^ ERROR function is expected to take
+}
+
+fn foo() {}
+fn qux(x: usize, y: usize) {}
+
+fn call<F, R>(_: F) where F: FnOnce() -> R {}
+struct Foo(u8);
diff --git a/tests/ui/mismatched_types/closure-arg-count.stderr b/tests/ui/mismatched_types/closure-arg-count.stderr
new file mode 100644
index 000000000..2ecab9f02
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-count.stderr
@@ -0,0 +1,189 @@
+error[E0593]: closure is expected to take 2 arguments, but it takes 0 arguments
+ --> $DIR/closure-arg-count.rs:5:15
+ |
+LL | [1, 2, 3].sort_by(|| panic!());
+ | ^^^^^^^ -- takes 0 arguments
+ | |
+ | expected closure that takes 2 arguments
+ |
+help: consider changing the closure to take and ignore the expected arguments
+ |
+LL | [1, 2, 3].sort_by(|_, _| panic!());
+ | ~~~~~~
+
+error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument
+ --> $DIR/closure-arg-count.rs:7:15
+ |
+LL | [1, 2, 3].sort_by(|tuple| panic!());
+ | ^^^^^^^ ------- takes 1 argument
+ | |
+ | expected closure that takes 2 arguments
+
+error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument
+ --> $DIR/closure-arg-count.rs:9:15
+ |
+LL | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
+ | ^^^^^^^ ----------------- takes a single 2-tuple as argument
+ | |
+ | expected closure that takes 2 distinct arguments
+ |
+help: change the closure to take multiple arguments instead of a single tuple
+ |
+LL | [1, 2, 3].sort_by(|tuple, tuple2| panic!());
+ | ~~~~~~~~~~~~~~~
+
+error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument
+ --> $DIR/closure-arg-count.rs:11:15
+ |
+LL | [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!());
+ | ^^^^^^^ ----------------------------- takes a single 2-tuple as argument
+ | |
+ | expected closure that takes 2 distinct arguments
+ |
+help: change the closure to take multiple arguments instead of a single tuple
+ |
+LL | [1, 2, 3].sort_by(|tuple, tuple2| panic!());
+ | ~~~~~~~~~~~~~~~
+
+error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
+ --> $DIR/closure-arg-count.rs:13:5
+ |
+LL | f(|| panic!());
+ | ^ -- takes 0 arguments
+ | |
+ | expected closure that takes 1 argument
+ |
+note: required by a bound in `f`
+ --> $DIR/closure-arg-count.rs:3:9
+ |
+LL | fn f<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `f`
+help: consider changing the closure to take and ignore the expected argument
+ |
+LL | f(|_| panic!());
+ | ~~~
+
+error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
+ --> $DIR/closure-arg-count.rs:15:5
+ |
+LL | f( move || panic!());
+ | ^ ---------- takes 0 arguments
+ | |
+ | expected closure that takes 1 argument
+ |
+note: required by a bound in `f`
+ --> $DIR/closure-arg-count.rs:3:9
+ |
+LL | fn f<F: Fn<(usize,)>>(_: F) {}
+ | ^^^^^^^^^^^^ required by this bound in `f`
+help: consider changing the closure to take and ignore the expected argument
+ |
+LL | f( move |_| panic!());
+ | ~~~
+
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
+ --> $DIR/closure-arg-count.rs:18:53
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i);
+ | ^^^ ------ takes 2 distinct arguments
+ | |
+ | expected closure that takes a single 2-tuple as argument
+ |
+help: change the closure to accept a tuple instead of individual arguments
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i);
+ | ~~~~~~~~
+
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
+ --> $DIR/closure-arg-count.rs:20:53
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i);
+ | ^^^ ------------- takes 2 distinct arguments
+ | |
+ | expected closure that takes a single 2-tuple as argument
+ |
+help: change the closure to accept a tuple instead of individual arguments
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i);
+ | ~~~~~~~~
+
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
+ --> $DIR/closure-arg-count.rs:22:53
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i);
+ | ^^^ --------- takes 3 distinct arguments
+ | |
+ | expected closure that takes a single 2-tuple as argument
+
+error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments
+ --> $DIR/closure-arg-count.rs:24:57
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
+ | --- ^^^ expected function that takes a single 2-tuple as argument
+ | |
+ | required by a bound introduced by this call
+...
+LL | fn foo() {}
+ | -------- takes 0 arguments
+ |
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
+ --> $DIR/closure-arg-count.rs:27:57
+ |
+LL | let bar = |i, x, y| i;
+ | --------- takes 3 distinct arguments
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
+ | --- ^^^ expected closure that takes a single 2-tuple as argument
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
+ --> $DIR/closure-arg-count.rs:29:57
+ |
+LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
+ | --- ^^^ expected function that takes a single 2-tuple as argument
+ | |
+ | required by a bound introduced by this call
+...
+LL | fn qux(x: usize, y: usize) {}
+ | -------------------------- takes 2 distinct arguments
+ |
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
+ --> $DIR/closure-arg-count.rs:32:45
+ |
+LL | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
+ | --- ^^^^^^^^^^^^^^^^^^ expected function that takes 1 argument
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
+ --> $DIR/closure-arg-count.rs:35:10
+ |
+LL | call(Foo);
+ | ---- ^^^ expected function that takes 0 arguments
+ | |
+ | required by a bound introduced by this call
+...
+LL | struct Foo(u8);
+ | ---------- takes 1 argument
+ |
+note: required by a bound in `call`
+ --> $DIR/closure-arg-count.rs:42:30
+ |
+LL | fn call<F, R>(_: F) where F: FnOnce() -> R {}
+ | ^^^^^^^^^^^^^ required by this bound in `call`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0593`.
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed
new file mode 100644
index 000000000..6315fcca2
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+ let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
+ let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
+}
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
new file mode 100644
index 000000000..c12c5362e
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+ let _ = (-10..=10).find(|x: i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
+ let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
+}
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr
new file mode 100644
index 000000000..fb8af4bb7
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr
@@ -0,0 +1,38 @@
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/closure-arg-type-mismatch-issue-45727.rs:3:24
+ |
+LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0);
+ | ^^^^ -------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `for<'a> fn(&'a {integer}) -> _`
+ found closure signature `fn(i32) -> _`
+note: required by a bound in `find`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+help: consider borrowing the argument
+ |
+LL | let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
+ | +
+
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/closure-arg-type-mismatch-issue-45727.rs:4:24
+ |
+LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
+ | ^^^^ ----------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `for<'a> fn(&'a {integer}) -> _`
+ found closure signature `for<'a, 'b, 'c> fn(&'a &'b &'c i32) -> _`
+note: required by a bound in `find`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+help: do not borrow the argument
+ |
+LL - let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
+LL + let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch.rs
new file mode 100644
index 000000000..98abb0ba9
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.rs
@@ -0,0 +1,11 @@
+fn main() {
+ let a = [(1u32, 2u32)];
+ a.iter().map(|_: (u32, u32)| 45); //~ ERROR type mismatch
+ a.iter().map(|_: &(u16, u16)| 45); //~ ERROR type mismatch
+ a.iter().map(|_: (u16, u16)| 45); //~ ERROR type mismatch
+}
+
+fn baz<F: Fn(*mut &u32)>(_: F) {}
+fn _test<'a>(f: fn(*mut &'a u32)) {
+ baz(f);
+}
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr
new file mode 100644
index 000000000..811ff0533
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -0,0 +1,46 @@
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/closure-arg-type-mismatch.rs:3:14
+ |
+LL | a.iter().map(|_: (u32, u32)| 45);
+ | ^^^ --------------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `fn(&(u32, u32)) -> _`
+ found closure signature `fn((u32, u32)) -> _`
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+help: consider borrowing the argument
+ |
+LL | a.iter().map(|_: &(u32, u32)| 45);
+ | +
+
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/closure-arg-type-mismatch.rs:4:14
+ |
+LL | a.iter().map(|_: &(u16, u16)| 45);
+ | ^^^ ---------------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `fn(&(u32, u32)) -> _`
+ found closure signature `for<'a> fn(&'a (u16, u16)) -> _`
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/closure-arg-type-mismatch.rs:5:14
+ |
+LL | a.iter().map(|_: (u16, u16)| 45);
+ | ^^^ --------------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `fn(&(u32, u32)) -> _`
+ found closure signature `fn((u16, u16)) -> _`
+note: required by a bound in `map`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/mismatched_types/closure-mismatch.rs b/tests/ui/mismatched_types/closure-mismatch.rs
new file mode 100644
index 000000000..b0644e796
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-mismatch.rs
@@ -0,0 +1,11 @@
+trait Foo {}
+
+impl<T: Fn(&())> Foo for T {}
+
+fn baz<T: Foo>(_: T) {}
+
+fn main() {
+ baz(|_| ());
+ //~^ ERROR implementation of `FnOnce` is not general enough
+ //~| ERROR mismatched types
+}
diff --git a/tests/ui/mismatched_types/closure-mismatch.stderr b/tests/ui/mismatched_types/closure-mismatch.stderr
new file mode 100644
index 000000000..a7ef8fa08
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-mismatch.stderr
@@ -0,0 +1,31 @@
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/closure-mismatch.rs:8:5
+ |
+LL | baz(|_| ());
+ | ^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+ |
+ = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
+
+error[E0308]: mismatched types
+ --> $DIR/closure-mismatch.rs:8:5
+ |
+LL | baz(|_| ());
+ | ^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected trait `for<'a> Fn<(&'a (),)>`
+ found trait `Fn<(&(),)>`
+note: this closure does not fulfill the lifetime requirements
+ --> $DIR/closure-mismatch.rs:8:9
+ |
+LL | baz(|_| ());
+ | ^^^
+note: the lifetime requirement is introduced here
+ --> $DIR/closure-mismatch.rs:5:11
+ |
+LL | fn baz<T: Foo>(_: T) {}
+ | ^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/const-fn-in-trait.rs b/tests/ui/mismatched_types/const-fn-in-trait.rs
new file mode 100644
index 000000000..e04d59c58
--- /dev/null
+++ b/tests/ui/mismatched_types/const-fn-in-trait.rs
@@ -0,0 +1,11 @@
+trait Foo {
+ fn f() -> u32;
+ const fn g(); //~ ERROR cannot be declared const
+}
+
+impl Foo for u32 {
+ const fn f() -> u32 { 22 } //~ ERROR cannot be declared const
+ fn g() {}
+}
+
+fn main() { }
diff --git a/tests/ui/mismatched_types/const-fn-in-trait.stderr b/tests/ui/mismatched_types/const-fn-in-trait.stderr
new file mode 100644
index 000000000..7d1fbe45c
--- /dev/null
+++ b/tests/ui/mismatched_types/const-fn-in-trait.stderr
@@ -0,0 +1,15 @@
+error[E0379]: functions in traits cannot be declared const
+ --> $DIR/const-fn-in-trait.rs:3:5
+ |
+LL | const fn g();
+ | ^^^^^ functions in traits cannot be const
+
+error[E0379]: functions in traits cannot be declared const
+ --> $DIR/const-fn-in-trait.rs:7:5
+ |
+LL | const fn f() -> u32 { 22 }
+ | ^^^^^ functions in traits cannot be const
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0379`.
diff --git a/tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs b/tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs
new file mode 100644
index 000000000..d302dc99b
--- /dev/null
+++ b/tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs
@@ -0,0 +1,23 @@
+struct S;
+struct Y;
+
+trait Trait {}
+
+impl Trait for Y {}
+
+fn foo() -> impl Trait {
+ if true {
+ S
+ } else {
+ Y //~ ERROR `if` and `else` have incompatible types
+ }
+}
+
+fn bar() -> impl Trait {
+ match true {
+ true => S,
+ false => Y, //~ ERROR `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr b/tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr
new file mode 100644
index 000000000..2f814445b
--- /dev/null
+++ b/tests/ui/mismatched_types/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.stderr
@@ -0,0 +1,26 @@
+error[E0308]: `if` and `else` have incompatible types
+ --> $DIR/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs:12:9
+ |
+LL | / if true {
+LL | | S
+ | | - expected because of this
+LL | | } else {
+LL | | Y
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `if` and `else` have incompatible types
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/do-not-suggest-boxed-trait-objects-instead-of-impl-trait.rs:19:18
+ |
+LL | / match true {
+LL | | true => S,
+ | | - this is found to be of type `S`
+LL | | false => Y,
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `match` arms have incompatible types
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.rs b/tests/ui/mismatched_types/dont-point-return-on-E0308.rs
new file mode 100644
index 000000000..f2ba610e2
--- /dev/null
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.rs
@@ -0,0 +1,18 @@
+// edition:2021
+
+async fn f(_: &()) {}
+//~^ NOTE function defined here
+//~| NOTE
+// Second note is the span of the underlined argument, I think...
+
+fn main() {
+ (|| async {
+ Err::<(), ()>(())?;
+ f(());
+ //~^ ERROR mismatched types
+ //~| NOTE arguments to this function are incorrect
+ //~| NOTE expected `&()`, found `()`
+ //~| HELP consider borrowing here
+ Ok::<(), ()>(())
+ })();
+}
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
new file mode 100644
index 000000000..13942682d
--- /dev/null
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/dont-point-return-on-E0308.rs:11:11
+ |
+LL | f(());
+ | - ^^
+ | | |
+ | | expected `&()`, found `()`
+ | | help: consider borrowing here: `&()`
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/dont-point-return-on-E0308.rs:3:10
+ |
+LL | async fn f(_: &()) {}
+ | ^ ------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/float-literal-inference-restrictions.rs b/tests/ui/mismatched_types/float-literal-inference-restrictions.rs
new file mode 100644
index 000000000..34079b61e
--- /dev/null
+++ b/tests/ui/mismatched_types/float-literal-inference-restrictions.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let x: f32 = 1; //~ ERROR mismatched types
+ let y: f32 = 1f64; //~ ERROR mismatched types
+}
diff --git a/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr b/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr
new file mode 100644
index 000000000..454373c32
--- /dev/null
+++ b/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr
@@ -0,0 +1,26 @@
+error[E0308]: mismatched types
+ --> $DIR/float-literal-inference-restrictions.rs:2:18
+ |
+LL | let x: f32 = 1;
+ | --- ^
+ | | |
+ | | expected `f32`, found integer
+ | | help: use a float literal: `1.0`
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/float-literal-inference-restrictions.rs:3:18
+ |
+LL | let y: f32 = 1f64;
+ | --- ^^^^ expected `f32`, found `f64`
+ | |
+ | expected due to this
+ |
+help: change the type of the numeric literal from `f64` to `f32`
+ |
+LL | let y: f32 = 1f32;
+ | ~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/fn-variance-1.rs b/tests/ui/mismatched_types/fn-variance-1.rs
new file mode 100644
index 000000000..b8a6c9a9b
--- /dev/null
+++ b/tests/ui/mismatched_types/fn-variance-1.rs
@@ -0,0 +1,17 @@
+fn takes_imm(x: &isize) { }
+
+fn takes_mut(x: &mut isize) { }
+
+fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+ f(t)
+}
+
+fn main() {
+ apply(&3, takes_imm);
+ apply(&3, takes_mut);
+ //~^ ERROR type mismatch
+
+ apply(&mut 3, takes_mut);
+ apply(&mut 3, takes_imm);
+ //~^ ERROR type mismatch
+}
diff --git a/tests/ui/mismatched_types/fn-variance-1.stderr b/tests/ui/mismatched_types/fn-variance-1.stderr
new file mode 100644
index 000000000..5794e606e
--- /dev/null
+++ b/tests/ui/mismatched_types/fn-variance-1.stderr
@@ -0,0 +1,41 @@
+error[E0631]: type mismatch in function arguments
+ --> $DIR/fn-variance-1.rs:11:15
+ |
+LL | fn takes_mut(x: &mut isize) { }
+ | --------------------------- found signature defined here
+...
+LL | apply(&3, takes_mut);
+ | ----- ^^^^^^^^^ expected due to this
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected function signature `fn(&{integer}) -> _`
+ found function signature `for<'a> fn(&'a mut isize) -> _`
+note: required by a bound in `apply`
+ --> $DIR/fn-variance-1.rs:5:37
+ |
+LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+ | ^^^^^^^^^ required by this bound in `apply`
+
+error[E0631]: type mismatch in function arguments
+ --> $DIR/fn-variance-1.rs:15:19
+ |
+LL | fn takes_imm(x: &isize) { }
+ | ----------------------- found signature defined here
+...
+LL | apply(&mut 3, takes_imm);
+ | ----- ^^^^^^^^^ expected due to this
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected function signature `fn(&mut {integer}) -> _`
+ found function signature `for<'a> fn(&'a isize) -> _`
+note: required by a bound in `apply`
+ --> $DIR/fn-variance-1.rs:5:37
+ |
+LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+ | ^^^^^^^^^ required by this bound in `apply`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/mismatched_types/for-loop-has-unit-body.rs b/tests/ui/mismatched_types/for-loop-has-unit-body.rs
new file mode 100644
index 000000000..a9433d7de
--- /dev/null
+++ b/tests/ui/mismatched_types/for-loop-has-unit-body.rs
@@ -0,0 +1,5 @@
+fn main() {
+ for x in 0..3 {
+ x //~ ERROR mismatched types
+ }
+}
diff --git a/tests/ui/mismatched_types/for-loop-has-unit-body.stderr b/tests/ui/mismatched_types/for-loop-has-unit-body.stderr
new file mode 100644
index 000000000..f36fe64bf
--- /dev/null
+++ b/tests/ui/mismatched_types/for-loop-has-unit-body.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+ --> $DIR/for-loop-has-unit-body.rs:3:9
+ |
+LL | x
+ | ^ expected `()`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-106182.fixed b/tests/ui/mismatched_types/issue-106182.fixed
new file mode 100644
index 000000000..b8ddebf6f
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-106182.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct _S(u32, Vec<i32>);
+
+fn _foo(x: &_S) {
+ match x {
+ _S(mut _y, _v) => {
+ //~^ ERROR mismatched types [E0308]
+ }
+ }
+}
+
+fn main() {
+}
diff --git a/tests/ui/mismatched_types/issue-106182.rs b/tests/ui/mismatched_types/issue-106182.rs
new file mode 100644
index 000000000..6eb6df13a
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-106182.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct _S(u32, Vec<i32>);
+
+fn _foo(x: &_S) {
+ match x {
+ _S(& (mut _y), _v) => {
+ //~^ ERROR mismatched types [E0308]
+ }
+ }
+}
+
+fn main() {
+}
diff --git a/tests/ui/mismatched_types/issue-106182.stderr b/tests/ui/mismatched_types/issue-106182.stderr
new file mode 100644
index 000000000..ac3ab8e98
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-106182.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-106182.rs:7:12
+ |
+LL | match x {
+ | - this expression has type `&_S`
+LL | _S(& (mut _y), _v) => {
+ | ^^^^^^^^^^ expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL | _S(mut _y, _v) => {
+ | ~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-19109.rs b/tests/ui/mismatched_types/issue-19109.rs
new file mode 100644
index 000000000..eae6a8790
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-19109.rs
@@ -0,0 +1,8 @@
+trait Trait { }
+
+fn function(t: &mut dyn Trait) {
+ t as *mut dyn Trait
+ //~^ ERROR: mismatched types
+}
+
+fn main() { }
diff --git a/tests/ui/mismatched_types/issue-19109.stderr b/tests/ui/mismatched_types/issue-19109.stderr
new file mode 100644
index 000000000..5cef64bb1
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-19109.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-19109.rs:4:5
+ |
+LL | fn function(t: &mut dyn Trait) {
+ | - help: try adding a return type: `-> *mut dyn Trait`
+LL | t as *mut dyn Trait
+ | ^^^^^^^^^^^^^^^^^^^ expected `()`, found `*mut dyn Trait`
+ |
+ = note: expected unit type `()`
+ found raw pointer `*mut dyn Trait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-26480.rs b/tests/ui/mismatched_types/issue-26480.rs
new file mode 100644
index 000000000..8bd26cebc
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-26480.rs
@@ -0,0 +1,29 @@
+extern "C" {
+ fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
+}
+
+#[inline(always)]
+fn size_of<T>(_: T) -> usize {
+ ::std::mem::size_of::<T>()
+}
+
+macro_rules! write {
+ ($arr:expr) => {{
+ #[allow(non_upper_case_globals)]
+ const stdout: i32 = 1;
+ unsafe {
+ write(stdout, $arr.as_ptr() as *const i8,
+ $arr.len() * size_of($arr[0])); //~ ERROR mismatched types
+ }
+ }}
+}
+
+macro_rules! cast {
+ ($x:expr) => ($x as ()) //~ ERROR non-primitive cast
+}
+
+fn main() {
+ let hello = ['H', 'e', 'y'];
+ write!(hello);
+ cast!(2);
+}
diff --git a/tests/ui/mismatched_types/issue-26480.stderr b/tests/ui/mismatched_types/issue-26480.stderr
new file mode 100644
index 000000000..ae10a0067
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-26480.stderr
@@ -0,0 +1,37 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-26480.rs:16:19
+ |
+LL | write(stdout, $arr.as_ptr() as *const i8,
+ | ----- arguments to this function are incorrect
+LL | $arr.len() * size_of($arr[0]));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `usize`
+...
+LL | write!(hello);
+ | ------------- in this macro invocation
+ |
+note: function defined here
+ --> $DIR/issue-26480.rs:2:8
+ |
+LL | fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
+ | ^^^^^
+ = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit
+ |
+LL | ($arr.len() * size_of($arr[0])).try_into().unwrap());
+ | + +++++++++++++++++++++
+
+error[E0605]: non-primitive cast: `{integer}` as `()`
+ --> $DIR/issue-26480.rs:22:19
+ |
+LL | ($x:expr) => ($x as ())
+ | ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+...
+LL | cast!(2);
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `cast` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0605.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-35030.rs b/tests/ui/mismatched_types/issue-35030.rs
new file mode 100644
index 000000000..91ea7ea80
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-35030.rs
@@ -0,0 +1,15 @@
+#![allow(non_camel_case_types)]
+
+trait Parser<T> {
+ fn parse(text: &str) -> Option<T>;
+}
+
+impl<bool> Parser<bool> for bool {
+ fn parse(text: &str) -> Option<bool> {
+ Some(true) //~ ERROR mismatched types
+ }
+}
+
+fn main() {
+ println!("{}", bool::parse("ok").unwrap_or(false));
+}
diff --git a/tests/ui/mismatched_types/issue-35030.stderr b/tests/ui/mismatched_types/issue-35030.stderr
new file mode 100644
index 000000000..de4e067fe
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-35030.stderr
@@ -0,0 +1,26 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-35030.rs:9:14
+ |
+LL | impl<bool> Parser<bool> for bool {
+ | ---- this type parameter
+LL | fn parse(text: &str) -> Option<bool> {
+LL | Some(true)
+ | ---- ^^^^ expected type parameter `bool`, found `bool`
+ | |
+ | arguments to this enum variant are incorrect
+ |
+ = note: expected type parameter `bool` (type parameter `bool`)
+ found type `bool` (`bool`)
+help: the type constructed contains `bool` due to the type of the argument passed
+ --> $DIR/issue-35030.rs:9:9
+ |
+LL | Some(true)
+ | ^^^^^----^
+ | |
+ | this argument influences the type of `Some`
+note: tuple variant defined here
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-36053-2.rs b/tests/ui/mismatched_types/issue-36053-2.rs
new file mode 100644
index 000000000..17d2292ba
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-36053-2.rs
@@ -0,0 +1,10 @@
+// Regression test for #36053. ICE was caused due to obligations
+// being added to a special, dedicated fulfillment cx during
+// a probe.
+
+use std::iter::once;
+fn main() {
+ once::<&str>("str").fuse().filter(|a: &str| true).count();
+ //~^ ERROR the method
+ //~| ERROR type mismatch in closure arguments
+}
diff --git a/tests/ui/mismatched_types/issue-36053-2.stderr b/tests/ui/mismatched_types/issue-36053-2.stderr
new file mode 100644
index 000000000..a6764a1dc
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-36053-2.stderr
@@ -0,0 +1,41 @@
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/issue-36053-2.rs:7:32
+ |
+LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
+ | ^^^^^^ --------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `for<'a> fn(&'a &str) -> _`
+ found closure signature `for<'a> fn(&'a str) -> _`
+note: required by a bound in `filter`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+help: consider borrowing the argument
+ |
+LL | once::<&str>("str").fuse().filter(|a: &&str| true).count();
+ | +
+
+error[E0599]: the method `count` exists for struct `Filter<Fuse<Once<&str>>, [closure@issue-36053-2.rs:7:39]>`, but its trait bounds were not satisfied
+ --> $DIR/issue-36053-2.rs:7:55
+ |
+LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
+ | --------- ^^^^^ method cannot be called due to unsatisfied trait bounds
+ | |
+ | doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
+ | doesn't satisfy `_: FnMut<(&&str,)>`
+ --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL
+ |
+ = note: doesn't satisfy `_: Iterator`
+ |
+ = note: the following trait bounds were not satisfied:
+ `<[closure@$DIR/issue-36053-2.rs:7:39: 7:48] as FnOnce<(&&str,)>>::Output = bool`
+ which is required by `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator`
+ `[closure@$DIR/issue-36053-2.rs:7:39: 7:48]: FnMut<(&&str,)>`
+ which is required by `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator`
+ `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator`
+ which is required by `&mut Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0599, E0631.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/tests/ui/mismatched_types/issue-38371-unfixable.rs b/tests/ui/mismatched_types/issue-38371-unfixable.rs
new file mode 100644
index 000000000..c4316bfdd
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-38371-unfixable.rs
@@ -0,0 +1,5 @@
+fn ugh(&[bar]: &u32) {} //~ ERROR expected an array or slice
+
+fn bgh(&&bar: u32) {} //~ ERROR mismatched types
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-38371-unfixable.stderr b/tests/ui/mismatched_types/issue-38371-unfixable.stderr
new file mode 100644
index 000000000..3c5e765ab
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-38371-unfixable.stderr
@@ -0,0 +1,21 @@
+error[E0529]: expected an array or slice, found `u32`
+ --> $DIR/issue-38371-unfixable.rs:1:9
+ |
+LL | fn ugh(&[bar]: &u32) {}
+ | ^^^^^ pattern cannot match with input type `u32`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-38371-unfixable.rs:3:8
+ |
+LL | fn bgh(&&bar: u32) {}
+ | ^^^^^ --- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0529.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-38371.fixed b/tests/ui/mismatched_types/issue-38371.fixed
new file mode 100644
index 000000000..0e20835be
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-38371.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+// see also issue-38371-unfixable.rs
+#![allow(dead_code)]
+
+#[derive(Copy, Clone)]
+struct Foo {}
+
+fn foo(_a: &Foo) {} //~ ERROR mismatched types
+
+fn bar(_a: Foo) {}
+
+fn qux(_a: &Foo) {}
+
+fn zar(&_a: &Foo) {}
+
+fn agh(&_a: &u32) {} //~ ERROR mismatched types
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-38371.rs b/tests/ui/mismatched_types/issue-38371.rs
new file mode 100644
index 000000000..fb9e4c173
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-38371.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+// see also issue-38371-unfixable.rs
+#![allow(dead_code)]
+
+#[derive(Copy, Clone)]
+struct Foo {}
+
+fn foo(&_a: Foo) {} //~ ERROR mismatched types
+
+fn bar(_a: Foo) {}
+
+fn qux(_a: &Foo) {}
+
+fn zar(&_a: &Foo) {}
+
+fn agh(&&_a: &u32) {} //~ ERROR mismatched types
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-38371.stderr b/tests/ui/mismatched_types/issue-38371.stderr
new file mode 100644
index 000000000..f43427f98
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-38371.stderr
@@ -0,0 +1,35 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-38371.rs:8:8
+ |
+LL | fn foo(&_a: Foo) {}
+ | ^^^ --- expected due to this
+ | |
+ | expected struct `Foo`, found reference
+ |
+ = note: expected struct `Foo`
+ found reference `&_`
+help: to take parameter `_a` by reference, move `&` to the type
+ |
+LL - fn foo(&_a: Foo) {}
+LL + fn foo(_a: &Foo) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/issue-38371.rs:16:9
+ |
+LL | fn agh(&&_a: &u32) {}
+ | ^^^ ---- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - fn agh(&&_a: &u32) {}
+LL + fn agh(&_a: &u32) {}
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/issue-47706-trait.rs b/tests/ui/mismatched_types/issue-47706-trait.rs
new file mode 100644
index 000000000..8fb4e0855
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-47706-trait.rs
@@ -0,0 +1,8 @@
+trait T {
+ fn f(&self, _: ()) {
+ None::<()>.map(Self::f);
+ }
+ //~^^ ERROR function is expected to take a single 0-tuple as argument
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-47706-trait.stderr b/tests/ui/mismatched_types/issue-47706-trait.stderr
new file mode 100644
index 000000000..a5f38dd53
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-47706-trait.stderr
@@ -0,0 +1,16 @@
+error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments
+ --> $DIR/issue-47706-trait.rs:3:24
+ |
+LL | fn f(&self, _: ()) {
+ | ------------------ takes 2 distinct arguments
+LL | None::<()>.map(Self::f);
+ | --- ^^^^^^^ expected function that takes a single 0-tuple as argument
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `Option::<T>::map`
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0593`.
diff --git a/tests/ui/mismatched_types/issue-47706.rs b/tests/ui/mismatched_types/issue-47706.rs
new file mode 100644
index 000000000..f47c1e694
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-47706.rs
@@ -0,0 +1,29 @@
+pub struct Foo {
+ foo: Option<i32>,
+}
+
+impl Foo {
+ pub fn new(foo: Option<i32>, _: ()) -> Foo {
+ Foo { foo }
+ }
+
+ pub fn map(self) -> Option<Foo> {
+ self.foo.map(Foo::new)
+ }
+ //~^^ ERROR function is expected to take 1 argument, but it takes 2 arguments [E0593]
+}
+
+enum Qux {
+ Bar(i32),
+}
+
+fn foo<F>(f: F)
+where
+ F: Fn(),
+{
+}
+
+fn main() {
+ foo(Qux::Bar);
+}
+//~^^ ERROR function is expected to take 0 arguments, but it takes 1 argument [E0593]
diff --git a/tests/ui/mismatched_types/issue-47706.stderr b/tests/ui/mismatched_types/issue-47706.stderr
new file mode 100644
index 000000000..d9d408844
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-47706.stderr
@@ -0,0 +1,37 @@
+error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
+ --> $DIR/issue-47706.rs:11:22
+ |
+LL | pub fn new(foo: Option<i32>, _: ()) -> Foo {
+ | ------------------------------------------ takes 2 arguments
+...
+LL | self.foo.map(Foo::new)
+ | --- ^^^^^^^^ expected function that takes 1 argument
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `Option::<T>::map`
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+
+error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
+ --> $DIR/issue-47706.rs:27:9
+ |
+LL | Bar(i32),
+ | --- takes 1 argument
+...
+LL | foo(Qux::Bar);
+ | --- ^^^^^^^^ expected function that takes 0 arguments
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-47706.rs:22:8
+ |
+LL | fn foo<F>(f: F)
+ | --- required by a bound in this
+LL | where
+LL | F: Fn(),
+ | ^^^^ required by this bound in `foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0593`.
diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs b/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs
new file mode 100644
index 000000000..c7842667d
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs
@@ -0,0 +1,29 @@
+// Regression test for issue #74918
+// Tests that we don't ICE after emitting an error
+
+struct ChunkingIterator<T, S: 'static + Iterator<Item = T>> {
+ source: S,
+}
+
+impl<T, S: Iterator<Item = T>> Iterator for ChunkingIterator<T, S> {
+ type Item = IteratorChunk<T, S>; //~ ERROR missing lifetime
+
+ fn next(&mut self) -> Option<IteratorChunk<T, S>> {
+ //~^ ERROR `impl` item signature doesn't match `trait` item signature
+ todo!()
+ }
+}
+
+struct IteratorChunk<'a, T, S: Iterator<Item = T>> {
+ source: &'a mut S,
+}
+
+impl<T, S: Iterator<Item = T>> Iterator for IteratorChunk<'_, T, S> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr
new file mode 100644
index 000000000..9ddea1629
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr
@@ -0,0 +1,28 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-74918-missing-lifetime.rs:9:30
+ |
+LL | type Item = IteratorChunk<T, S>;
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | type Item<'a> = IteratorChunk<'a, T, S>;
+ | ++++ +++
+
+error: `impl` item signature doesn't match `trait` item signature
+ --> $DIR/issue-74918-missing-lifetime.rs:11:5
+ |
+LL | fn next(&mut self) -> Option<IteratorChunk<T, S>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+ = note: expected `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, T, S>>`
+ |
+ = note: expected signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, T, S>>`
+ found signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
+ = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
+ = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/mismatched_types/issue-75361-mismatched-impl.rs b/tests/ui/mismatched_types/issue-75361-mismatched-impl.rs
new file mode 100644
index 000000000..441051447
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-75361-mismatched-impl.rs
@@ -0,0 +1,24 @@
+// Regresison test for issue #75361
+// Tests that we don't ICE on mismatched types with inference variables
+
+
+trait MyTrait {
+ type Item;
+}
+
+pub trait Graph {
+ type EdgeType;
+
+ fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
+}
+
+impl<T> Graph for T {
+ type EdgeType = T;
+
+ fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> { //~ ERROR `impl`
+ panic!()
+ }
+
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-75361-mismatched-impl.stderr b/tests/ui/mismatched_types/issue-75361-mismatched-impl.stderr
new file mode 100644
index 000000000..88416ba4b
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-75361-mismatched-impl.stderr
@@ -0,0 +1,19 @@
+error: `impl` item signature doesn't match `trait` item signature
+ --> $DIR/issue-75361-mismatched-impl.rs:18:3
+ |
+LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
+ | --------------------------------------------------------------------- expected `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + 'static)>`
+...
+LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
+ |
+ = note: expected signature `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + 'static)>`
+ found signature `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
+help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
+ --> $DIR/issue-75361-mismatched-impl.rs:12:55
+ |
+LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
+ | ^^^^ consider borrowing this type parameter in the trait
+
+error: aborting due to previous error
+
diff --git a/tests/ui/mismatched_types/issue-84976.rs b/tests/ui/mismatched_types/issue-84976.rs
new file mode 100644
index 000000000..db6fe0b45
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-84976.rs
@@ -0,0 +1,25 @@
+/* Checks whether primitive type names are formatted correctly in the
+ * error messages about mismatched types (#84976).
+ */
+
+fn foo(length: &u32) -> i32 {
+ 0
+}
+
+fn bar(length: &f32) -> f64 {
+ 0.0
+}
+
+fn main() {
+ let mut length = 0;
+ length = { foo(&length) };
+ //~^ ERROR mismatched types [E0308]
+ length = foo(&length);
+ //~^ ERROR mismatched types [E0308]
+
+ let mut float_length = 0.0;
+ float_length = { bar(&float_length) };
+ //~^ ERROR mismatched types [E0308]
+ float_length = bar(&float_length);
+ //~^ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/mismatched_types/issue-84976.stderr b/tests/ui/mismatched_types/issue-84976.stderr
new file mode 100644
index 000000000..9157566e3
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-84976.stderr
@@ -0,0 +1,38 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:15:16
+ |
+LL | length = { foo(&length) };
+ | ^^^^^^^^^^^^ expected `u32`, found `i32`
+ |
+help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
+ |
+LL | length = { foo(&length).try_into().unwrap() };
+ | ++++++++++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:17:14
+ |
+LL | let mut length = 0;
+ | - expected due to this value
+...
+LL | length = foo(&length);
+ | ^^^^^^^^^^^^ expected `u32`, found `i32`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:21:22
+ |
+LL | float_length = { bar(&float_length) };
+ | ^^^^^^^^^^^^^^^^^^ expected `f32`, found `f64`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:23:20
+ |
+LL | let mut float_length = 0.0;
+ | --- expected due to this value
+...
+LL | float_length = bar(&float_length);
+ | ^^^^^^^^^^^^^^^^^^ expected `f32`, found `f64`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/main.rs b/tests/ui/mismatched_types/main.rs
new file mode 100644
index 000000000..e2d09dc21
--- /dev/null
+++ b/tests/ui/mismatched_types/main.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let x: u32 = ( //~ ERROR mismatched types
+ );
+}
diff --git a/tests/ui/mismatched_types/main.stderr b/tests/ui/mismatched_types/main.stderr
new file mode 100644
index 000000000..a662741af
--- /dev/null
+++ b/tests/ui/mismatched_types/main.stderr
@@ -0,0 +1,13 @@
+error[E0308]: mismatched types
+ --> $DIR/main.rs:2:18
+ |
+LL | let x: u32 = (
+ | ____________---___^
+ | | |
+ | | expected due to this
+LL | | );
+ | |_____^ expected `u32`, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/method-help-unsatisfied-bound.rs b/tests/ui/mismatched_types/method-help-unsatisfied-bound.rs
new file mode 100644
index 000000000..6303c6e6a
--- /dev/null
+++ b/tests/ui/mismatched_types/method-help-unsatisfied-bound.rs
@@ -0,0 +1,7 @@
+struct Foo;
+
+fn main() {
+ let a: Result<(), Foo> = Ok(());
+ a.unwrap();
+ //~^ ERROR `Foo` doesn't implement `Debug`
+}
diff --git a/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr
new file mode 100644
index 000000000..d3b752507
--- /dev/null
+++ b/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr
@@ -0,0 +1,18 @@
+error[E0277]: `Foo` doesn't implement `Debug`
+ --> $DIR/method-help-unsatisfied-bound.rs:5:7
+ |
+LL | a.unwrap();
+ | ^^^^^^ `Foo` cannot be formatted using `{:?}`
+ |
+ = help: the trait `Debug` is not implemented for `Foo`
+ = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
+note: required by a bound in `Result::<T, E>::unwrap`
+ --> $SRC_DIR/core/src/result.rs:LL:COL
+help: consider annotating `Foo` with `#[derive(Debug)]`
+ |
+LL | #[derive(Debug)]
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.rs b/tests/ui/mismatched_types/non_zero_assigned_something.rs
new file mode 100644
index 000000000..d2adbe01c
--- /dev/null
+++ b/tests/ui/mismatched_types/non_zero_assigned_something.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let _: std::num::NonZeroU64 = 1;
+ //~^ ERROR mismatched types
+ //~| HELP consider calling `NonZeroU64::new`
+
+ let _: Option<std::num::NonZeroU64> = 1;
+ //~^ ERROR mismatched types
+ //~| HELP consider calling `NonZeroU64::new`
+}
diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.stderr b/tests/ui/mismatched_types/non_zero_assigned_something.stderr
new file mode 100644
index 000000000..d4b2c902f
--- /dev/null
+++ b/tests/ui/mismatched_types/non_zero_assigned_something.stderr
@@ -0,0 +1,31 @@
+error[E0308]: mismatched types
+ --> $DIR/non_zero_assigned_something.rs:2:35
+ |
+LL | let _: std::num::NonZeroU64 = 1;
+ | -------------------- ^ expected struct `NonZeroU64`, found integer
+ | |
+ | expected due to this
+ |
+help: consider calling `NonZeroU64::new`
+ |
+LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap();
+ | ++++++++++++++++ ++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/non_zero_assigned_something.rs:6:43
+ |
+LL | let _: Option<std::num::NonZeroU64> = 1;
+ | ---------------------------- ^ expected enum `Option`, found integer
+ | |
+ | expected due to this
+ |
+ = note: expected enum `Option<NonZeroU64>`
+ found type `{integer}`
+help: consider calling `NonZeroU64::new`
+ |
+LL | let _: Option<std::num::NonZeroU64> = NonZeroU64::new(1);
+ | ++++++++++++++++ +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/normalize-fn-sig.rs b/tests/ui/mismatched_types/normalize-fn-sig.rs
new file mode 100644
index 000000000..1a2093c44
--- /dev/null
+++ b/tests/ui/mismatched_types/normalize-fn-sig.rs
@@ -0,0 +1,16 @@
+trait Foo {
+ type Bar;
+}
+
+impl<T> Foo for T {
+ type Bar = i32;
+}
+
+fn foo<T>(_: <T as Foo>::Bar, _: &'static <T as Foo>::Bar) {}
+
+fn needs_i32_ref_fn(_: fn(&'static i32, i32)) {}
+
+fn main() {
+ needs_i32_ref_fn(foo::<()>);
+ //~^ ERROR mismatched types
+}
diff --git a/tests/ui/mismatched_types/normalize-fn-sig.stderr b/tests/ui/mismatched_types/normalize-fn-sig.stderr
new file mode 100644
index 000000000..6c55f29c5
--- /dev/null
+++ b/tests/ui/mismatched_types/normalize-fn-sig.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/normalize-fn-sig.rs:14:22
+ |
+LL | needs_i32_ref_fn(foo::<()>);
+ | ---------------- ^^^^^^^^^ expected `&i32`, found `i32`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn pointer `fn(&'static i32, i32)`
+ found fn item `fn(i32, &'static i32) {foo::<()>}`
+note: function defined here
+ --> $DIR/normalize-fn-sig.rs:11:4
+ |
+LL | fn needs_i32_ref_fn(_: fn(&'static i32, i32)) {}
+ | ^^^^^^^^^^^^^^^^ ------------------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/numeric-literal-cast.rs b/tests/ui/mismatched_types/numeric-literal-cast.rs
new file mode 100644
index 000000000..69cfe262f
--- /dev/null
+++ b/tests/ui/mismatched_types/numeric-literal-cast.rs
@@ -0,0 +1,12 @@
+fn foo(_: u16) {}
+fn foo1(_: f64) {}
+fn foo2(_: i32) {}
+
+fn main() {
+ foo(1u8);
+//~^ ERROR mismatched types
+ foo1(2f32);
+//~^ ERROR mismatched types
+ foo2(3i16);
+//~^ ERROR mismatched types
+}
diff --git a/tests/ui/mismatched_types/numeric-literal-cast.stderr b/tests/ui/mismatched_types/numeric-literal-cast.stderr
new file mode 100644
index 000000000..fcf3eccbc
--- /dev/null
+++ b/tests/ui/mismatched_types/numeric-literal-cast.stderr
@@ -0,0 +1,57 @@
+error[E0308]: mismatched types
+ --> $DIR/numeric-literal-cast.rs:6:9
+ |
+LL | foo(1u8);
+ | --- ^^^ expected `u16`, found `u8`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/numeric-literal-cast.rs:1:4
+ |
+LL | fn foo(_: u16) {}
+ | ^^^ ------
+help: change the type of the numeric literal from `u8` to `u16`
+ |
+LL | foo(1u16);
+ | ~~~
+
+error[E0308]: mismatched types
+ --> $DIR/numeric-literal-cast.rs:8:10
+ |
+LL | foo1(2f32);
+ | ---- ^^^^ expected `f64`, found `f32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/numeric-literal-cast.rs:2:4
+ |
+LL | fn foo1(_: f64) {}
+ | ^^^^ ------
+help: change the type of the numeric literal from `f32` to `f64`
+ |
+LL | foo1(2f64);
+ | ~~~
+
+error[E0308]: mismatched types
+ --> $DIR/numeric-literal-cast.rs:10:10
+ |
+LL | foo2(3i16);
+ | ---- ^^^^ expected `i32`, found `i16`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/numeric-literal-cast.rs:3:4
+ |
+LL | fn foo2(_: i32) {}
+ | ^^^^ ------
+help: change the type of the numeric literal from `i16` to `i32`
+ |
+LL | foo2(3i32);
+ | ~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.rs b/tests/ui/mismatched_types/overloaded-calls-bad.rs
new file mode 100644
index 000000000..5b1804d82
--- /dev/null
+++ b/tests/ui/mismatched_types/overloaded-calls-bad.rs
@@ -0,0 +1,42 @@
+#![feature(fn_traits, unboxed_closures)]
+
+use std::ops::FnMut;
+
+struct S {
+ x: isize,
+ y: isize,
+}
+
+impl FnMut<(isize,)> for S {
+ extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
+ self.x * self.y * z
+ }
+}
+
+impl FnOnce<(isize,)> for S {
+ type Output = isize;
+ extern "rust-call" fn call_once(mut self, (z,): (isize,)) -> isize {
+ self.call_mut((z,))
+ }
+}
+
+struct F;
+
+impl FnOnce<(i32,)> for F {
+ type Output = ();
+
+ extern "rust-call" fn call_once(self, args: (i32,)) -> Self::Output {}
+}
+
+fn main() {
+ let mut s = S { x: 3, y: 3 };
+ let ans = s("what");
+ //~^ ERROR mismatched types
+ let ans = s();
+ //~^ ERROR function takes 1 argument but 0 arguments were supplied
+ let ans = s("burma", "shave");
+ //~^ ERROR function takes 1 argument but 2 arguments were supplied
+
+ F("");
+ //~^ ERROR mismatched types
+}
diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.stderr b/tests/ui/mismatched_types/overloaded-calls-bad.stderr
new file mode 100644
index 000000000..3a895acbd
--- /dev/null
+++ b/tests/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -0,0 +1,66 @@
+error[E0308]: mismatched types
+ --> $DIR/overloaded-calls-bad.rs:33:17
+ |
+LL | let ans = s("what");
+ | - ^^^^^^ expected `isize`, found `&str`
+ | |
+ | arguments to this function are incorrect
+ |
+note: implementation defined here
+ --> $DIR/overloaded-calls-bad.rs:10:1
+ |
+LL | impl FnMut<(isize,)> for S {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0057]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/overloaded-calls-bad.rs:35:15
+ |
+LL | let ans = s();
+ | ^-- an argument of type `isize` is missing
+ |
+note: implementation defined here
+ --> $DIR/overloaded-calls-bad.rs:10:1
+ |
+LL | impl FnMut<(isize,)> for S {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: provide the argument
+ |
+LL | let ans = s(/* isize */);
+ | ~~~~~~~~~~~~~
+
+error[E0057]: this function takes 1 argument but 2 arguments were supplied
+ --> $DIR/overloaded-calls-bad.rs:37:15
+ |
+LL | let ans = s("burma", "shave");
+ | ^ ------- ------- argument of type `&'static str` unexpected
+ | |
+ | expected `isize`, found `&str`
+ |
+note: implementation defined here
+ --> $DIR/overloaded-calls-bad.rs:10:1
+ |
+LL | impl FnMut<(isize,)> for S {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: remove the extra argument
+ |
+LL | let ans = s(/* isize */);
+ | ~~~~~~~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/overloaded-calls-bad.rs:40:7
+ |
+LL | F("");
+ | - ^^ expected `i32`, found `&str`
+ | |
+ | arguments to this struct are incorrect
+ |
+note: implementation defined here
+ --> $DIR/overloaded-calls-bad.rs:25:1
+ |
+LL | impl FnOnce<(i32,)> for F {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0057, E0308.
+For more information about an error, try `rustc --explain E0057`.
diff --git a/tests/ui/mismatched_types/recovered-block.rs b/tests/ui/mismatched_types/recovered-block.rs
new file mode 100644
index 000000000..b230b47d3
--- /dev/null
+++ b/tests/ui/mismatched_types/recovered-block.rs
@@ -0,0 +1,21 @@
+use std::env;
+
+pub struct Foo {
+ text: String
+}
+
+pub fn foo() -> Foo {
+ let args: Vec<String> = env::args().collect();
+ let text = args[1].clone();
+
+ pub Foo { text }
+}
+//~^^ ERROR missing `struct` for struct definition
+
+pub fn bar() -> Foo {
+ fn
+ Foo { text: "".to_string() }
+}
+//~^^ ERROR expected one of `(` or `<`, found `{`
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/recovered-block.stderr b/tests/ui/mismatched_types/recovered-block.stderr
new file mode 100644
index 000000000..f275321ab
--- /dev/null
+++ b/tests/ui/mismatched_types/recovered-block.stderr
@@ -0,0 +1,19 @@
+error: missing `struct` for struct definition
+ --> $DIR/recovered-block.rs:11:8
+ |
+LL | pub Foo { text }
+ | ^
+ |
+help: add `struct` here to parse `Foo` as a public struct
+ |
+LL | pub struct Foo { text }
+ | ++++++
+
+error: expected one of `(` or `<`, found `{`
+ --> $DIR/recovered-block.rs:17:9
+ |
+LL | Foo { text: "".to_string() }
+ | ^ expected one of `(` or `<`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/mismatched_types/ref-pat-suggestions.fixed b/tests/ui/mismatched_types/ref-pat-suggestions.fixed
new file mode 100644
index 000000000..d50acd1ac
--- /dev/null
+++ b/tests/ui/mismatched_types/ref-pat-suggestions.fixed
@@ -0,0 +1,37 @@
+// run-rustfix
+
+fn _f0(_a: &u32) {} //~ ERROR mismatched types
+fn _f1(_a: &mut u32) {} //~ ERROR mismatched types
+fn _f2(&_a: &u32) {} //~ ERROR mismatched types
+fn _f3(&mut _a: &mut u32) {} //~ ERROR mismatched types
+fn _f4(&_a: &u32) {} //~ ERROR mismatched types
+fn _f5(&mut _a: &mut u32) {} //~ ERROR mismatched types
+
+fn main() {
+ let _: fn(u32) = |_a| (); //~ ERROR mismatched types
+ let _: fn(u32) = |_a| (); //~ ERROR mismatched types
+ let _: fn(&u32) = |&_a| (); //~ ERROR mismatched types
+ let _: fn(&mut u32) = |&mut _a| (); //~ ERROR mismatched types
+ let _: fn(&u32) = |&_a| (); //~ ERROR mismatched types
+ let _: fn(&mut u32) = |&mut _a| (); //~ ERROR mismatched types
+
+ let _ = |_a: &u32| (); //~ ERROR mismatched types
+ let _ = |_a: &mut u32| (); //~ ERROR mismatched types
+ let _ = |&_a: &u32| (); //~ ERROR mismatched types
+ let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
+ let _ = |&_a: &u32| (); //~ ERROR mismatched types
+ let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
+
+ #[allow(unused_mut)]
+ {
+ struct S(u8);
+
+ let mut _a = 0; //~ ERROR mismatched types
+ let S(_b) = S(0); //~ ERROR mismatched types
+ let (_c,) = (0,); //~ ERROR mismatched types
+
+ match 0 {
+ _d => {} //~ ERROR mismatched types
+ }
+ }
+}
diff --git a/tests/ui/mismatched_types/ref-pat-suggestions.rs b/tests/ui/mismatched_types/ref-pat-suggestions.rs
new file mode 100644
index 000000000..1a77f6876
--- /dev/null
+++ b/tests/ui/mismatched_types/ref-pat-suggestions.rs
@@ -0,0 +1,37 @@
+// run-rustfix
+
+fn _f0(&_a: u32) {} //~ ERROR mismatched types
+fn _f1(&mut _a: u32) {} //~ ERROR mismatched types
+fn _f2(&&_a: &u32) {} //~ ERROR mismatched types
+fn _f3(&mut &_a: &mut u32) {} //~ ERROR mismatched types
+fn _f4(&&mut _a: &u32) {} //~ ERROR mismatched types
+fn _f5(&mut &mut _a: &mut u32) {} //~ ERROR mismatched types
+
+fn main() {
+ let _: fn(u32) = |&_a| (); //~ ERROR mismatched types
+ let _: fn(u32) = |&mut _a| (); //~ ERROR mismatched types
+ let _: fn(&u32) = |&&_a| (); //~ ERROR mismatched types
+ let _: fn(&mut u32) = |&mut &_a| (); //~ ERROR mismatched types
+ let _: fn(&u32) = |&&mut _a| (); //~ ERROR mismatched types
+ let _: fn(&mut u32) = |&mut &mut _a| (); //~ ERROR mismatched types
+
+ let _ = |&_a: u32| (); //~ ERROR mismatched types
+ let _ = |&mut _a: u32| (); //~ ERROR mismatched types
+ let _ = |&&_a: &u32| (); //~ ERROR mismatched types
+ let _ = |&mut &_a: &mut u32| (); //~ ERROR mismatched types
+ let _ = |&&mut _a: &u32| (); //~ ERROR mismatched types
+ let _ = |&mut &mut _a: &mut u32| (); //~ ERROR mismatched types
+
+ #[allow(unused_mut)]
+ {
+ struct S(u8);
+
+ let &mut _a = 0; //~ ERROR mismatched types
+ let S(&mut _b) = S(0); //~ ERROR mismatched types
+ let (&mut _c,) = (0,); //~ ERROR mismatched types
+
+ match 0 {
+ &mut _d => {} //~ ERROR mismatched types
+ }
+ }
+}
diff --git a/tests/ui/mismatched_types/ref-pat-suggestions.stderr b/tests/ui/mismatched_types/ref-pat-suggestions.stderr
new file mode 100644
index 000000000..63eaa3930
--- /dev/null
+++ b/tests/ui/mismatched_types/ref-pat-suggestions.stderr
@@ -0,0 +1,386 @@
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:3:8
+ |
+LL | fn _f0(&_a: u32) {}
+ | ^^^ --- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: to take parameter `_a` by reference, move `&` to the type
+ |
+LL - fn _f0(&_a: u32) {}
+LL + fn _f0(_a: &u32) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:4:8
+ |
+LL | fn _f1(&mut _a: u32) {}
+ | ^^^^^^^ --- expected due to this
+ | |
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+note: to declare a mutable parameter use: `mut _a`
+ --> $DIR/ref-pat-suggestions.rs:4:8
+ |
+LL | fn _f1(&mut _a: u32) {}
+ | ^^^^^^^
+help: to take parameter `_a` by reference, move `&mut` to the type
+ |
+LL - fn _f1(&mut _a: u32) {}
+LL + fn _f1(_a: &mut u32) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:5:9
+ |
+LL | fn _f2(&&_a: &u32) {}
+ | ^^^ ---- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - fn _f2(&&_a: &u32) {}
+LL + fn _f2(&_a: &u32) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:6:13
+ |
+LL | fn _f3(&mut &_a: &mut u32) {}
+ | ^^^ -------- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - fn _f3(&mut &_a: &mut u32) {}
+LL + fn _f3(&mut _a: &mut u32) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:7:9
+ |
+LL | fn _f4(&&mut _a: &u32) {}
+ | ^^^^^^^ ---- expected due to this
+ | |
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+ |
+LL - fn _f4(&&mut _a: &u32) {}
+LL + fn _f4(&_a: &u32) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:8:13
+ |
+LL | fn _f5(&mut &mut _a: &mut u32) {}
+ | ^^^^^^^ -------- expected due to this
+ | |
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+ |
+LL - fn _f5(&mut &mut _a: &mut u32) {}
+LL + fn _f5(&mut _a: &mut u32) {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:11:23
+ |
+LL | let _: fn(u32) = |&_a| ();
+ | ^--
+ | ||
+ | |expected due to this
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - let _: fn(u32) = |&_a| ();
+LL + let _: fn(u32) = |_a| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:12:23
+ |
+LL | let _: fn(u32) = |&mut _a| ();
+ | ^^^^^--
+ | | |
+ | | expected due to this
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+note: to declare a mutable parameter use: `mut _a`
+ --> $DIR/ref-pat-suggestions.rs:12:23
+ |
+LL | let _: fn(u32) = |&mut _a| ();
+ | ^^^^^^^
+help: consider removing `&mut` from the pattern
+ |
+LL - let _: fn(u32) = |&mut _a| ();
+LL + let _: fn(u32) = |_a| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:13:25
+ |
+LL | let _: fn(&u32) = |&&_a| ();
+ | ^--
+ | ||
+ | |expected due to this
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - let _: fn(&u32) = |&&_a| ();
+LL + let _: fn(&u32) = |&_a| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:14:33
+ |
+LL | let _: fn(&mut u32) = |&mut &_a| ();
+ | ^--
+ | ||
+ | |expected due to this
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - let _: fn(&mut u32) = |&mut &_a| ();
+LL + let _: fn(&mut u32) = |&mut _a| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:15:25
+ |
+LL | let _: fn(&u32) = |&&mut _a| ();
+ | ^^^^^--
+ | | |
+ | | expected due to this
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+ |
+LL - let _: fn(&u32) = |&&mut _a| ();
+LL + let _: fn(&u32) = |&_a| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:16:33
+ |
+LL | let _: fn(&mut u32) = |&mut &mut _a| ();
+ | ^^^^^--
+ | | |
+ | | expected due to this
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+ |
+LL - let _: fn(&mut u32) = |&mut &mut _a| ();
+LL + let _: fn(&mut u32) = |&mut _a| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:18:14
+ |
+LL | let _ = |&_a: u32| ();
+ | ^^^ --- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: to take parameter `_a` by reference, move `&` to the type
+ |
+LL - let _ = |&_a: u32| ();
+LL + let _ = |_a: &u32| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:19:14
+ |
+LL | let _ = |&mut _a: u32| ();
+ | ^^^^^^^ --- expected due to this
+ | |
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+note: to declare a mutable parameter use: `mut _a`
+ --> $DIR/ref-pat-suggestions.rs:19:14
+ |
+LL | let _ = |&mut _a: u32| ();
+ | ^^^^^^^
+help: to take parameter `_a` by reference, move `&mut` to the type
+ |
+LL - let _ = |&mut _a: u32| ();
+LL + let _ = |_a: &mut u32| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:20:15
+ |
+LL | let _ = |&&_a: &u32| ();
+ | ^^^ ---- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - let _ = |&&_a: &u32| ();
+LL + let _ = |&_a: &u32| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:21:19
+ |
+LL | let _ = |&mut &_a: &mut u32| ();
+ | ^^^ -------- expected due to this
+ | |
+ | expected `u32`, found reference
+ |
+ = note: expected type `u32`
+ found reference `&_`
+help: consider removing `&` from the pattern
+ |
+LL - let _ = |&mut &_a: &mut u32| ();
+LL + let _ = |&mut _a: &mut u32| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:22:15
+ |
+LL | let _ = |&&mut _a: &u32| ();
+ | ^^^^^^^ ---- expected due to this
+ | |
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+ |
+LL - let _ = |&&mut _a: &u32| ();
+LL + let _ = |&_a: &u32| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:23:19
+ |
+LL | let _ = |&mut &mut _a: &mut u32| ();
+ | ^^^^^^^ -------- expected due to this
+ | |
+ | expected `u32`, found `&mut _`
+ |
+ = note: expected type `u32`
+ found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+ |
+LL - let _ = |&mut &mut _a: &mut u32| ();
+LL + let _ = |&mut _a: &mut u32| ();
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:29:13
+ |
+LL | let &mut _a = 0;
+ | ^^^^^^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found `&mut _`
+ | help: to declare a mutable variable use: `mut _a`
+ |
+ = note: expected type `{integer}`
+ found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:30:15
+ |
+LL | let S(&mut _b) = S(0);
+ | ^^^^^^^ ---- this expression has type `S`
+ | |
+ | expected `u8`, found `&mut _`
+ |
+ = note: expected type `u8`
+ found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut _b`
+ --> $DIR/ref-pat-suggestions.rs:30:15
+ |
+LL | let S(&mut _b) = S(0);
+ | ^^^^^^^
+help: consider removing `&mut` from the pattern
+ |
+LL | let S(_b) = S(0);
+ | ~~
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:31:14
+ |
+LL | let (&mut _c,) = (0,);
+ | ^^^^^^^ ---- this expression has type `({integer},)`
+ | |
+ | expected integer, found `&mut _`
+ |
+ = note: expected type `{integer}`
+ found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut _c`
+ --> $DIR/ref-pat-suggestions.rs:31:14
+ |
+LL | let (&mut _c,) = (0,);
+ | ^^^^^^^
+help: consider removing `&mut` from the pattern
+ |
+LL - let (&mut _c,) = (0,);
+LL + let (_c,) = (0,);
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/ref-pat-suggestions.rs:34:13
+ |
+LL | match 0 {
+ | - this expression has type `{integer}`
+LL | &mut _d => {}
+ | ^^^^^^^ expected integer, found `&mut _`
+ |
+ = note: expected type `{integer}`
+ found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut _d`
+ --> $DIR/ref-pat-suggestions.rs:34:13
+ |
+LL | &mut _d => {}
+ | ^^^^^^^
+help: consider removing `&mut` from the pattern
+ |
+LL - &mut _d => {}
+LL + _d => {}
+ |
+
+error: aborting due to 22 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/show_module.rs b/tests/ui/mismatched_types/show_module.rs
new file mode 100644
index 000000000..61550b887
--- /dev/null
+++ b/tests/ui/mismatched_types/show_module.rs
@@ -0,0 +1,18 @@
+pub mod blah {
+ pub mod baz {
+ pub struct Foo;
+ }
+}
+
+pub mod meh {
+ pub struct Foo;
+}
+
+pub type Foo = blah::baz::Foo;
+
+fn foo() -> Foo {
+ meh::Foo
+ //~^ ERROR mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/show_module.stderr b/tests/ui/mismatched_types/show_module.stderr
new file mode 100644
index 000000000..5e48e0955
--- /dev/null
+++ b/tests/ui/mismatched_types/show_module.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+ --> $DIR/show_module.rs:14:5
+ |
+LL | fn foo() -> Foo {
+ | --- expected `baz::Foo` because of return type
+LL | meh::Foo
+ | ^^^^^^^^ expected struct `baz::Foo`, found struct `meh::Foo`
+ |
+ = note: struct `meh::Foo` and struct `baz::Foo` have similar names, but are actually distinct types
+note: struct `meh::Foo` is defined in module `crate::meh` of the current crate
+ --> $DIR/show_module.rs:8:5
+ |
+LL | pub struct Foo;
+ | ^^^^^^^^^^^^^^
+note: struct `baz::Foo` is defined in module `crate::blah::baz` of the current crate
+ --> $DIR/show_module.rs:3:9
+ |
+LL | pub struct Foo;
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/similar_paths.rs b/tests/ui/mismatched_types/similar_paths.rs
new file mode 100644
index 000000000..4b9157f39
--- /dev/null
+++ b/tests/ui/mismatched_types/similar_paths.rs
@@ -0,0 +1,11 @@
+enum Option<T> {
+ Some(T),
+ None,
+}
+
+pub fn foo() -> Option<u8> {
+ Some(42_u8)
+ //~^ ERROR mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/similar_paths.stderr b/tests/ui/mismatched_types/similar_paths.stderr
new file mode 100644
index 000000000..46a383325
--- /dev/null
+++ b/tests/ui/mismatched_types/similar_paths.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/similar_paths.rs:7:5
+ |
+LL | pub fn foo() -> Option<u8> {
+ | ---------- expected `Option<u8>` because of return type
+LL | Some(42_u8)
+ | ^^^^^^^^^^^ expected enum `Option`, found enum `std::option::Option`
+ |
+ = note: enum `std::option::Option` and enum `Option` have similar names, but are actually distinct types
+note: enum `std::option::Option` is defined in crate `core`
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+note: enum `Option` is defined in the current crate
+ --> $DIR/similar_paths.rs:1:1
+ |
+LL | enum Option<T> {
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/similar_paths_primitive.rs b/tests/ui/mismatched_types/similar_paths_primitive.rs
new file mode 100644
index 000000000..8f5b7cce4
--- /dev/null
+++ b/tests/ui/mismatched_types/similar_paths_primitive.rs
@@ -0,0 +1,10 @@
+#![allow(non_camel_case_types)]
+
+struct bool;
+
+fn foo(_: bool) {}
+
+fn main() {
+ foo(true);
+ //~^ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/mismatched_types/similar_paths_primitive.stderr b/tests/ui/mismatched_types/similar_paths_primitive.stderr
new file mode 100644
index 000000000..8a2f73945
--- /dev/null
+++ b/tests/ui/mismatched_types/similar_paths_primitive.stderr
@@ -0,0 +1,24 @@
+error[E0308]: mismatched types
+ --> $DIR/similar_paths_primitive.rs:8:9
+ |
+LL | foo(true);
+ | --- ^^^^ expected struct `bool`, found `bool`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: bool and struct `bool` have similar names, but are actually distinct types
+ = note: bool is a primitive defined by the language
+note: struct `bool` is defined in the current crate
+ --> $DIR/similar_paths_primitive.rs:3:1
+ |
+LL | struct bool;
+ | ^^^^^^^^^^^
+note: function defined here
+ --> $DIR/similar_paths_primitive.rs:5:4
+ |
+LL | fn foo(_: bool) {}
+ | ^^^ -------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed b/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed
new file mode 100644
index 000000000..56f93cfbf
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.fixed
@@ -0,0 +1,21 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+fn main() {
+ enum Blah {
+ A(isize, isize, usize),
+ B(isize, usize),
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, ref y) | Blah::B(x, ref y) => {}
+ //~^ ERROR mismatched types
+ //~| ERROR variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, y) | Blah::B(x, y) => {}
+ //~^ ERROR mismatched types
+ //~| variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+}
diff --git a/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs b/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs
new file mode 100644
index 000000000..0c33f99a4
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.rs
@@ -0,0 +1,21 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+fn main() {
+ enum Blah {
+ A(isize, isize, usize),
+ B(isize, usize),
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, ref y) | Blah::B(x, y) => {}
+ //~^ ERROR mismatched types
+ //~| ERROR variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+
+ match Blah::A(1, 1, 2) {
+ Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+ //~^ ERROR mismatched types
+ //~| variable `y` is bound inconsistently across alternatives separated by `|`
+ }
+}
diff --git a/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr b/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr
new file mode 100644
index 000000000..e8357f9a3
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-adding-or-removing-ref-for-binding-pattern.stderr
@@ -0,0 +1,49 @@
+error[E0409]: variable `y` is bound inconsistently across alternatives separated by `|`
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:11:43
+ |
+LL | Blah::A(_, x, ref y) | Blah::B(x, y) => {}
+ | - first binding ^ bound in different ways
+
+error[E0409]: variable `y` is bound inconsistently across alternatives separated by `|`
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:17:43
+ |
+LL | Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+ | - first binding ^ bound in different ways
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:11:43
+ |
+LL | match Blah::A(1, 1, 2) {
+ | ---------------- this expression has type `Blah`
+LL | Blah::A(_, x, ref y) | Blah::B(x, y) => {}
+ | ----- ^ expected `&usize`, found `usize`
+ | |
+ | first introduced with type `&usize` here
+ |
+ = note: in the same arm, a binding must have the same type in all alternatives
+help: consider adding `ref`
+ |
+LL | Blah::A(_, x, ref y) | Blah::B(x, ref y) => {}
+ | +++
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-adding-or-removing-ref-for-binding-pattern.rs:17:39
+ |
+LL | match Blah::A(1, 1, 2) {
+ | ---------------- this expression has type `Blah`
+LL | Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+ | - ^^^^^ expected `usize`, found `&usize`
+ | |
+ | first introduced with type `usize` here
+ |
+ = note: in the same arm, a binding must have the same type in all alternatives
+help: consider removing `ref`
+ |
+LL - Blah::A(_, x, y) | Blah::B(x, ref y) => {}
+LL + Blah::A(_, x, y) | Blah::B(x, y) => {}
+ |
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0409.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed b/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed
new file mode 100644
index 000000000..f30feaed0
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+struct S;
+struct Y;
+
+trait Trait {}
+
+impl Trait for S {}
+impl Trait for Y {}
+
+fn foo() -> Box<dyn Trait> {
+ if true {
+ Box::new(S)
+ } else {
+ Box::new(Y) //~ ERROR `if` and `else` have incompatible types
+ }
+}
+
+fn bar() -> Box<dyn Trait> {
+ match true {
+ true => Box::new(S),
+ false => Box::new(Y), //~ ERROR `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs b/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs
new file mode 100644
index 000000000..2bd8146e2
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+struct S;
+struct Y;
+
+trait Trait {}
+
+impl Trait for S {}
+impl Trait for Y {}
+
+fn foo() -> impl Trait {
+ if true {
+ S
+ } else {
+ Y //~ ERROR `if` and `else` have incompatible types
+ }
+}
+
+fn bar() -> impl Trait {
+ match true {
+ true => S,
+ false => Y, //~ ERROR `match` arms have incompatible types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr b/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr
new file mode 100644
index 000000000..f58b9c3ec
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-boxed-trait-objects-instead-of-impl-trait.stderr
@@ -0,0 +1,47 @@
+error[E0308]: `if` and `else` have incompatible types
+ --> $DIR/suggest-boxed-trait-objects-instead-of-impl-trait.rs:17:9
+ |
+LL | / if true {
+LL | | S
+ | | - expected because of this
+LL | | } else {
+LL | | Y
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `if` and `else` have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn foo() -> Box<dyn Trait> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ Box::new(S)
+LL | } else {
+LL ~ Box::new(Y)
+ |
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/suggest-boxed-trait-objects-instead-of-impl-trait.rs:24:18
+ |
+LL | / match true {
+LL | | true => S,
+ | | - this is found to be of type `S`
+LL | | false => Y,
+ | | ^ expected struct `S`, found struct `Y`
+LL | | }
+ | |_____- `match` arms have incompatible types
+ |
+help: you could change the return type to be a boxed trait object
+ |
+LL | fn bar() -> Box<dyn Trait> {
+ | ~~~~~~~ +
+help: if you change the return type to expect trait objects, box the returned expressions
+ |
+LL ~ true => Box::new(S),
+LL ~ false => Box::new(Y),
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.fixed b/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.fixed
new file mode 100644
index 000000000..63b65ab20
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.fixed
@@ -0,0 +1,17 @@
+// run-rustfix
+
+macro_rules! my_wrapper {
+ ($expr:expr) => { MyWrapper($expr) }
+}
+
+pub struct MyWrapper(u32);
+
+fn main() {
+ let value = MyWrapper(123);
+ some_fn(value); //~ ERROR mismatched types
+ some_fn(my_wrapper!(123)); //~ ERROR mismatched types
+}
+
+fn some_fn(wrapped: MyWrapper) {
+ drop(wrapped);
+}
diff --git a/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.rs b/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.rs
new file mode 100644
index 000000000..2ab4e3955
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.rs
@@ -0,0 +1,17 @@
+// run-rustfix
+
+macro_rules! my_wrapper {
+ ($expr:expr) => { MyWrapper($expr) }
+}
+
+pub struct MyWrapper(u32);
+
+fn main() {
+ let value = MyWrapper(123);
+ some_fn(value.0); //~ ERROR mismatched types
+ some_fn(my_wrapper!(123).0); //~ ERROR mismatched types
+}
+
+fn some_fn(wrapped: MyWrapper) {
+ drop(wrapped);
+}
diff --git a/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.stderr b/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.stderr
new file mode 100644
index 000000000..35871afb5
--- /dev/null
+++ b/tests/ui/mismatched_types/suggest-removing-tuple-struct-field.stderr
@@ -0,0 +1,41 @@
+error[E0308]: mismatched types
+ --> $DIR/suggest-removing-tuple-struct-field.rs:11:13
+ |
+LL | some_fn(value.0);
+ | ------- ^^^^^^^ expected struct `MyWrapper`, found `u32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/suggest-removing-tuple-struct-field.rs:15:4
+ |
+LL | fn some_fn(wrapped: MyWrapper) {
+ | ^^^^^^^ ------------------
+help: consider removing the tuple struct field `0`
+ |
+LL - some_fn(value.0);
+LL + some_fn(value);
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-removing-tuple-struct-field.rs:12:13
+ |
+LL | some_fn(my_wrapper!(123).0);
+ | ------- ^^^^^^^^^^^^^^^^^^ expected struct `MyWrapper`, found `u32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/suggest-removing-tuple-struct-field.rs:15:4
+ |
+LL | fn some_fn(wrapped: MyWrapper) {
+ | ^^^^^^^ ------------------
+help: consider removing the tuple struct field `0`
+ |
+LL - some_fn(my_wrapper!(123).0);
+LL + some_fn(my_wrapper!(123));
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/trait-bounds-cant-coerce.rs b/tests/ui/mismatched_types/trait-bounds-cant-coerce.rs
new file mode 100644
index 000000000..882533992
--- /dev/null
+++ b/tests/ui/mismatched_types/trait-bounds-cant-coerce.rs
@@ -0,0 +1,16 @@
+trait Foo {
+ fn dummy(&self) { }
+}
+
+fn a(_x: Box<dyn Foo + Send>) {
+}
+
+fn c(x: Box<dyn Foo + Sync + Send>) {
+ a(x);
+}
+
+fn d(x: Box<dyn Foo>) {
+ a(x); //~ ERROR mismatched types [E0308]
+}
+
+fn main() { }
diff --git a/tests/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/tests/ui/mismatched_types/trait-bounds-cant-coerce.stderr
new file mode 100644
index 000000000..80aef7fcb
--- /dev/null
+++ b/tests/ui/mismatched_types/trait-bounds-cant-coerce.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/trait-bounds-cant-coerce.rs:13:7
+ |
+LL | a(x);
+ | - ^ expected trait `Foo + Send`, found trait `Foo`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Box<(dyn Foo + Send + 'static)>`
+ found struct `Box<(dyn Foo + 'static)>`
+note: function defined here
+ --> $DIR/trait-bounds-cant-coerce.rs:5:4
+ |
+LL | fn a(_x: Box<dyn Foo + Send>) {
+ | ^ -----------------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.rs b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.rs
new file mode 100644
index 000000000..ba206b860
--- /dev/null
+++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.rs
@@ -0,0 +1,14 @@
+trait Foo {
+ fn foo(x: u16);
+ fn bar(&mut self, bar: &mut Bar);
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ fn foo(x: i16) { } //~ ERROR incompatible type
+ fn bar(&mut self, bar: &Bar) { } //~ ERROR incompatible type
+}
+
+fn main() {
+}
diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
new file mode 100644
index 000000000..6e7bf5eb4
--- /dev/null
+++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -0,0 +1,37 @@
+error[E0053]: method `foo` has an incompatible type for trait
+ --> $DIR/trait-impl-fn-incompatibility.rs:9:15
+ |
+LL | fn foo(x: i16) { }
+ | ^^^
+ | |
+ | expected `u16`, found `i16`
+ | help: change the parameter type to match the trait: `u16`
+ |
+note: type in trait
+ --> $DIR/trait-impl-fn-incompatibility.rs:2:15
+ |
+LL | fn foo(x: u16);
+ | ^^^
+ = note: expected signature `fn(u16)`
+ found signature `fn(i16)`
+
+error[E0053]: method `bar` has an incompatible type for trait
+ --> $DIR/trait-impl-fn-incompatibility.rs:10:28
+ |
+LL | fn bar(&mut self, bar: &Bar) { }
+ | ^^^^
+ | |
+ | types differ in mutability
+ | help: change the parameter type to match the trait: `&mut Bar`
+ |
+note: type in trait
+ --> $DIR/trait-impl-fn-incompatibility.rs:3:28
+ |
+LL | fn bar(&mut self, bar: &mut Bar);
+ | ^^^^^^^^
+ = note: expected signature `fn(&mut Bar, &mut Bar)`
+ found signature `fn(&mut Bar, &Bar)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
new file mode 100644
index 000000000..307104e47
--- /dev/null
+++ b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
@@ -0,0 +1,22 @@
+#![feature(unboxed_closures,tuple_trait)]
+
+use std::ops::FnMut;
+
+fn to_fn_mut<A:std::marker::Tuple, F:FnMut<A>>(f: F) -> F { f }
+
+fn call_it<F: FnMut(isize, isize) -> isize>(y: isize, mut f: F) -> isize {
+ //~^ NOTE required by this bound in `call_it`
+ //~| NOTE required by a bound in `call_it`
+ f(2, y)
+}
+
+pub fn main() {
+ let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
+ //~^ NOTE found signature defined here
+ let z = call_it(3, f);
+ //~^ ERROR type mismatch
+ //~| NOTE expected due to this
+ //~| NOTE expected closure signature `fn(isize, _) -> _`
+ //~| NOTE required by a bound introduced by this call
+ println!("{}", z);
+}
diff --git a/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
new file mode 100644
index 000000000..54b220065
--- /dev/null
+++ b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -0,0 +1,22 @@
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/unboxed-closures-vtable-mismatch.rs:16:24
+ |
+LL | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
+ | ----------------------------- found signature defined here
+LL |
+LL | let z = call_it(3, f);
+ | ------- ^ expected due to this
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected closure signature `fn(isize, _) -> _`
+ found closure signature `fn(usize, _) -> _`
+note: required by a bound in `call_it`
+ --> $DIR/unboxed-closures-vtable-mismatch.rs:7:15
+ |
+LL | fn call_it<F: FnMut(isize, isize) -> isize>(y: isize, mut f: F) -> isize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call_it`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/mismatched_types/wrap-suggestion-privacy.rs b/tests/ui/mismatched_types/wrap-suggestion-privacy.rs
new file mode 100644
index 000000000..63cb1a129
--- /dev/null
+++ b/tests/ui/mismatched_types/wrap-suggestion-privacy.rs
@@ -0,0 +1,24 @@
+mod inner {
+ pub struct Wrapper<T>(T);
+}
+
+fn needs_wrapper(t: inner::Wrapper<i32>) {}
+fn needs_wrapping(t: std::num::Wrapping<i32>) {}
+fn needs_ready(t: std::future::Ready<i32>) {}
+
+fn main() {
+ // Suggest wrapping expression because type is local
+ // and its privacy can be easily changed
+ needs_wrapper(0);
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping the expression in `inner::Wrapper`
+
+ // Suggest wrapping expression because field is accessible
+ needs_wrapping(0);
+ //~^ ERROR mismatched types
+ //~| HELP try wrapping the expression in `std::num::Wrapping`
+
+ // Do not suggest wrapping expression
+ needs_ready(Some(0));
+ //~^ ERROR mismatched types
+}
diff --git a/tests/ui/mismatched_types/wrap-suggestion-privacy.stderr b/tests/ui/mismatched_types/wrap-suggestion-privacy.stderr
new file mode 100644
index 000000000..fdd92cbfc
--- /dev/null
+++ b/tests/ui/mismatched_types/wrap-suggestion-privacy.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+ --> $DIR/wrap-suggestion-privacy.rs:12:19
+ |
+LL | needs_wrapper(0);
+ | ------------- ^ expected struct `Wrapper`, found integer
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Wrapper<i32>`
+ found type `{integer}`
+note: function defined here
+ --> $DIR/wrap-suggestion-privacy.rs:5:4
+ |
+LL | fn needs_wrapper(t: inner::Wrapper<i32>) {}
+ | ^^^^^^^^^^^^^ ----------------------
+help: try wrapping the expression in `inner::Wrapper` (its field is private, but it's local to this crate and its privacy can be changed)
+ |
+LL | needs_wrapper(inner::Wrapper(0));
+ | +++++++++++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/wrap-suggestion-privacy.rs:17:20
+ |
+LL | needs_wrapping(0);
+ | -------------- ^ expected struct `Wrapping`, found integer
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Wrapping<i32>`
+ found type `{integer}`
+note: function defined here
+ --> $DIR/wrap-suggestion-privacy.rs:6:4
+ |
+LL | fn needs_wrapping(t: std::num::Wrapping<i32>) {}
+ | ^^^^^^^^^^^^^^ --------------------------
+help: try wrapping the expression in `std::num::Wrapping`
+ |
+LL | needs_wrapping(std::num::Wrapping(0));
+ | +++++++++++++++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/wrap-suggestion-privacy.rs:22:17
+ |
+LL | needs_ready(Some(0));
+ | ----------- ^^^^^^^ expected struct `Ready`, found enum `Option`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `std::future::Ready<i32>`
+ found enum `Option<{integer}>`
+note: function defined here
+ --> $DIR/wrap-suggestion-privacy.rs:7:4
+ |
+LL | fn needs_ready(t: std::future::Ready<i32>) {}
+ | ^^^^^^^^^^^ --------------------------
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.