diff options
Diffstat (limited to 'tests/ui/inference')
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); +} |