summaryrefslogtreecommitdiffstats
path: root/tests/ui/inference
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/inference')
-rw-r--r--tests/ui/inference/ambiguous_type_parameter.rs17
-rw-r--r--tests/ui/inference/ambiguous_type_parameter.stderr14
-rw-r--r--tests/ui/inference/auxiliary/inference_unstable_iterator.rs35
-rw-r--r--tests/ui/inference/auxiliary/inference_unstable_itertools.rs25
-rw-r--r--tests/ui/inference/cannot-infer-async.rs16
-rw-r--r--tests/ui/inference/cannot-infer-async.stderr14
-rw-r--r--tests/ui/inference/cannot-infer-closure-circular.rs13
-rw-r--r--tests/ui/inference/cannot-infer-closure-circular.stderr14
-rw-r--r--tests/ui/inference/cannot-infer-closure.rs7
-rw-r--r--tests/ui/inference/cannot-infer-closure.stderr14
-rw-r--r--tests/ui/inference/cannot-infer-partial-try-return.rs23
-rw-r--r--tests/ui/inference/cannot-infer-partial-try-return.stderr14
-rw-r--r--tests/ui/inference/char-as-str-multi.rs7
-rw-r--r--tests/ui/inference/char-as-str-multi.stderr19
-rw-r--r--tests/ui/inference/char-as-str-single.fixed12
-rw-r--r--tests/ui/inference/char-as-str-single.rs12
-rw-r--r--tests/ui/inference/char-as-str-single.stderr42
-rw-r--r--tests/ui/inference/deref-suggestion.rs75
-rw-r--r--tests/ui/inference/deref-suggestion.stderr180
-rw-r--r--tests/ui/inference/erase-type-params-in-label.rs27
-rw-r--r--tests/ui/inference/erase-type-params-in-label.stderr37
-rw-r--r--tests/ui/inference/infer-binary-operand-behind-reference.rs30
-rw-r--r--tests/ui/inference/inference-variable-behind-raw-pointer.rs11
-rw-r--r--tests/ui/inference/inference-variable-behind-raw-pointer.stderr12
-rw-r--r--tests/ui/inference/inference_unstable.rs31
-rw-r--r--tests/ui/inference/inference_unstable.stderr57
-rw-r--r--tests/ui/inference/inference_unstable_featured.rs17
-rw-r--r--tests/ui/inference/inference_unstable_featured.stderr20
-rw-r--r--tests/ui/inference/inference_unstable_forced.rs12
-rw-r--r--tests/ui/inference/inference_unstable_forced.stderr12
-rw-r--r--tests/ui/inference/issue-103587.rs12
-rw-r--r--tests/ui/inference/issue-103587.stderr40
-rw-r--r--tests/ui/inference/issue-104649.rs32
-rw-r--r--tests/ui/inference/issue-104649.stderr14
-rw-r--r--tests/ui/inference/issue-28935.rs9
-rw-r--r--tests/ui/inference/issue-36053.rs22
-rw-r--r--tests/ui/inference/issue-70703.rs26
-rw-r--r--tests/ui/inference/issue-71309.rs7
-rw-r--r--tests/ui/inference/issue-71309.stderr15
-rw-r--r--tests/ui/inference/issue-71732.rs24
-rw-r--r--tests/ui/inference/issue-71732.stderr22
-rw-r--r--tests/ui/inference/issue-72616.rs32
-rw-r--r--tests/ui/inference/issue-72616.stderr37
-rw-r--r--tests/ui/inference/issue-72690.rs70
-rw-r--r--tests/ui/inference/issue-72690.stderr229
-rw-r--r--tests/ui/inference/issue-80816.rs55
-rw-r--r--tests/ui/inference/issue-80816.stderr29
-rw-r--r--tests/ui/inference/issue-81522.rs31
-rw-r--r--tests/ui/inference/issue-83606.rs10
-rw-r--r--tests/ui/inference/issue-83606.stderr14
-rw-r--r--tests/ui/inference/issue-86162-1.rs9
-rw-r--r--tests/ui/inference/issue-86162-1.stderr22
-rw-r--r--tests/ui/inference/issue-86162-2.rs14
-rw-r--r--tests/ui/inference/issue-86162-2.stderr22
-rw-r--r--tests/ui/inference/lub-glb-with-unbound-infer-var.rs15
-rw-r--r--tests/ui/inference/need_type_info/channel.rs19
-rw-r--r--tests/ui/inference/need_type_info/channel.stderr25
-rw-r--r--tests/ui/inference/need_type_info/concrete-impl.rs16
-rw-r--r--tests/ui/inference/need_type_info/concrete-impl.stderr24
-rw-r--r--tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs11
-rw-r--r--tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr9
-rw-r--r--tests/ui/inference/need_type_info/expr-struct-type-relative-enum.rs21
-rw-r--r--tests/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr14
-rw-r--r--tests/ui/inference/need_type_info/expr-struct-type-relative-gat.rs19
-rw-r--r--tests/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr9
-rw-r--r--tests/ui/inference/need_type_info/expr-struct-type-relative.rs21
-rw-r--r--tests/ui/inference/need_type_info/expr-struct-type-relative.stderr14
-rw-r--r--tests/ui/inference/need_type_info/issue-103053.rs18
-rw-r--r--tests/ui/inference/need_type_info/issue-103053.stderr14
-rw-r--r--tests/ui/inference/need_type_info/self-ty-in-path.rs13
-rw-r--r--tests/ui/inference/need_type_info/self-ty-in-path.stderr14
-rw-r--r--tests/ui/inference/need_type_info/type-alias-indirect.rs18
-rw-r--r--tests/ui/inference/need_type_info/type-alias-indirect.stderr9
-rw-r--r--tests/ui/inference/need_type_info/type-alias.rs36
-rw-r--r--tests/ui/inference/need_type_info/type-alias.stderr15
-rw-r--r--tests/ui/inference/newlambdas-ret-infer.rs12
-rw-r--r--tests/ui/inference/newlambdas-ret-infer2.rs12
-rw-r--r--tests/ui/inference/question-mark-type-infer.rs16
-rw-r--r--tests/ui/inference/question-mark-type-infer.stderr14
-rw-r--r--tests/ui/inference/range-type-infer.rs22
-rw-r--r--tests/ui/inference/simple-infer.rs6
-rw-r--r--tests/ui/inference/str-as-char.fixed10
-rw-r--r--tests/ui/inference/str-as-char.rs10
-rw-r--r--tests/ui/inference/str-as-char.stderr38
-rw-r--r--tests/ui/inference/tutorial-suffix-inference-test.rs24
-rw-r--r--tests/ui/inference/tutorial-suffix-inference-test.stderr57
-rw-r--r--tests/ui/inference/type-infer-generalize-ty-var.rs56
87 files changed, 2247 insertions, 0 deletions
diff --git a/tests/ui/inference/ambiguous_type_parameter.rs b/tests/ui/inference/ambiguous_type_parameter.rs
new file mode 100644
index 000000000..dc70ed661
--- /dev/null
+++ b/tests/ui/inference/ambiguous_type_parameter.rs
@@ -0,0 +1,17 @@
+use std::collections::HashMap;
+
+trait Store<K, V> {
+ fn get_raw(&self, key: &K) -> Option<()>;
+}
+
+struct InMemoryStore;
+
+impl<K> Store<String, HashMap<K, String>> for InMemoryStore {
+ fn get_raw(&self, key: &String) -> Option<()> {
+ None
+ }
+}
+
+fn main() {
+ InMemoryStore.get_raw(&String::default()); //~ ERROR type annotations needed
+}
diff --git a/tests/ui/inference/ambiguous_type_parameter.stderr b/tests/ui/inference/ambiguous_type_parameter.stderr
new file mode 100644
index 000000000..9cbe221de
--- /dev/null
+++ b/tests/ui/inference/ambiguous_type_parameter.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/ambiguous_type_parameter.rs:16:19
+ |
+LL | InMemoryStore.get_raw(&String::default());
+ | ^^^^^^^
+ |
+help: try using a fully qualified path to specify the expected types
+ |
+LL | <InMemoryStore as Store<String, HashMap<K, String>>>::get_raw(&InMemoryStore, &String::default());
+ | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/auxiliary/inference_unstable_iterator.rs b/tests/ui/inference/auxiliary/inference_unstable_iterator.rs
new file mode 100644
index 000000000..04bc0b1a8
--- /dev/null
+++ b/tests/ui/inference/auxiliary/inference_unstable_iterator.rs
@@ -0,0 +1,35 @@
+#![feature(staged_api)]
+#![feature(arbitrary_self_types)]
+
+#![stable(feature = "ipu_iterator", since = "1.0.0")]
+
+#[stable(feature = "ipu_iterator", since = "1.0.0")]
+pub trait IpuIterator {
+ #[unstable(feature = "ipu_flatten", issue = "99999")]
+ fn ipu_flatten(&self) -> u32 {
+ 0
+ }
+
+ #[unstable(feature = "ipu_flatten", issue = "99999")]
+ fn ipu_by_value_vs_by_ref(self) -> u32 where Self: Sized {
+ 0
+ }
+
+ #[unstable(feature = "ipu_flatten", issue = "99999")]
+ fn ipu_by_ref_vs_by_ref_mut(&self) -> u32 {
+ 0
+ }
+
+ #[unstable(feature = "ipu_flatten", issue = "99999")]
+ fn ipu_by_mut_ptr_vs_by_const_ptr(self: *mut Self) -> u32 {
+ 0
+ }
+
+ #[unstable(feature = "assoc_const_ipu_iter", issue = "99999")]
+ const C: i32;
+}
+
+#[stable(feature = "ipu_iterator", since = "1.0.0")]
+impl IpuIterator for char {
+ const C: i32 = 42;
+}
diff --git a/tests/ui/inference/auxiliary/inference_unstable_itertools.rs b/tests/ui/inference/auxiliary/inference_unstable_itertools.rs
new file mode 100644
index 000000000..fa1efbcfe
--- /dev/null
+++ b/tests/ui/inference/auxiliary/inference_unstable_itertools.rs
@@ -0,0 +1,25 @@
+#![feature(arbitrary_self_types)]
+
+pub trait IpuItertools {
+ fn ipu_flatten(&self) -> u32 {
+ 1
+ }
+
+ fn ipu_by_value_vs_by_ref(&self) -> u32 {
+ 1
+ }
+
+ fn ipu_by_ref_vs_by_ref_mut(&mut self) -> u32 {
+ 1
+ }
+
+ fn ipu_by_mut_ptr_vs_by_const_ptr(self: *const Self) -> u32 {
+ 1
+ }
+
+ const C: i32;
+}
+
+impl IpuItertools for char {
+ const C: i32 = 1;
+}
diff --git a/tests/ui/inference/cannot-infer-async.rs b/tests/ui/inference/cannot-infer-async.rs
new file mode 100644
index 000000000..b5152d04f
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-async.rs
@@ -0,0 +1,16 @@
+// edition:2018
+
+use std::io::Error;
+
+fn make_unit() -> Result<(), Error> {
+ Ok(())
+}
+
+fn main() {
+ let fut = async {
+ make_unit()?;
+
+ Ok(())
+ //~^ ERROR type annotations needed
+ };
+}
diff --git a/tests/ui/inference/cannot-infer-async.stderr b/tests/ui/inference/cannot-infer-async.stderr
new file mode 100644
index 000000000..0579cf238
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-async.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/cannot-infer-async.rs:13:9
+ |
+LL | Ok(())
+ | ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
+ |
+help: consider specifying the generic arguments
+ |
+LL | Ok::<(), E>(())
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/cannot-infer-closure-circular.rs b/tests/ui/inference/cannot-infer-closure-circular.rs
new file mode 100644
index 000000000..affb48149
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-closure-circular.rs
@@ -0,0 +1,13 @@
+fn main() {
+ // Below we call the closure with its own return as the argument, unifying
+ // its inferred input and return types. We want to make sure that the generated
+ // error handles this gracefully, and in particular doesn't generate an extra
+ // note about the `?` operator in the closure body, which isn't relevant to
+ // the inference.
+ let x = |r| { //~ ERROR type annotations needed for `Result<(), E>`
+ let v = r?;
+ Ok(v)
+ };
+
+ let _ = x(x(Ok(())));
+}
diff --git a/tests/ui/inference/cannot-infer-closure-circular.stderr b/tests/ui/inference/cannot-infer-closure-circular.stderr
new file mode 100644
index 000000000..b706cd2bc
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-closure-circular.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `Result<(), E>`
+ --> $DIR/cannot-infer-closure-circular.rs:7:14
+ |
+LL | let x = |r| {
+ | ^
+ |
+help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified
+ |
+LL | let x = |r: Result<(), E>| {
+ | +++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/cannot-infer-closure.rs b/tests/ui/inference/cannot-infer-closure.rs
new file mode 100644
index 000000000..bd5d10b41
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-closure.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let x = |a: (), b: ()| {
+ Err(a)?;
+ Ok(b)
+ //~^ ERROR type annotations needed
+ };
+}
diff --git a/tests/ui/inference/cannot-infer-closure.stderr b/tests/ui/inference/cannot-infer-closure.stderr
new file mode 100644
index 000000000..a4b818e6e
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-closure.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/cannot-infer-closure.rs:4:9
+ |
+LL | Ok(b)
+ | ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
+ |
+help: consider specifying the generic arguments
+ |
+LL | Ok::<(), E>(b)
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/cannot-infer-partial-try-return.rs b/tests/ui/inference/cannot-infer-partial-try-return.rs
new file mode 100644
index 000000000..b555697dc
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-partial-try-return.rs
@@ -0,0 +1,23 @@
+struct QualifiedError<E>(E);
+
+impl<E, T> From<E> for QualifiedError<T>
+where
+ E: std::error::Error,
+ T: From<E>,
+{
+ fn from(e: E) -> QualifiedError<T> {
+ QualifiedError(e.into())
+ }
+}
+
+fn infallible() -> Result<(), std::convert::Infallible> {
+ Ok(())
+}
+
+fn main() {
+ let x = || -> Result<_, QualifiedError<_>> {
+ infallible()?;
+ Ok(())
+ //~^ ERROR type annotations needed
+ };
+}
diff --git a/tests/ui/inference/cannot-infer-partial-try-return.stderr b/tests/ui/inference/cannot-infer-partial-try-return.stderr
new file mode 100644
index 000000000..888c321bc
--- /dev/null
+++ b/tests/ui/inference/cannot-infer-partial-try-return.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/cannot-infer-partial-try-return.rs:20:9
+ |
+LL | Ok(())
+ | ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
+ |
+help: consider specifying the generic arguments
+ |
+LL | Ok::<(), QualifiedError<_>>(())
+ | +++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/char-as-str-multi.rs b/tests/ui/inference/char-as-str-multi.rs
new file mode 100644
index 000000000..c29a15025
--- /dev/null
+++ b/tests/ui/inference/char-as-str-multi.rs
@@ -0,0 +1,7 @@
+// When a MULTI/NO-character string literal is used where a char should be,
+// DO NOT suggest changing to single quotes.
+
+fn main() {
+ let _: char = "foo"; //~ ERROR mismatched types
+ let _: char = ""; //~ ERROR mismatched types
+}
diff --git a/tests/ui/inference/char-as-str-multi.stderr b/tests/ui/inference/char-as-str-multi.stderr
new file mode 100644
index 000000000..297ca2b54
--- /dev/null
+++ b/tests/ui/inference/char-as-str-multi.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/char-as-str-multi.rs:5:19
+ |
+LL | let _: char = "foo";
+ | ---- ^^^^^ expected `char`, found `&str`
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/char-as-str-multi.rs:6:19
+ |
+LL | let _: char = "";
+ | ---- ^^ expected `char`, found `&str`
+ | |
+ | expected due to this
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/char-as-str-single.fixed b/tests/ui/inference/char-as-str-single.fixed
new file mode 100644
index 000000000..bab1854dc
--- /dev/null
+++ b/tests/ui/inference/char-as-str-single.fixed
@@ -0,0 +1,12 @@
+// When a SINGLE-character string literal is used where a char should be,
+// suggest changing to single quotes.
+
+// Testing both single-byte and multi-byte characters, as we should handle both.
+
+// run-rustfix
+
+fn main() {
+ let _: char = 'a'; //~ ERROR mismatched types
+ let _: char = '人'; //~ ERROR mismatched types
+ let _: char = '\''; //~ ERROR mismatched types
+}
diff --git a/tests/ui/inference/char-as-str-single.rs b/tests/ui/inference/char-as-str-single.rs
new file mode 100644
index 000000000..736920643
--- /dev/null
+++ b/tests/ui/inference/char-as-str-single.rs
@@ -0,0 +1,12 @@
+// When a SINGLE-character string literal is used where a char should be,
+// suggest changing to single quotes.
+
+// Testing both single-byte and multi-byte characters, as we should handle both.
+
+// run-rustfix
+
+fn main() {
+ let _: char = "a"; //~ ERROR mismatched types
+ let _: char = "人"; //~ ERROR mismatched types
+ let _: char = "'"; //~ ERROR mismatched types
+}
diff --git a/tests/ui/inference/char-as-str-single.stderr b/tests/ui/inference/char-as-str-single.stderr
new file mode 100644
index 000000000..3375ec6ac
--- /dev/null
+++ b/tests/ui/inference/char-as-str-single.stderr
@@ -0,0 +1,42 @@
+error[E0308]: mismatched types
+ --> $DIR/char-as-str-single.rs:9:19
+ |
+LL | let _: char = "a";
+ | ---- ^^^ expected `char`, found `&str`
+ | |
+ | expected due to this
+ |
+help: if you meant to write a `char` literal, use single quotes
+ |
+LL | let _: char = 'a';
+ | ~~~
+
+error[E0308]: mismatched types
+ --> $DIR/char-as-str-single.rs:10:19
+ |
+LL | let _: char = "人";
+ | ---- ^^^^ expected `char`, found `&str`
+ | |
+ | expected due to this
+ |
+help: if you meant to write a `char` literal, use single quotes
+ |
+LL | let _: char = '人';
+ | ~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/char-as-str-single.rs:11:19
+ |
+LL | let _: char = "'";
+ | ---- ^^^ expected `char`, found `&str`
+ | |
+ | expected due to this
+ |
+help: if you meant to write a `char` literal, use single quotes
+ |
+LL | let _: char = '\'';
+ | ~~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/deref-suggestion.rs b/tests/ui/inference/deref-suggestion.rs
new file mode 100644
index 000000000..0d8e7289d
--- /dev/null
+++ b/tests/ui/inference/deref-suggestion.rs
@@ -0,0 +1,75 @@
+macro_rules! borrow {
+ ($x:expr) => { &$x }
+}
+
+fn foo(_: String) {}
+
+fn foo2(s: &String) {
+ foo(s);
+ //~^ ERROR mismatched types
+}
+
+fn foo3(_: u32) {}
+fn foo4(u: &u32) {
+ foo3(u);
+ //~^ ERROR mismatched types
+}
+
+struct S<'a> {
+ u: &'a u32,
+}
+
+struct R {
+ i: u32,
+}
+
+fn main() {
+ let s = String::new();
+ let r_s = &s;
+ foo2(r_s);
+ foo(&"aaa".to_owned());
+ //~^ ERROR mismatched types
+ foo(&mut "aaa".to_owned());
+ //~^ ERROR mismatched types
+ foo3(borrow!(0));
+ //~^ ERROR mismatched types
+ foo4(&0);
+ assert_eq!(3i32, &3i32);
+ //~^ ERROR mismatched types
+ let u = 3;
+ let s = S { u };
+ //~^ ERROR mismatched types
+ let s = S { u: u };
+ //~^ ERROR mismatched types
+ let i = &4;
+ let r = R { i };
+ //~^ ERROR mismatched types
+ let r = R { i: i };
+ //~^ ERROR mismatched types
+
+
+ let a = &1;
+ let b = &2;
+ let val: i32 = if true {
+ a + 1
+ } else {
+ b
+ //~^ ERROR mismatched types
+ };
+ let val: i32 = if true {
+ let _ = 2;
+ a + 1
+ } else {
+ let _ = 2;
+ b
+ //~^ ERROR mismatched types
+ };
+ let val = if true {
+ *a
+ } else if true {
+ //~^ ERROR incompatible types
+ b
+ } else {
+ &0
+ };
+}
diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr
new file mode 100644
index 000000000..3db67cdb5
--- /dev/null
+++ b/tests/ui/inference/deref-suggestion.stderr
@@ -0,0 +1,180 @@
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:8:9
+ |
+LL | foo(s);
+ | --- ^- help: try using a conversion method: `.to_string()`
+ | | |
+ | | expected struct `String`, found `&String`
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/deref-suggestion.rs:5:4
+ |
+LL | fn foo(_: String) {}
+ | ^^^ ---------
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:14:10
+ |
+LL | foo3(u);
+ | ---- ^ expected `u32`, found `&u32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/deref-suggestion.rs:12:4
+ |
+LL | fn foo3(_: u32) {}
+ | ^^^^ ------
+help: consider dereferencing the borrow
+ |
+LL | foo3(*u);
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:30:9
+ |
+LL | foo(&"aaa".to_owned());
+ | --- ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/deref-suggestion.rs:5:4
+ |
+LL | fn foo(_: String) {}
+ | ^^^ ---------
+help: consider removing the borrow
+ |
+LL - foo(&"aaa".to_owned());
+LL + foo("aaa".to_owned());
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:32:9
+ |
+LL | foo(&mut "aaa".to_owned());
+ | --- ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/deref-suggestion.rs:5:4
+ |
+LL | fn foo(_: String) {}
+ | ^^^ ---------
+help: consider removing the borrow
+ |
+LL - foo(&mut "aaa".to_owned());
+LL + foo("aaa".to_owned());
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:34:10
+ |
+LL | foo3(borrow!(0));
+ | ---- ^^^^^^^^^^ expected `u32`, found `&{integer}`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/deref-suggestion.rs:12:4
+ |
+LL | fn foo3(_: u32) {}
+ | ^^^^ ------
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:37:5
+ |
+LL | assert_eq!(3i32, &3i32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected `i32`, found `&i32`
+ | expected because this is `i32`
+ |
+ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:40:17
+ |
+LL | let s = S { u };
+ | ^
+ | |
+ | expected `&u32`, found integer
+ | help: consider borrowing here: `u: &u`
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:42:20
+ |
+LL | let s = S { u: u };
+ | ^
+ | |
+ | expected `&u32`, found integer
+ | help: consider borrowing here: `&u`
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:45:17
+ |
+LL | let r = R { i };
+ | ^ expected `u32`, found `&{integer}`
+ |
+help: consider dereferencing the borrow
+ |
+LL | let r = R { i: *i };
+ | ++++
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:47:20
+ |
+LL | let r = R { i: i };
+ | ^ expected `u32`, found `&{integer}`
+ |
+help: consider dereferencing the borrow
+ |
+LL | let r = R { i: *i };
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:56:9
+ |
+LL | b
+ | ^ expected `i32`, found `&{integer}`
+ |
+help: consider dereferencing the borrow
+ |
+LL | *b
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/deref-suggestion.rs:64:9
+ |
+LL | b
+ | ^ expected `i32`, found `&{integer}`
+ |
+help: consider dereferencing the borrow
+ |
+LL | *b
+ | +
+
+error[E0308]: `if` and `else` have incompatible types
+ --> $DIR/deref-suggestion.rs:69:12
+ |
+LL | let val = if true {
+ | ________________-
+LL | | *a
+ | | -- expected because of this
+LL | | } else if true {
+ | | ____________^
+LL | ||
+LL | || b
+LL | || } else {
+LL | || &0
+LL | || };
+ | || ^
+ | ||_____|
+ | |_____`if` and `else` have incompatible types
+ | expected `i32`, found `&{integer}`
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/erase-type-params-in-label.rs b/tests/ui/inference/erase-type-params-in-label.rs
new file mode 100644
index 000000000..1fea2da92
--- /dev/null
+++ b/tests/ui/inference/erase-type-params-in-label.rs
@@ -0,0 +1,27 @@
+fn main() {
+ let foo = foo(1, ""); //~ ERROR E0283
+}
+fn baz() {
+ let bar = bar(1, ""); //~ ERROR E0283
+}
+
+struct Bar<T, K, N: Default> {
+ t: T,
+ k: K,
+ n: N,
+}
+
+fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
+ Bar { t, k, n: Default::default() }
+}
+
+struct Foo<T, K, N: Default, M: Default> {
+ t: T,
+ k: K,
+ n: N,
+ m: M,
+}
+
+fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
+ Foo { t, k, n: Default::default(), m: Default::default() }
+}
diff --git a/tests/ui/inference/erase-type-params-in-label.stderr b/tests/ui/inference/erase-type-params-in-label.stderr
new file mode 100644
index 000000000..9be182864
--- /dev/null
+++ b/tests/ui/inference/erase-type-params-in-label.stderr
@@ -0,0 +1,37 @@
+error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>`
+ --> $DIR/erase-type-params-in-label.rs:2:9
+ |
+LL | let foo = foo(1, "");
+ | ^^^ --- type must be known at this point
+ |
+ = note: cannot satisfy `_: Default`
+note: required by a bound in `foo`
+ --> $DIR/erase-type-params-in-label.rs:25:17
+ |
+LL | fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
+ | ^^^^^^^ required by this bound in `foo`
+help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified
+ |
+LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
+ | ++++++++++++++++++++++
+
+error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
+ --> $DIR/erase-type-params-in-label.rs:5:9
+ |
+LL | let bar = bar(1, "");
+ | ^^^ --- type must be known at this point
+ |
+ = note: cannot satisfy `_: Default`
+note: required by a bound in `bar`
+ --> $DIR/erase-type-params-in-label.rs:14:17
+ |
+LL | fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
+ | ^^^^^^^ required by this bound in `bar`
+help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified
+ |
+LL | let bar: Bar<i32, &str, Z> = bar(1, "");
+ | +++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/inference/infer-binary-operand-behind-reference.rs b/tests/ui/inference/infer-binary-operand-behind-reference.rs
new file mode 100644
index 000000000..0c0a3171e
--- /dev/null
+++ b/tests/ui/inference/infer-binary-operand-behind-reference.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+fn main() {
+ // Test that we can infer the type of binary operands when
+ // references are involved, on various types and operators.
+ let _: u8 = 0 + 0;
+ let _: u8 = 0 + &0;
+ let _: u8 = &0 + 0;
+ let _: u8 = &0 + &0;
+
+ let _: f32 = 0.0 + 0.0;
+ let _: f32 = 0.0 + &0.0;
+ let _: f32 = &0.0 + 0.0;
+ let _: f32 = &0.0 + &0.0;
+
+ let _: u8 = 0 << 0;
+ let _: u8 = 0 << &0;
+ let _: u8 = &0 << 0;
+ let _: u8 = &0 << &0;
+
+ // Test type inference when variable types are indirectly inferred.
+ let a = 22;
+ let _: usize = a + &44;
+
+ // When we have no expected type, the types of the operands is the default type.
+ let _ = 0 + 0;
+ let _ = 0 + &0;
+ let _ = &0 + 0;
+ let _ = &0 + &0;
+}
diff --git a/tests/ui/inference/inference-variable-behind-raw-pointer.rs b/tests/ui/inference/inference-variable-behind-raw-pointer.rs
new file mode 100644
index 000000000..6662e46b1
--- /dev/null
+++ b/tests/ui/inference/inference-variable-behind-raw-pointer.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+// tests that the following code compiles, but produces a future-compatibility warning
+
+fn main() {
+ let data = std::ptr::null();
+ let _ = &data as *const *const ();
+ if data.is_null() {}
+ //~^ WARNING type annotations needed
+ //~| WARNING this is accepted in the current edition
+}
diff --git a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr
new file mode 100644
index 000000000..3dea09e7f
--- /dev/null
+++ b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr
@@ -0,0 +1,12 @@
+warning: type annotations needed
+ --> $DIR/inference-variable-behind-raw-pointer.rs:8:13
+ |
+LL | if data.is_null() {}
+ | ^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+ = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
+ = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/inference/inference_unstable.rs b/tests/ui/inference/inference_unstable.rs
new file mode 100644
index 000000000..daf0cf042
--- /dev/null
+++ b/tests/ui/inference/inference_unstable.rs
@@ -0,0 +1,31 @@
+// Ensures #[unstable] functions without opting in the corresponding #![feature]
+// will not break inference.
+
+// aux-build:inference_unstable_iterator.rs
+// aux-build:inference_unstable_itertools.rs
+// run-pass
+
+extern crate inference_unstable_iterator;
+extern crate inference_unstable_itertools;
+
+#[allow(unused_imports)]
+use inference_unstable_iterator::IpuIterator;
+use inference_unstable_itertools::IpuItertools;
+
+fn main() {
+ assert_eq!('x'.ipu_flatten(), 1);
+//~^ WARN an associated function with this name may be added to the standard library in the future
+//~| WARN once this associated item is added to the standard library, the ambiguity may cause an
+ assert_eq!('x'.ipu_by_value_vs_by_ref(), 1);
+//~^ WARN an associated function with this name may be added to the standard library in the future
+//~| WARN once this associated item is added to the standard library, the ambiguity may cause an
+ assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1);
+//~^ WARN an associated function with this name may be added to the standard library in the future
+//~| WARN once this associated item is added to the standard library, the ambiguity may cause an
+ assert_eq!((&mut 'x' as *mut char).ipu_by_mut_ptr_vs_by_const_ptr(), 1);
+//~^ WARN an associated function with this name may be added to the standard library in the future
+//~| WARN once this associated item is added to the standard library, the ambiguity may cause an
+ assert_eq!(char::C, 1);
+//~^ WARN an associated constant with this name may be added to the standard library in the future
+//~| WARN once this associated item is added to the standard library, the ambiguity may cause an
+}
diff --git a/tests/ui/inference/inference_unstable.stderr b/tests/ui/inference/inference_unstable.stderr
new file mode 100644
index 000000000..ecbf2641b
--- /dev/null
+++ b/tests/ui/inference/inference_unstable.stderr
@@ -0,0 +1,57 @@
+warning: an associated function with this name may be added to the standard library in the future
+ --> $DIR/inference_unstable.rs:16:20
+ |
+LL | assert_eq!('x'.ipu_flatten(), 1);
+ | ^^^^^^^^^^^
+ |
+ = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
+ = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
+ = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method
+ = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`
+ = note: `#[warn(unstable_name_collisions)]` on by default
+
+warning: an associated function with this name may be added to the standard library in the future
+ --> $DIR/inference_unstable.rs:19:20
+ |
+LL | assert_eq!('x'.ipu_by_value_vs_by_ref(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
+ = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
+ = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_value_vs_by_ref(...)` to keep using the current method
+ = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_value_vs_by_ref`
+
+warning: an associated function with this name may be added to the standard library in the future
+ --> $DIR/inference_unstable.rs:22:20
+ |
+LL | assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
+ = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
+ = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_ref_vs_by_ref_mut(...)` to keep using the current method
+ = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_ref_vs_by_ref_mut`
+
+warning: an associated function with this name may be added to the standard library in the future
+ --> $DIR/inference_unstable.rs:25:40
+ |
+LL | assert_eq!((&mut 'x' as *mut char).ipu_by_mut_ptr_vs_by_const_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
+ = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
+ = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_mut_ptr_vs_by_const_ptr(...)` to keep using the current method
+ = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_mut_ptr_vs_by_const_ptr`
+
+warning: an associated constant with this name may be added to the standard library in the future
+ --> $DIR/inference_unstable.rs:28:16
+ |
+LL | assert_eq!(char::C, 1);
+ | ^^^^^^^ help: use the fully qualified path to the associated const: `<char as IpuItertools>::C`
+ |
+ = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
+ = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
+ = help: add `#![feature(assoc_const_ipu_iter)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::C`
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/inference/inference_unstable_featured.rs b/tests/ui/inference/inference_unstable_featured.rs
new file mode 100644
index 000000000..792b29aaa
--- /dev/null
+++ b/tests/ui/inference/inference_unstable_featured.rs
@@ -0,0 +1,17 @@
+// There should be E0034 "multiple applicable items in scope" if we opt-in for
+// the feature.
+
+// aux-build:inference_unstable_iterator.rs
+// aux-build:inference_unstable_itertools.rs
+
+#![feature(ipu_flatten)]
+
+extern crate inference_unstable_iterator;
+extern crate inference_unstable_itertools;
+
+use inference_unstable_iterator::IpuIterator;
+use inference_unstable_itertools::IpuItertools;
+
+fn main() {
+ assert_eq!('x'.ipu_flatten(), 0); //~ ERROR E0034
+}
diff --git a/tests/ui/inference/inference_unstable_featured.stderr b/tests/ui/inference/inference_unstable_featured.stderr
new file mode 100644
index 000000000..4ddede29c
--- /dev/null
+++ b/tests/ui/inference/inference_unstable_featured.stderr
@@ -0,0 +1,20 @@
+error[E0034]: multiple applicable items in scope
+ --> $DIR/inference_unstable_featured.rs:16:20
+ |
+LL | assert_eq!('x'.ipu_flatten(), 0);
+ | ^^^^^^^^^^^ multiple `ipu_flatten` found
+ |
+ = note: candidate #1 is defined in an impl of the trait `IpuIterator` for the type `char`
+ = note: candidate #2 is defined in an impl of the trait `IpuItertools` for the type `char`
+help: disambiguate the associated function for candidate #1
+ |
+LL | assert_eq!(IpuIterator::ipu_flatten(&'x'), 0);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+help: disambiguate the associated function for candidate #2
+ |
+LL | assert_eq!(IpuItertools::ipu_flatten(&'x'), 0);
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/inference/inference_unstable_forced.rs b/tests/ui/inference/inference_unstable_forced.rs
new file mode 100644
index 000000000..649b3ed2a
--- /dev/null
+++ b/tests/ui/inference/inference_unstable_forced.rs
@@ -0,0 +1,12 @@
+// If the unstable API is the only possible solution,
+// still emit E0658 "use of unstable library feature".
+
+// aux-build:inference_unstable_iterator.rs
+
+extern crate inference_unstable_iterator;
+
+use inference_unstable_iterator::IpuIterator;
+
+fn main() {
+ assert_eq!('x'.ipu_flatten(), 0); //~ ERROR E0658
+}
diff --git a/tests/ui/inference/inference_unstable_forced.stderr b/tests/ui/inference/inference_unstable_forced.stderr
new file mode 100644
index 000000000..a1c4cd851
--- /dev/null
+++ b/tests/ui/inference/inference_unstable_forced.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'ipu_flatten'
+ --> $DIR/inference_unstable_forced.rs:11:20
+ |
+LL | assert_eq!('x'.ipu_flatten(), 0);
+ | ^^^^^^^^^^^
+ |
+ = note: see issue #99999 <https://github.com/rust-lang/rust/issues/99999> for more information
+ = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/inference/issue-103587.rs b/tests/ui/inference/issue-103587.rs
new file mode 100644
index 000000000..11536f9f4
--- /dev/null
+++ b/tests/ui/inference/issue-103587.rs
@@ -0,0 +1,12 @@
+fn main() {
+ let x = Some(123);
+
+ if let Some(_) == x {}
+ //~^ ERROR expected `=`, found `==`
+
+ if Some(_) = x {}
+ //~^ ERROR mismatched types
+
+ if None = x { }
+ //~^ ERROR mismatched types
+}
diff --git a/tests/ui/inference/issue-103587.stderr b/tests/ui/inference/issue-103587.stderr
new file mode 100644
index 000000000..b373fbfbb
--- /dev/null
+++ b/tests/ui/inference/issue-103587.stderr
@@ -0,0 +1,40 @@
+error: expected `=`, found `==`
+ --> $DIR/issue-103587.rs:4:20
+ |
+LL | if let Some(_) == x {}
+ | ^^
+ |
+help: consider using `=` here
+ |
+LL | if let Some(_) = x {}
+ | ~
+
+error[E0308]: mismatched types
+ --> $DIR/issue-103587.rs:7:8
+ |
+LL | if Some(_) = x {}
+ | ^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | if let Some(_) = x {}
+ | +++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-103587.rs:10:8
+ |
+LL | if None = x { }
+ | ^^^^^^^^ expected `bool`, found `()`
+ |
+help: you might have meant to use pattern matching
+ |
+LL | if let None = x { }
+ | +++
+help: you might have meant to compare for equality
+ |
+LL | if None == x { }
+ | +
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/issue-104649.rs b/tests/ui/inference/issue-104649.rs
new file mode 100644
index 000000000..4637b884d
--- /dev/null
+++ b/tests/ui/inference/issue-104649.rs
@@ -0,0 +1,32 @@
+type Result<T, E = Error> = ::std::result::Result<T, E>;
+struct Error;
+
+trait ForEach {
+ type Input;
+ fn for_each<F, U>(self, f: F)
+ where
+ F: FnOnce(Self::Input) -> U;
+}
+
+impl<T> ForEach for A<T> {
+ type Input = T;
+ fn for_each<F, U>(self, f: F)
+ where
+ F: FnOnce(Self::Input) -> U,
+ {
+ todo!()
+ }
+}
+
+struct A<T>(T);
+
+fn main() {
+ let a = A(Result::Ok(Result::Ok(()))); //~ ERROR type annotations needed
+ a.for_each(|a: Result<_>| {
+ let f = || match a {
+ Ok(Ok(a)) => {}
+ Ok(Err(a)) => {}
+ Err(a) => {}
+ };
+ });
+}
diff --git a/tests/ui/inference/issue-104649.stderr b/tests/ui/inference/issue-104649.stderr
new file mode 100644
index 000000000..4962b21f9
--- /dev/null
+++ b/tests/ui/inference/issue-104649.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>`
+ --> $DIR/issue-104649.rs:24:9
+ |
+LL | let a = A(Result::Ok(Result::Ok(())));
+ | ^
+ |
+help: consider giving `a` an explicit type, where the type for type parameter `E` is specified
+ |
+LL | let a: A<std::result::Result<std::result::Result<(), E>, Error>> = A(Result::Ok(Result::Ok(())));
+ | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/issue-28935.rs b/tests/ui/inference/issue-28935.rs
new file mode 100644
index 000000000..872822dbd
--- /dev/null
+++ b/tests/ui/inference/issue-28935.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+use std::cell::RefCell;
+
+pub fn f(v: Vec<RefCell<u8>>) {
+ let _t = &mut *v[0].borrow_mut();
+}
+
+fn main() {}
diff --git a/tests/ui/inference/issue-36053.rs b/tests/ui/inference/issue-36053.rs
new file mode 100644
index 000000000..5c6d07804
--- /dev/null
+++ b/tests/ui/inference/issue-36053.rs
@@ -0,0 +1,22 @@
+// run-pass
+// Regression test for #36053. ICE was caused due to obligations being
+// added to a special, dedicated fulfillment cx during a
+// probe. Problem seems to be related to the particular definition of
+// `FusedIterator` in std but I was not able to isolate that into an
+// external crate.
+
+use std::iter::FusedIterator;
+
+struct Thing<'a>(#[allow(unused_tuple_struct_fields)] &'a str);
+impl<'a> Iterator for Thing<'a> {
+ type Item = &'a str;
+ fn next(&mut self) -> Option<&'a str> {
+ None
+ }
+}
+
+impl<'a> FusedIterator for Thing<'a> {}
+
+fn main() {
+ Thing("test").fuse().filter(|_| true).count();
+}
diff --git a/tests/ui/inference/issue-70703.rs b/tests/ui/inference/issue-70703.rs
new file mode 100644
index 000000000..d90498e96
--- /dev/null
+++ b/tests/ui/inference/issue-70703.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+trait Factory {
+ type Product;
+}
+
+impl Factory for () {
+ type Product = ();
+}
+
+trait ProductConsumer<P> {
+ fn consume(self, product: P);
+}
+
+impl<P> ProductConsumer<P> for () {
+ fn consume(self, _: P) {}
+}
+
+fn make_product_consumer<F: Factory>(_: F) -> impl ProductConsumer<F::Product> {
+ ()
+}
+
+fn main() {
+ let consumer = make_product_consumer(());
+ consumer.consume(());
+}
diff --git a/tests/ui/inference/issue-71309.rs b/tests/ui/inference/issue-71309.rs
new file mode 100644
index 000000000..c31107d8f
--- /dev/null
+++ b/tests/ui/inference/issue-71309.rs
@@ -0,0 +1,7 @@
+fn foo(x: Result<i32, ()>) -> Result<(), ()> {
+ let y: u32 = x?;
+ //~^ ERROR: `?` operator has incompatible types
+ Ok(())
+}
+
+fn main() {}
diff --git a/tests/ui/inference/issue-71309.stderr b/tests/ui/inference/issue-71309.stderr
new file mode 100644
index 000000000..af8714f1c
--- /dev/null
+++ b/tests/ui/inference/issue-71309.stderr
@@ -0,0 +1,15 @@
+error[E0308]: `?` operator has incompatible types
+ --> $DIR/issue-71309.rs:2:18
+ |
+LL | let y: u32 = x?;
+ | ^^ expected `u32`, found `i32`
+ |
+ = note: `?` operator cannot convert from `i32` to `u32`
+help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
+ |
+LL | let y: u32 = x?.try_into().unwrap();
+ | ++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/issue-71732.rs b/tests/ui/inference/issue-71732.rs
new file mode 100644
index 000000000..8a9d2b235
--- /dev/null
+++ b/tests/ui/inference/issue-71732.rs
@@ -0,0 +1,24 @@
+// Regression test for #71732, it used to emit incorrect diagnostics, like:
+// error[E0283]: type annotations needed
+// --> src/main.rs:5:10
+// |
+// 5 | .get(&"key".into())
+// | ^^^ cannot infer type for struct `String`
+// |
+// = note: cannot satisfy `String: Borrow<_>`
+// help: consider specifying the type argument in the method call
+// |
+// 5 | .get::<Q>(&"key".into())
+// |
+
+use std::collections::hash_map::HashMap;
+
+fn foo(parameters: &HashMap<String, String>) -> bool {
+ parameters
+ .get(&"key".into())
+ //~^ ERROR type annotations needed
+ .and_then(|found: &String| Some(false))
+ .unwrap_or(false)
+}
+
+fn main() {}
diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr
new file mode 100644
index 000000000..01b37f2ac
--- /dev/null
+++ b/tests/ui/inference/issue-71732.stderr
@@ -0,0 +1,22 @@
+error[E0283]: type annotations needed
+ --> $DIR/issue-71732.rs:18:10
+ |
+LL | .get(&"key".into())
+ | ^^^ ------------- type must be known at this point
+ | |
+ | cannot infer type of the type parameter `Q` declared on the associated function `get`
+ |
+ = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
+ - impl Borrow<str> for String;
+ - impl<T> Borrow<T> for T
+ where T: ?Sized;
+note: required by a bound in `HashMap::<K, V, S>::get`
+ --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
+help: consider specifying the generic argument
+ |
+LL | .get::<Q>(&"key".into())
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/inference/issue-72616.rs b/tests/ui/inference/issue-72616.rs
new file mode 100644
index 000000000..69ade1a75
--- /dev/null
+++ b/tests/ui/inference/issue-72616.rs
@@ -0,0 +1,32 @@
+// ignore-wasm32 FIXME: ignoring wasm as it suggests slightly different impls
+
+// Regression test for #72616, it used to emit incorrect diagnostics, like:
+// error[E0283]: type annotations needed for `String`
+// --> src/main.rs:8:30
+// |
+// 5 | let _: String = "".to_owned().try_into().unwrap();
+// | - consider giving this pattern a type
+// ...
+// 8 | if String::from("a") == "a".try_into().unwrap() {}
+// | ^^ cannot infer type for struct `String`
+// |
+// = note: cannot satisfy `String: PartialEq<_>`
+
+use std::convert::TryInto;
+
+pub fn main() {
+ {
+ let _: String = "".to_owned().try_into().unwrap();
+ }
+ {
+ if String::from("a") == "a".try_into().unwrap() {}
+ //~^ ERROR type annotations needed
+ //~| ERROR type annotations needed
+ }
+ {
+ let _: String = match "_".try_into() {
+ Ok(a) => a,
+ Err(_) => "".into(),
+ };
+ }
+}
diff --git a/tests/ui/inference/issue-72616.stderr b/tests/ui/inference/issue-72616.stderr
new file mode 100644
index 000000000..6ee0626ca
--- /dev/null
+++ b/tests/ui/inference/issue-72616.stderr
@@ -0,0 +1,37 @@
+error[E0283]: type annotations needed
+ --> $DIR/issue-72616.rs:22:37
+ |
+LL | if String::from("a") == "a".try_into().unwrap() {}
+ | -- ^^^^^^^^
+ | |
+ | type must be known at this point
+ |
+ = note: multiple `impl`s satisfying `String: PartialEq<_>` found in the `alloc` crate:
+ - impl PartialEq for String;
+ - impl<'a, 'b> PartialEq<&'a str> for String;
+ - impl<'a, 'b> PartialEq<Cow<'a, str>> for String;
+ - impl<'a, 'b> PartialEq<str> for String;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | if String::from("a") == <&str as TryInto<T>>::try_into("a").unwrap() {}
+ | +++++++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72616.rs:22:37
+ |
+LL | if String::from("a") == "a".try_into().unwrap() {}
+ | ^^^^^^^^
+ |
+ = note: multiple `impl`s satisfying `_: TryFrom<&str>` found in the following crates: `core`, `std`:
+ - impl<> TryFrom<&str> for std::sys_common::net::LookupHost;
+ - impl<T, U> TryFrom<U> for T
+ where U: Into<T>;
+ = note: required for `&str` to implement `TryInto<_>`
+help: try using a fully qualified path to specify the expected types
+ |
+LL | if String::from("a") == <&str as TryInto<T>>::try_into("a").unwrap() {}
+ | +++++++++++++++++++++++++++++++ ~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/inference/issue-72690.rs b/tests/ui/inference/issue-72690.rs
new file mode 100644
index 000000000..8c0a0f51a
--- /dev/null
+++ b/tests/ui/inference/issue-72690.rs
@@ -0,0 +1,70 @@
+fn no_err() {
+ |x: String| x;
+ let _ = String::from("x");
+}
+
+fn err() {
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+}
+
+fn arg_pat_closure_err() {
+ |x| String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~| ERROR type annotations needed
+}
+
+fn local_pat_closure_err() {
+ let _ = "x".as_ref(); //~ ERROR type annotations needed
+}
+
+fn err_first_arg_pat() {
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+ |x: String| x;
+}
+
+fn err_second_arg_pat() {
+ |x: String| x;
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+}
+
+fn err_mid_arg_pat() {
+ |x: String| x;
+ |x: String| x;
+ |x: String| x;
+ |x: String| x;
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+ |x: String| x;
+ |x: String| x;
+ |x: String| x;
+ |x: String| x;
+}
+
+fn err_first_local_pat() {
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+ let _ = String::from("x");
+}
+
+fn err_second_local_pat() {
+ let _ = String::from("x");
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+}
+
+fn err_mid_local_pat() {
+ let _ = String::from("x");
+ let _ = String::from("x");
+ let _ = String::from("x");
+ let _ = String::from("x");
+ String::from("x".as_ref()); //~ ERROR type annotations needed
+ //~^ ERROR type annotations needed
+ let _ = String::from("x");
+ let _ = String::from("x");
+ let _ = String::from("x");
+ let _ = String::from("x");
+}
+
+fn main() {}
diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr
new file mode 100644
index 000000000..8eda71ec0
--- /dev/null
+++ b/tests/ui/inference/issue-72690.stderr
@@ -0,0 +1,229 @@
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:7:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:7:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0282]: type annotations needed
+ --> $DIR/issue-72690.rs:12:6
+ |
+LL | |x| String::from("x".as_ref());
+ | ^
+ |
+help: consider giving this closure parameter an explicit type
+ |
+LL | |x: /* Type */| String::from("x".as_ref());
+ | ++++++++++++
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:12:26
+ |
+LL | |x| String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | |x| String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed for `&T`
+ --> $DIR/issue-72690.rs:17:9
+ |
+LL | let _ = "x".as_ref();
+ | ^ ------ type must be known at this point
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: consider giving this pattern a type, where the type for type parameter `T` is specified
+ |
+LL | let _: &T = "x".as_ref();
+ | ++++
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:21:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:21:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:28:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:28:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:37:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:37:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:46:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:46:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:53:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:53:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:62:5
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^^^^^^^ cannot infer type for reference `&_`
+ |
+ = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
+ - impl<> From<&String> for String;
+ - impl<> From<&str> for String;
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72690.rs:62:22
+ |
+LL | String::from("x".as_ref());
+ | ^^^^^^
+ |
+ = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
+ - impl AsRef<OsStr> for str;
+ - impl AsRef<Path> for str;
+ - impl AsRef<[u8]> for str;
+ - impl AsRef<str> for str;
+help: try using a fully qualified path to specify the expected types
+ |
+LL | String::from(<str as AsRef<T>>::as_ref("x"));
+ | ++++++++++++++++++++++++++ ~
+
+error: aborting due to 17 previous errors
+
+Some errors have detailed explanations: E0282, E0283.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/issue-80816.rs b/tests/ui/inference/issue-80816.rs
new file mode 100644
index 000000000..4d319b449
--- /dev/null
+++ b/tests/ui/inference/issue-80816.rs
@@ -0,0 +1,55 @@
+#![allow(unreachable_code)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::sync::Arc;
+
+pub struct Guard<T> {
+ _phantom: PhantomData<T>,
+}
+impl<T> Deref for Guard<T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ unimplemented!()
+ }
+}
+
+pub struct DirectDeref<T>(T);
+impl<T> Deref for DirectDeref<Arc<T>> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ unimplemented!()
+ }
+}
+
+pub trait Access<T> {
+ type Guard: Deref<Target = T>;
+ fn load(&self) -> Self::Guard {
+ unimplemented!()
+ }
+}
+impl<T, A: Access<T>, P: Deref<Target = A>> Access<T> for P {
+ //~^ NOTE: required for `Arc<ArcSwapAny<Arc<usize>>>` to implement `Access<_>`
+ //~| NOTE unsatisfied trait bound introduced here
+ type Guard = A::Guard;
+}
+impl<T> Access<T> for ArcSwapAny<T> {
+ //~^ NOTE: multiple `impl`s satisfying `ArcSwapAny<Arc<usize>>: Access<_>` found
+ type Guard = Guard<T>;
+}
+impl<T> Access<T> for ArcSwapAny<Arc<T>> {
+ type Guard = DirectDeref<Arc<T>>;
+}
+
+pub struct ArcSwapAny<T> {
+ _phantom_arc: PhantomData<T>,
+}
+
+pub fn foo() {
+ let s: Arc<ArcSwapAny<Arc<usize>>> = unimplemented!();
+ let guard: Guard<Arc<usize>> = s.load();
+ //~^ ERROR: type annotations needed
+ //~| HELP: try using a fully qualified path to specify the expected types
+}
+
+fn main() {}
diff --git a/tests/ui/inference/issue-80816.stderr b/tests/ui/inference/issue-80816.stderr
new file mode 100644
index 000000000..80c0c8abe
--- /dev/null
+++ b/tests/ui/inference/issue-80816.stderr
@@ -0,0 +1,29 @@
+error[E0283]: type annotations needed
+ --> $DIR/issue-80816.rs:50:38
+ |
+LL | let guard: Guard<Arc<usize>> = s.load();
+ | ^^^^
+ |
+note: multiple `impl`s satisfying `ArcSwapAny<Arc<usize>>: Access<_>` found
+ --> $DIR/issue-80816.rs:36:1
+ |
+LL | impl<T> Access<T> for ArcSwapAny<T> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | impl<T> Access<T> for ArcSwapAny<Arc<T>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required for `Arc<ArcSwapAny<Arc<usize>>>` to implement `Access<_>`
+ --> $DIR/issue-80816.rs:31:45
+ |
+LL | impl<T, A: Access<T>, P: Deref<Target = A>> Access<T> for P {
+ | --------- ^^^^^^^^^ ^
+ | |
+ | unsatisfied trait bound introduced here
+help: try using a fully qualified path to specify the expected types
+ |
+LL | let guard: Guard<Arc<usize>> = <Arc<ArcSwapAny<Arc<usize>>> as Access<T>>::load(&s);
+ | ++++++++++++++++++++++++++++++++++++++++++++++++++ ~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/inference/issue-81522.rs b/tests/ui/inference/issue-81522.rs
new file mode 100644
index 000000000..902f8fdde
--- /dev/null
+++ b/tests/ui/inference/issue-81522.rs
@@ -0,0 +1,31 @@
+// Regression test for #81522.
+// Ensures that `#[allow(unstable_name_collisions)]` appended to things other than function
+// suppresses the corresponding diagnostics emitted from inside them.
+// But note that this attribute doesn't work for macro invocations if it is appended directly.
+
+// aux-build:inference_unstable_iterator.rs
+// aux-build:inference_unstable_itertools.rs
+// run-pass
+
+extern crate inference_unstable_iterator;
+extern crate inference_unstable_itertools;
+
+#[allow(unused_imports)]
+use inference_unstable_iterator::IpuIterator;
+use inference_unstable_itertools::IpuItertools;
+
+fn main() {
+ // expression statement
+ #[allow(unstable_name_collisions)]
+ 'x'.ipu_flatten();
+
+ // let statement
+ #[allow(unstable_name_collisions)]
+ let _ = 'x'.ipu_flatten();
+
+ // block expression
+ #[allow(unstable_name_collisions)]
+ {
+ 'x'.ipu_flatten();
+ }
+}
diff --git a/tests/ui/inference/issue-83606.rs b/tests/ui/inference/issue-83606.rs
new file mode 100644
index 000000000..c387046e9
--- /dev/null
+++ b/tests/ui/inference/issue-83606.rs
@@ -0,0 +1,10 @@
+// Regression test for #83606.
+
+fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
+ [0; N]
+}
+
+fn main() {
+ let _ = foo("foo");
+ //~^ ERROR: type annotations needed for `[usize; N]`
+}
diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr
new file mode 100644
index 000000000..f2ee8692e
--- /dev/null
+++ b/tests/ui/inference/issue-83606.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `[usize; N]`
+ --> $DIR/issue-83606.rs:8:9
+ |
+LL | let _ = foo("foo");
+ | ^
+ |
+help: consider giving this pattern a type, where the the value of const parameter `N` is specified
+ |
+LL | let _: [usize; N] = foo("foo");
+ | ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/issue-86162-1.rs b/tests/ui/inference/issue-86162-1.rs
new file mode 100644
index 000000000..5a547eb38
--- /dev/null
+++ b/tests/ui/inference/issue-86162-1.rs
@@ -0,0 +1,9 @@
+// Regression test of #86162.
+
+fn foo(x: impl Clone) {}
+fn gen<T>() -> T { todo!() }
+
+fn main() {
+ foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
+ //~^ ERROR: type annotations needed
+}
diff --git a/tests/ui/inference/issue-86162-1.stderr b/tests/ui/inference/issue-86162-1.stderr
new file mode 100644
index 000000000..4f621b82d
--- /dev/null
+++ b/tests/ui/inference/issue-86162-1.stderr
@@ -0,0 +1,22 @@
+error[E0283]: type annotations needed
+ --> $DIR/issue-86162-1.rs:7:9
+ |
+LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
+ | --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: cannot satisfy `_: Clone`
+note: required by a bound in `foo`
+ --> $DIR/issue-86162-1.rs:3:16
+ |
+LL | fn foo(x: impl Clone) {}
+ | ^^^^^ required by this bound in `foo`
+help: consider specifying the generic argument
+ |
+LL | foo(gen::<T>()); //<- Do not suggest `foo::<impl Clone>()`!
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/inference/issue-86162-2.rs b/tests/ui/inference/issue-86162-2.rs
new file mode 100644
index 000000000..b8c75dd77
--- /dev/null
+++ b/tests/ui/inference/issue-86162-2.rs
@@ -0,0 +1,14 @@
+// Regression test of #86162.
+
+fn gen<T>() -> T { todo!() }
+
+struct Foo;
+
+impl Foo {
+ fn bar(x: impl Clone) {}
+}
+
+fn main() {
+ Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
+ //~^ ERROR: type annotations needed
+}
diff --git a/tests/ui/inference/issue-86162-2.stderr b/tests/ui/inference/issue-86162-2.stderr
new file mode 100644
index 000000000..9aff2cec1
--- /dev/null
+++ b/tests/ui/inference/issue-86162-2.stderr
@@ -0,0 +1,22 @@
+error[E0283]: type annotations needed
+ --> $DIR/issue-86162-2.rs:12:14
+ |
+LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
+ | -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: cannot satisfy `_: Clone`
+note: required by a bound in `Foo::bar`
+ --> $DIR/issue-86162-2.rs:8:20
+ |
+LL | fn bar(x: impl Clone) {}
+ | ^^^^^ required by this bound in `Foo::bar`
+help: consider specifying the generic argument
+ |
+LL | Foo::bar(gen::<T>()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/inference/lub-glb-with-unbound-infer-var.rs b/tests/ui/inference/lub-glb-with-unbound-infer-var.rs
new file mode 100644
index 000000000..c9e117089
--- /dev/null
+++ b/tests/ui/inference/lub-glb-with-unbound-infer-var.rs
@@ -0,0 +1,15 @@
+// run-pass
+// Test for a specific corner case: when we compute the LUB of two fn
+// types and their parameters have unbound variables. In that case, we
+// wind up relating those two variables. This was causing an ICE in an
+// in-progress PR.
+
+fn main() {
+ let a_f: fn(_) = |_| ();
+ let b_f: fn(_) = |_| ();
+ let c_f = match 22 {
+ 0 => a_f,
+ _ => b_f,
+ };
+ c_f(4);
+}
diff --git a/tests/ui/inference/need_type_info/channel.rs b/tests/ui/inference/need_type_info/channel.rs
new file mode 100644
index 000000000..e2ba5a941
--- /dev/null
+++ b/tests/ui/inference/need_type_info/channel.rs
@@ -0,0 +1,19 @@
+// Test that we suggest specifying the generic argument of `channel`
+// instead of the return type of that function, which is a lot more
+// complex.
+use std::sync::mpsc::channel;
+
+fn no_tuple() {
+ let _data =
+ channel(); //~ ERROR type annotations needed
+}
+
+fn tuple() {
+ let (_sender, _receiver) =
+ channel(); //~ ERROR type annotations needed
+}
+
+fn main() {
+ no_tuple();
+ tuple();
+}
diff --git a/tests/ui/inference/need_type_info/channel.stderr b/tests/ui/inference/need_type_info/channel.stderr
new file mode 100644
index 000000000..e33ace033
--- /dev/null
+++ b/tests/ui/inference/need_type_info/channel.stderr
@@ -0,0 +1,25 @@
+error[E0282]: type annotations needed
+ --> $DIR/channel.rs:8:9
+ |
+LL | channel();
+ | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `channel`
+ |
+help: consider specifying the generic argument
+ |
+LL | channel::<T>();
+ | +++++
+
+error[E0282]: type annotations needed
+ --> $DIR/channel.rs:13:9
+ |
+LL | channel();
+ | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `channel`
+ |
+help: consider specifying the generic argument
+ |
+LL | channel::<T>();
+ | +++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/concrete-impl.rs b/tests/ui/inference/need_type_info/concrete-impl.rs
new file mode 100644
index 000000000..72e0e74f3
--- /dev/null
+++ b/tests/ui/inference/need_type_info/concrete-impl.rs
@@ -0,0 +1,16 @@
+trait Ambiguous<A> {
+ fn method() {}
+}
+
+struct One;
+struct Two;
+struct Struct;
+
+impl Ambiguous<One> for Struct {}
+impl Ambiguous<Two> for Struct {}
+
+fn main() {
+ <Struct as Ambiguous<_>>::method();
+ //~^ ERROR type annotations needed
+ //~| ERROR type annotations needed
+}
diff --git a/tests/ui/inference/need_type_info/concrete-impl.stderr b/tests/ui/inference/need_type_info/concrete-impl.stderr
new file mode 100644
index 000000000..aa3296995
--- /dev/null
+++ b/tests/ui/inference/need_type_info/concrete-impl.stderr
@@ -0,0 +1,24 @@
+error[E0282]: type annotations needed
+ --> $DIR/concrete-impl.rs:13:5
+ |
+LL | <Struct as Ambiguous<_>>::method();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
+
+error[E0283]: type annotations needed
+ --> $DIR/concrete-impl.rs:13:5
+ |
+LL | <Struct as Ambiguous<_>>::method();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
+ |
+note: multiple `impl`s satisfying `Struct: Ambiguous<_>` found
+ --> $DIR/concrete-impl.rs:9:1
+ |
+LL | impl Ambiguous<One> for Struct {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl Ambiguous<Two> for Struct {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0283.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs b/tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
new file mode 100644
index 000000000..3084f6eac
--- /dev/null
+++ b/tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
@@ -0,0 +1,11 @@
+enum OhNo<T, U> {
+ A(T),
+ B(U),
+ C,
+}
+
+fn uwu() {
+ OhNo::C::<u32, _>; //~ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr b/tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr
new file mode 100644
index 000000000..2ad35ab03
--- /dev/null
+++ b/tests/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+ --> $DIR/do-not-suggest-generic-arguments-for-turbofish.rs:8:5
+ |
+LL | OhNo::C::<u32, _>;
+ | ^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the enum `OhNo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/expr-struct-type-relative-enum.rs b/tests/ui/inference/need_type_info/expr-struct-type-relative-enum.rs
new file mode 100644
index 000000000..42af9fa8d
--- /dev/null
+++ b/tests/ui/inference/need_type_info/expr-struct-type-relative-enum.rs
@@ -0,0 +1,21 @@
+trait Foo {
+ type Output;
+
+ fn baz() -> Self::Output;
+}
+
+fn needs_infer<T>() {}
+
+enum Bar {
+ Variant {}
+}
+
+impl Foo for u8 {
+ type Output = Bar;
+ fn baz() -> Self::Output {
+ needs_infer(); //~ ERROR type annotations needed
+ Self::Output::Variant {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr b/tests/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr
new file mode 100644
index 000000000..68ecb3813
--- /dev/null
+++ b/tests/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/expr-struct-type-relative-enum.rs:16:9
+ |
+LL | needs_infer();
+ | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `needs_infer`
+ |
+help: consider specifying the generic argument
+ |
+LL | needs_infer::<T>();
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/expr-struct-type-relative-gat.rs b/tests/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
new file mode 100644
index 000000000..b0c0d3397
--- /dev/null
+++ b/tests/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
@@ -0,0 +1,19 @@
+trait Foo {
+ type Output<T>;
+
+ fn baz();
+}
+
+enum Bar<T> {
+ Simple {},
+ Generic(T),
+}
+
+impl Foo for u8 {
+ type Output<T> = Bar<T>;
+ fn baz() {
+ Self::Output::Simple {}; //~ ERROR type annotations needed
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr b/tests/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
new file mode 100644
index 000000000..cbc2477de
--- /dev/null
+++ b/tests/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+ --> $DIR/expr-struct-type-relative-gat.rs:15:9
+ |
+LL | Self::Output::Simple {};
+ | ^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated type `Output`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/expr-struct-type-relative.rs b/tests/ui/inference/need_type_info/expr-struct-type-relative.rs
new file mode 100644
index 000000000..c3ece2b16
--- /dev/null
+++ b/tests/ui/inference/need_type_info/expr-struct-type-relative.rs
@@ -0,0 +1,21 @@
+// regression test for #98598
+
+trait Foo {
+ type Output;
+
+ fn baz() -> Self::Output;
+}
+
+fn needs_infer<T>() {}
+
+struct Bar {}
+
+impl Foo for u8 {
+ type Output = Bar;
+ fn baz() -> Self::Output {
+ needs_infer(); //~ ERROR type annotations needed
+ Self::Output {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/expr-struct-type-relative.stderr b/tests/ui/inference/need_type_info/expr-struct-type-relative.stderr
new file mode 100644
index 000000000..397d8e7be
--- /dev/null
+++ b/tests/ui/inference/need_type_info/expr-struct-type-relative.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/expr-struct-type-relative.rs:16:9
+ |
+LL | needs_infer();
+ | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `needs_infer`
+ |
+help: consider specifying the generic argument
+ |
+LL | needs_infer::<T>();
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/issue-103053.rs b/tests/ui/inference/need_type_info/issue-103053.rs
new file mode 100644
index 000000000..05169666f
--- /dev/null
+++ b/tests/ui/inference/need_type_info/issue-103053.rs
@@ -0,0 +1,18 @@
+trait TypeMapper {
+ type MapType;
+}
+
+type Mapped<T> = <T as TypeMapper>::MapType;
+
+struct Test {}
+
+impl TypeMapper for () {
+ type MapType = Test;
+}
+
+fn test() {
+ Mapped::<()> {};
+ None; //~ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/issue-103053.stderr b/tests/ui/inference/need_type_info/issue-103053.stderr
new file mode 100644
index 000000000..84f0475d8
--- /dev/null
+++ b/tests/ui/inference/need_type_info/issue-103053.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-103053.rs:15:5
+ |
+LL | None;
+ | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
+ |
+help: consider specifying the generic argument
+ |
+LL | None::<T>;
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/self-ty-in-path.rs b/tests/ui/inference/need_type_info/self-ty-in-path.rs
new file mode 100644
index 000000000..768a8cc37
--- /dev/null
+++ b/tests/ui/inference/need_type_info/self-ty-in-path.rs
@@ -0,0 +1,13 @@
+// Test that we don't ICE when encountering a `Self` in a path.
+struct TestErr<T>(T);
+
+impl<T> TestErr<T> {
+ fn func_a<U>() {}
+
+ fn func_b() {
+ Self::func_a();
+ //~^ ERROR type annotations needed
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/self-ty-in-path.stderr b/tests/ui/inference/need_type_info/self-ty-in-path.stderr
new file mode 100644
index 000000000..04b521dbd
--- /dev/null
+++ b/tests/ui/inference/need_type_info/self-ty-in-path.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/self-ty-in-path.rs:8:9
+ |
+LL | Self::func_a();
+ | ^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the associated function `func_a`
+ |
+help: consider specifying the generic argument
+ |
+LL | Self::func_a::<U>();
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/type-alias-indirect.rs b/tests/ui/inference/need_type_info/type-alias-indirect.rs
new file mode 100644
index 000000000..0ed02ddc5
--- /dev/null
+++ b/tests/ui/inference/need_type_info/type-alias-indirect.rs
@@ -0,0 +1,18 @@
+// An addition to the `type-alias.rs` test,
+// see the FIXME in that file for why this test
+// exists.
+//
+// If there is none, feel free to remove this test
+// again.
+struct Ty<T>(T);
+impl<T> Ty<T> {
+ fn new() {}
+}
+
+type IndirectAlias<T> = Ty<Box<T>>;
+fn indirect_alias() {
+ IndirectAlias::new();
+ //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/type-alias-indirect.stderr b/tests/ui/inference/need_type_info/type-alias-indirect.stderr
new file mode 100644
index 000000000..6161690df
--- /dev/null
+++ b/tests/ui/inference/need_type_info/type-alias-indirect.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+ --> $DIR/type-alias-indirect.rs:14:5
+ |
+LL | IndirectAlias::new();
+ | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/type-alias.rs b/tests/ui/inference/need_type_info/type-alias.rs
new file mode 100644
index 000000000..f921b046b
--- /dev/null
+++ b/tests/ui/inference/need_type_info/type-alias.rs
@@ -0,0 +1,36 @@
+// Test the inference errors in case the relevant path
+// uses a type alias.
+//
+// Regression test for #97698.
+struct Ty<T>(T);
+impl<T> Ty<T> {
+ fn new() {}
+}
+
+type DirectAlias<T> = Ty<T>;
+fn direct_alias() {
+ DirectAlias::new()
+ //~^ ERROR type annotations needed
+}
+
+type IndirectAlias<T> = Ty<Box<T>>;
+fn indirect_alias() {
+ IndirectAlias::new();
+ // FIXME: This should also emit an error.
+ //
+ // Added it separately as `type-alias-indirect.rs`
+ // where it does error.
+}
+
+struct TyDefault<T, U = u32>(T, U);
+impl<T> TyDefault<T> {
+ fn new() {}
+}
+
+type DirectButWithDefaultAlias<T> = TyDefault<T>;
+fn direct_but_with_default_alias() {
+ DirectButWithDefaultAlias::new();
+ //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr
new file mode 100644
index 000000000..a33f49baf
--- /dev/null
+++ b/tests/ui/inference/need_type_info/type-alias.stderr
@@ -0,0 +1,15 @@
+error[E0282]: type annotations needed
+ --> $DIR/type-alias.rs:12:5
+ |
+LL | DirectAlias::new()
+ | ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+ --> $DIR/type-alias.rs:32:5
+ |
+LL | DirectButWithDefaultAlias::new();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/newlambdas-ret-infer.rs b/tests/ui/inference/newlambdas-ret-infer.rs
new file mode 100644
index 000000000..9b629838f
--- /dev/null
+++ b/tests/ui/inference/newlambdas-ret-infer.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+#![allow(dead_code)]
+// Test that the lambda kind is inferred correctly as a return
+// expression
+
+// pretty-expanded FIXME #23616
+
+fn unique() -> Box<dyn FnMut()+'static> { return Box::new(|| ()); }
+
+pub fn main() {
+}
diff --git a/tests/ui/inference/newlambdas-ret-infer2.rs b/tests/ui/inference/newlambdas-ret-infer2.rs
new file mode 100644
index 000000000..abe31a05f
--- /dev/null
+++ b/tests/ui/inference/newlambdas-ret-infer2.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+#![allow(dead_code)]
+// Test that the lambda kind is inferred correctly as a return
+// expression
+
+// pretty-expanded FIXME #23616
+
+fn unique() -> Box<dyn FnMut()+'static> { Box::new(|| ()) }
+
+pub fn main() {
+}
diff --git a/tests/ui/inference/question-mark-type-infer.rs b/tests/ui/inference/question-mark-type-infer.rs
new file mode 100644
index 000000000..10560f85e
--- /dev/null
+++ b/tests/ui/inference/question-mark-type-infer.rs
@@ -0,0 +1,16 @@
+// Test that type inference fails where there are multiple possible return types
+// for the `?` operator.
+
+fn f(x: &i32) -> Result<i32, ()> {
+ Ok(*x)
+}
+
+fn g() -> Result<Vec<i32>, ()> {
+ let l = [1, 2, 3, 4];
+ l.iter().map(f).collect()?
+ //~^ ERROR type annotations needed
+}
+
+fn main() {
+ g();
+}
diff --git a/tests/ui/inference/question-mark-type-infer.stderr b/tests/ui/inference/question-mark-type-infer.stderr
new file mode 100644
index 000000000..a9cb7e525
--- /dev/null
+++ b/tests/ui/inference/question-mark-type-infer.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/question-mark-type-infer.rs:10:21
+ |
+LL | l.iter().map(f).collect()?
+ | ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect`
+ |
+help: consider specifying the generic argument
+ |
+LL | l.iter().map(f).collect::<Vec<_>>()?
+ | ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/range-type-infer.rs b/tests/ui/inference/range-type-infer.rs
new file mode 100644
index 000000000..f07c04171
--- /dev/null
+++ b/tests/ui/inference/range-type-infer.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+#![allow(unused_must_use)]
+// Make sure the type inference for the new range expression work as
+// good as the old one. Check out issue #21672, #21595 and #21649 for
+// more details.
+
+
+fn main() {
+ let xs = (0..8).map(|i| i == 1u64).collect::<Vec<_>>();
+ assert_eq!(xs[1], true);
+ let xs = (0..8).map(|i| 1u64 == i).collect::<Vec<_>>();
+ assert_eq!(xs[1], true);
+ let xs: Vec<u8> = (0..10).collect();
+ assert_eq!(xs.len(), 10);
+
+ for x in 0..10 { x % 2; }
+ for x in 0..100 { x as f32; }
+
+ let array = [true, false];
+ for i in 0..1 { array[i]; }
+}
diff --git a/tests/ui/inference/simple-infer.rs b/tests/ui/inference/simple-infer.rs
new file mode 100644
index 000000000..561e4fdec
--- /dev/null
+++ b/tests/ui/inference/simple-infer.rs
@@ -0,0 +1,6 @@
+// run-pass
+
+#![allow(unused_mut)]
+
+
+pub fn main() { let mut n; n = 1; println!("{}", n); }
diff --git a/tests/ui/inference/str-as-char.fixed b/tests/ui/inference/str-as-char.fixed
new file mode 100644
index 000000000..6aea809cb
--- /dev/null
+++ b/tests/ui/inference/str-as-char.fixed
@@ -0,0 +1,10 @@
+// When a char literal is used where a str should be,
+// suggest changing to double quotes.
+
+// run-rustfix
+
+fn main() {
+ let _: &str = "a"; //~ ERROR mismatched types
+ let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint
+ let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint
+}
diff --git a/tests/ui/inference/str-as-char.rs b/tests/ui/inference/str-as-char.rs
new file mode 100644
index 000000000..eaa8d788c
--- /dev/null
+++ b/tests/ui/inference/str-as-char.rs
@@ -0,0 +1,10 @@
+// When a char literal is used where a str should be,
+// suggest changing to double quotes.
+
+// run-rustfix
+
+fn main() {
+ let _: &str = 'a'; //~ ERROR mismatched types
+ let _: &str = '"""'; //~ ERROR character literal may only contain one codepoint
+ let _: &str = '\"\"\"'; //~ ERROR character literal may only contain one codepoint
+}
diff --git a/tests/ui/inference/str-as-char.stderr b/tests/ui/inference/str-as-char.stderr
new file mode 100644
index 000000000..2c84dac8e
--- /dev/null
+++ b/tests/ui/inference/str-as-char.stderr
@@ -0,0 +1,38 @@
+error: character literal may only contain one codepoint
+ --> $DIR/str-as-char.rs:8:19
+ |
+LL | let _: &str = '"""';
+ | ^^^^^
+ |
+help: if you meant to write a `str` literal, use double quotes
+ |
+LL | let _: &str = "\"\"\"";
+ | ~~~~~~~~
+
+error: character literal may only contain one codepoint
+ --> $DIR/str-as-char.rs:9:19
+ |
+LL | let _: &str = '\"\"\"';
+ | ^^^^^^^^
+ |
+help: if you meant to write a `str` literal, use double quotes
+ |
+LL | let _: &str = "\"\"\"";
+ | ~~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/str-as-char.rs:7:19
+ |
+LL | let _: &str = 'a';
+ | ---- ^^^ expected `&str`, found `char`
+ | |
+ | expected due to this
+ |
+help: if you meant to write a `str` literal, use double quotes
+ |
+LL | let _: &str = "a";
+ | ~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/tutorial-suffix-inference-test.rs b/tests/ui/inference/tutorial-suffix-inference-test.rs
new file mode 100644
index 000000000..849adfd53
--- /dev/null
+++ b/tests/ui/inference/tutorial-suffix-inference-test.rs
@@ -0,0 +1,24 @@
+fn main() {
+ let x = 3;
+ let y: i32 = 3;
+
+ fn identity_u8(n: u8) -> u8 { n }
+ fn identity_u16(n: u16) -> u16 { n }
+
+ identity_u8(x); // after this, `x` is assumed to have type `u8`
+ identity_u16(x);
+ //~^ ERROR mismatched types
+ //~| expected `u16`, found `u8`
+ identity_u16(y);
+ //~^ ERROR mismatched types
+ //~| expected `u16`, found `i32`
+
+ let a = 3;
+
+ fn identity_i(n: isize) -> isize { n }
+
+ identity_i(a); // ok
+ identity_u16(a);
+ //~^ ERROR mismatched types
+ //~| expected `u16`, found `isize`
+}
diff --git a/tests/ui/inference/tutorial-suffix-inference-test.stderr b/tests/ui/inference/tutorial-suffix-inference-test.stderr
new file mode 100644
index 000000000..d83a1367d
--- /dev/null
+++ b/tests/ui/inference/tutorial-suffix-inference-test.stderr
@@ -0,0 +1,57 @@
+error[E0308]: mismatched types
+ --> $DIR/tutorial-suffix-inference-test.rs:9:18
+ |
+LL | identity_u16(x);
+ | ------------ ^ expected `u16`, found `u8`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/tutorial-suffix-inference-test.rs:6:8
+ |
+LL | fn identity_u16(n: u16) -> u16 { n }
+ | ^^^^^^^^^^^^ ------
+help: you can convert a `u8` to a `u16`
+ |
+LL | identity_u16(x.into());
+ | +++++++
+
+error[E0308]: mismatched types
+ --> $DIR/tutorial-suffix-inference-test.rs:12:18
+ |
+LL | identity_u16(y);
+ | ------------ ^ expected `u16`, found `i32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/tutorial-suffix-inference-test.rs:6:8
+ |
+LL | fn identity_u16(n: u16) -> u16 { n }
+ | ^^^^^^^^^^^^ ------
+help: you can convert an `i32` to a `u16` and panic if the converted value doesn't fit
+ |
+LL | identity_u16(y.try_into().unwrap());
+ | ++++++++++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/tutorial-suffix-inference-test.rs:21:18
+ |
+LL | identity_u16(a);
+ | ------------ ^ expected `u16`, found `isize`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/tutorial-suffix-inference-test.rs:6:8
+ |
+LL | fn identity_u16(n: u16) -> u16 { n }
+ | ^^^^^^^^^^^^ ------
+help: you can convert an `isize` to a `u16` and panic if the converted value doesn't fit
+ |
+LL | identity_u16(a.try_into().unwrap());
+ | ++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/inference/type-infer-generalize-ty-var.rs b/tests/ui/inference/type-infer-generalize-ty-var.rs
new file mode 100644
index 000000000..a3d6916cb
--- /dev/null
+++ b/tests/ui/inference/type-infer-generalize-ty-var.rs
@@ -0,0 +1,56 @@
+// run-pass
+
+#![allow(non_upper_case_globals)]
+#![allow(dead_code)]
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+// Test a scenario where we generate a constraint like `?1 <: &?2`.
+// In such a case, it is important that we instantiate `?1` with `&?3`
+// where `?3 <: ?2`, and not with `&?2`. This is a regression test for
+// #18653. The important thing is that we build.
+
+use std::cell::RefCell;
+
+enum Wrap<A> {
+ WrapSome(A),
+ WrapNone
+}
+
+use Wrap::*;
+
+struct T;
+struct U;
+
+trait Get<T: ?Sized> {
+ fn get(&self) -> &T;
+}
+
+impl Get<dyn MyShow + 'static> for Wrap<T> {
+ fn get(&self) -> &(dyn MyShow + 'static) {
+ static x: usize = 42;
+ &x
+ }
+}
+
+impl Get<usize> for Wrap<U> {
+ fn get(&self) -> &usize {
+ static x: usize = 55;
+ &x
+ }
+}
+
+trait MyShow { fn dummy(&self) { } }
+impl<'a> MyShow for &'a (dyn MyShow + 'a) { }
+impl MyShow for usize { }
+fn constrain<'a>(rc: RefCell<&'a (dyn MyShow + 'a)>) { }
+
+fn main() {
+ let mut collection: Wrap<_> = WrapNone;
+
+ {
+ let __arg0 = Get::get(&collection);
+ let __args_cell = RefCell::new(__arg0);
+ constrain(__args_cell);
+ }
+ collection = WrapSome(T);
+}