diff options
Diffstat (limited to 'src/test/ui/type')
96 files changed, 3008 insertions, 0 deletions
diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs new file mode 100644 index 000000000..44b47cc4e --- /dev/null +++ b/src/test/ui/type/ascription/issue-34255-1.rs @@ -0,0 +1,15 @@ +struct Reactor { + input_cells: Vec<usize>, +} + +impl Reactor { + pub fn new() -> Self { + input_cells: Vec::new() + //~^ ERROR cannot find value `input_cells` in this scope + //~| ERROR parenthesized type parameters may only be used with a `Fn` trait + //~| ERROR missing generics for struct `Vec` + } +} + +// This case isn't currently being handled gracefully, including for completeness. +fn main() {} diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr new file mode 100644 index 000000000..6819d14bb --- /dev/null +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -0,0 +1,41 @@ +error[E0425]: cannot find value `input_cells` in this scope + --> $DIR/issue-34255-1.rs:7:9 + | +LL | input_cells: Vec::new() + | ^^^^^^^^^^^ a field by this name exists in `Self` + | +help: you might have meant to write a `struct` literal + | +LL ~ pub fn new() -> Self { SomeStruct { +LL | input_cells: Vec::new() + ... +LL | +LL ~ }} + | + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-34255-1.rs:7:27 + | +LL | input_cells: Vec::new() + | ^^^^^ only `Fn` traits may use parentheses + +error[E0107]: missing generics for struct `Vec` + --> $DIR/issue-34255-1.rs:7:22 + | +LL | input_cells: Vec::new() + | ^^^ expected at least 1 generic argument + | +note: struct defined here, with at least 1 generic parameter: `T` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> { + | ^^^ - +help: add missing generic argument + | +LL | input_cells: Vec<T>::new() + | ~~~~~~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0214, E0425. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/type/ascription/issue-47666.fixed b/src/test/ui/type/ascription/issue-47666.fixed new file mode 100644 index 000000000..c4db74755 --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.fixed @@ -0,0 +1,4 @@ +// run-rustfix +fn main() { + let _ = Option::Some(vec![0, 1]); //~ ERROR expected type, found +} diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs new file mode 100644 index 000000000..c67202e21 --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.rs @@ -0,0 +1,4 @@ +// run-rustfix +fn main() { + let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found +} diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr new file mode 100644 index 000000000..0f90fce3a --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -0,0 +1,16 @@ +error: expected type, found `<[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([0, 1]))` + --> $DIR/issue-47666.rs:3:25 + | +LL | let _ = Option:Some(vec![0, 1]); + | - ^^^^^^^^^^ + | | | + | | expected type + | | in this macro invocation + | | this macro call doesn't expand to a type + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: this error originates in the macro `$crate::__rust_force_expr` which comes from the expansion of the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/type/ascription/issue-54516.fixed b/src/test/ui/type/ascription/issue-54516.fixed new file mode 100644 index 000000000..f78268894 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.fixed @@ -0,0 +1,7 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem::size_of::<BTreeMap<u32, u32>>()); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs new file mode 100644 index 000000000..1f34e6943 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.rs @@ -0,0 +1,7 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr new file mode 100644 index 000000000..1ab9093e5 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.stderr @@ -0,0 +1,12 @@ +error: type ascription cannot be followed by a function call + --> $DIR/issue-54516.rs:5:20 + | +LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); + | ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + +error: aborting due to previous error + diff --git a/src/test/ui/type/ascription/issue-60933.fixed b/src/test/ui/type/ascription/issue-60933.fixed new file mode 100644 index 000000000..3e8be3875 --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _: usize = std::mem::size_of::<u32>(); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs new file mode 100644 index 000000000..2a4ad7bdc --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.rs @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _: usize = std::mem:size_of::<u32>(); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr new file mode 100644 index 000000000..0b7f8edf6 --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.stderr @@ -0,0 +1,12 @@ +error: type ascription cannot be followed by a function call + --> $DIR/issue-60933.rs:3:20 + | +LL | let _: usize = std::mem:size_of::<u32>(); + | ^^^^^^^^-^^^^^^^^^^^^^^ + | | + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + +error: aborting due to previous error + diff --git a/src/test/ui/type/auxiliary/crate_a1.rs b/src/test/ui/type/auxiliary/crate_a1.rs new file mode 100644 index 000000000..e2e185005 --- /dev/null +++ b/src/test/ui/type/auxiliary/crate_a1.rs @@ -0,0 +1,11 @@ +pub struct Foo; + +pub trait Bar{} + +pub fn bar() -> Box<Bar> { + unimplemented!() +} + + +pub fn try_foo(x: Foo){} +pub fn try_bar(x: Box<Bar>){} diff --git a/src/test/ui/type/auxiliary/crate_a2.rs b/src/test/ui/type/auxiliary/crate_a2.rs new file mode 100644 index 000000000..d16a4ac10 --- /dev/null +++ b/src/test/ui/type/auxiliary/crate_a2.rs @@ -0,0 +1,7 @@ +pub struct Foo; + +pub trait Bar{} + +pub fn bar() -> Box<Bar> { + unimplemented!() +} diff --git a/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs new file mode 100644 index 000000000..68aadcf60 --- /dev/null +++ b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs @@ -0,0 +1,8 @@ +// Regression test for issue #67690 +// Rustc endless loop out-of-memory and consequent SIGKILL in generic new type + +// check-pass +pub type T<P: Send + Send + Send> = P; +//~^ WARN bounds on generic parameters are not enforced in type aliases + +fn main() {} diff --git a/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr new file mode 100644 index 000000000..125ffbbb4 --- /dev/null +++ b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr @@ -0,0 +1,15 @@ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15 + | +LL | pub type T<P: Send + Send + Send> = P; + | ^^^^ ^^^^ ^^^^ + | + = note: `#[warn(type_alias_bounds)]` on by default +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - pub type T<P: Send + Send + Send> = P; +LL + pub type T<P> = P; + | + +warning: 1 warning emitted + diff --git a/src/test/ui/type/issue-91268.rs b/src/test/ui/type/issue-91268.rs new file mode 100644 index 000000000..f1e16bc7b --- /dev/null +++ b/src/test/ui/type/issue-91268.rs @@ -0,0 +1,9 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: cannot find type `Å£` in this scope +// error-pattern: parenthesized type parameters may only be used with a `Fn` trait +// error-pattern: type arguments are not allowed on builtin type `u8` +// error-pattern: mismatched types +// ignore-tidy-trailing-newlines +// `Å£` must be the last character in this file, it cannot be followed by a newline +fn main() { + 0: u8(Å£
\ No newline at end of file diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr new file mode 100644 index 000000000..6c9ee9945 --- /dev/null +++ b/src/test/ui/type/issue-91268.stderr @@ -0,0 +1,63 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-91268.rs:9:12 + | +LL | fn main() { + | - unclosed delimiter +LL | 0: u8(Å£ + | - ^ + | | + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-91268.rs:9:12 + | +LL | fn main() { + | - unclosed delimiter +LL | 0: u8(Å£ + | - ^ + | | + | unclosed delimiter + +error[E0412]: cannot find type `Å£` in this scope + --> $DIR/issue-91268.rs:9:11 + | +LL | 0: u8(Å£ + | ^ expecting a type here because of type ascription + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-91268.rs:9:8 + | +LL | 0: u8(Å£ + | ^^^^ only `Fn` traits may use parentheses + | +help: use angle brackets instead + | +LL | 0: u8<Å£> + | ~ + + +error[E0109]: type arguments are not allowed on builtin type `u8` + --> $DIR/issue-91268.rs:9:11 + | +LL | 0: u8(Å£ + | -- ^ type argument not allowed + | | + | not allowed on builtin type `u8` + | +help: primitive type `u8` doesn't have generic parameters + | +LL - 0: u8(Å£ +LL + 0: u8 + | + +error[E0308]: mismatched types + --> $DIR/issue-91268.rs:9:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | 0: u8(Å£ + | ^^^^^^^ expected `()`, found `u8` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0109, E0214, E0308, E0412. +For more information about an error, try `rustc --explain E0109`. diff --git a/src/test/ui/type/missing-let-in-binding.fixed b/src/test/ui/type/missing-let-in-binding.fixed new file mode 100644 index 000000000..d17876889 --- /dev/null +++ b/src/test/ui/type/missing-let-in-binding.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let mut _foo: i32 = 1; + let _foo: i32 = 4; //~ ERROR type ascription is experimental +} diff --git a/src/test/ui/type/missing-let-in-binding.rs b/src/test/ui/type/missing-let-in-binding.rs new file mode 100644 index 000000000..ca42f2e6e --- /dev/null +++ b/src/test/ui/type/missing-let-in-binding.rs @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let mut _foo: i32 = 1; + _foo: i32 = 4; //~ ERROR type ascription is experimental +} diff --git a/src/test/ui/type/missing-let-in-binding.stderr b/src/test/ui/type/missing-let-in-binding.stderr new file mode 100644 index 000000000..12759c509 --- /dev/null +++ b/src/test/ui/type/missing-let-in-binding.stderr @@ -0,0 +1,16 @@ +error[E0658]: type ascription is experimental + --> $DIR/missing-let-in-binding.rs:4:5 + | +LL | _foo: i32 = 4; + | ^^^^^^^^^ + | + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + = help: add `#![feature(type_ascription)]` to the crate attributes to enable +help: you might have meant to introduce a new binding + | +LL | let _foo: i32 = 4; + | +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs new file mode 100644 index 000000000..65b79650d --- /dev/null +++ b/src/test/ui/type/type-alias-bounds.rs @@ -0,0 +1,59 @@ +// Test `ignored_generic_bounds` lint warning about bounds in type aliases. + +// check-pass +#![allow(dead_code)] + +use std::rc::Rc; + +type SVec<T: Send + Send> = Vec<T>; +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +type S2Vec<T> where T: Send = Vec<T>; +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] +type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] + +static STATIC: u32 = 0; + +fn foo<'a>(y: &'a i32) { + // If any of the bounds above would matter, the code below would be rejected. + // This can be seen when replacing the type aliases above by newtype structs. + // (The type aliases have no unused parameters to make that a valid transformation.) + let mut x: SVec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x: S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not `Send` + + let mut x: VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // `'a: 'static` does not hold + + let mut x: WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold + + let mut x: W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold +} + +// Bounds are not checked either; i.e., the definition is not necessarily well-formed. +struct Sendable<T: Send>(T); +type MySendable<T> = Sendable<T>; // no error here! + +// However, bounds *are* taken into account when accessing associated types +trait Bound { type Assoc; } +type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases +type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases + +// This errors: +// `type T3<U> = U::Assoc;` +// Do this instead: +type T4<U> = <U as Bound>::Assoc; + +// Make sure the help about associatd types is not shown incorrectly +type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN not enforced in type aliases +type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN not enforced in type aliases + +fn main() {} diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr new file mode 100644 index 000000000..92e573393 --- /dev/null +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -0,0 +1,121 @@ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:8:14 + | +LL | type SVec<T: Send + Send> = Vec<T>; + | ^^^^ ^^^^ + | + = note: `#[warn(type_alias_bounds)]` on by default +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type SVec<T: Send + Send> = Vec<T>; +LL + type SVec<T> = Vec<T>; + | + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:10:21 + | +LL | type S2Vec<T> where T: Send = Vec<T>; + | ^^^^^^^ + | +help: the clause will not be checked when the type alias is used, and should be removed + | +LL - type S2Vec<T> where T: Send = Vec<T>; +LL + type S2Vec<T> = Vec<T>; + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:12:19 + | +LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); +LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>); + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:14:18 + | +LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); + | ^^ ^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); +LL + type WVec<'b, T> = (&'b u32, Vec<T>); + | + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:16:25 + | +LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); + | ^^^^^ ^^^^^ + | +help: the clause will not be checked when the type alias is used, and should be removed + | +LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); +LL + type W2Vec<'b, T> = (&'b u32, Vec<T>); + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:47:12 + | +LL | type T1<U: Bound> = U::Assoc; + | ^^^^^ + | +help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:47:21 + | +LL | type T1<U: Bound> = U::Assoc; + | ^^^^^^^^ +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type T1<U: Bound> = U::Assoc; +LL + type T1<U> = U::Assoc; + | + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:48:18 + | +LL | type T2<U> where U: Bound = U::Assoc; + | ^^^^^^^^ + | +help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:48:29 + | +LL | type T2<U> where U: Bound = U::Assoc; + | ^^^^^^^^ +help: the clause will not be checked when the type alias is used, and should be removed + | +LL - type T2<U> where U: Bound = U::Assoc; +LL + type T2<U> = U::Assoc; + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:56:12 + | +LL | type T5<U: Bound> = <U as Bound>::Assoc; + | ^^^^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type T5<U: Bound> = <U as Bound>::Assoc; +LL + type T5<U> = <U as Bound>::Assoc; + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:57:12 + | +LL | type T6<U: Bound> = ::std::vec::Vec<U>; + | ^^^^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type T6<U: Bound> = ::std::vec::Vec<U>; +LL + type T6<U> = ::std::vec::Vec<U>; + | + +warning: 9 warnings emitted + diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs new file mode 100644 index 000000000..347887f4b --- /dev/null +++ b/src/test/ui/type/type-annotation-needed.rs @@ -0,0 +1,10 @@ +fn foo<T: Into<String>>(x: i32) {} +//~^ NOTE required by +//~| NOTE required by + +fn main() { + foo(42); + //~^ ERROR type annotations needed + //~| NOTE cannot infer type + //~| NOTE cannot satisfy +} diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr new file mode 100644 index 000000000..4af4c22f7 --- /dev/null +++ b/src/test/ui/type/type-annotation-needed.stderr @@ -0,0 +1,20 @@ +error[E0283]: type annotations needed + --> $DIR/type-annotation-needed.rs:6:5 + | +LL | foo(42); + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | + = note: cannot satisfy `_: Into<String>` +note: required by a bound in `foo` + --> $DIR/type-annotation-needed.rs:1:11 + | +LL | fn foo<T: Into<String>>(x: i32) {} + | ^^^^^^^^^^^^ required by this bound in `foo` +help: consider specifying the type argument in the function call + | +LL | foo::<T>(42); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type/type-arg-out-of-scope.rs b/src/test/ui/type/type-arg-out-of-scope.rs new file mode 100644 index 000000000..02aad0077 --- /dev/null +++ b/src/test/ui/type/type-arg-out-of-scope.rs @@ -0,0 +1,5 @@ +// error-pattern:can't use generic parameters from outer function +fn foo<T>(x: T) { + fn bar(f: Box<dyn FnMut(T) -> T>) { } +} +fn main() { foo(1); } diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr new file mode 100644 index 000000000..0b6283fbc --- /dev/null +++ b/src/test/ui/type/type-arg-out-of-scope.stderr @@ -0,0 +1,23 @@ +error[E0401]: can't use generic parameters from outer function + --> $DIR/type-arg-out-of-scope.rs:3:29 + | +LL | fn foo<T>(x: T) { + | - type parameter from outer function +LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } + | --- ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `bar<T>` + +error[E0401]: can't use generic parameters from outer function + --> $DIR/type-arg-out-of-scope.rs:3:35 + | +LL | fn foo<T>(x: T) { + | - type parameter from outer function +LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } + | --- ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `bar<T>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.rs b/src/test/ui/type/type-ascription-instead-of-initializer.rs new file mode 100644 index 000000000..9f9b6f06b --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-initializer.rs @@ -0,0 +1,4 @@ +fn main() { + let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10` + //~^ ERROR this function takes 1 argument +} diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr new file mode 100644 index 000000000..fcac6c495 --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr @@ -0,0 +1,28 @@ +error: expected type, found `10` + --> $DIR/type-ascription-instead-of-initializer.rs:2:31 + | +LL | let x: Vec::with_capacity(10, 20); + | -- ^^ expected type + | || + | |help: use `=` if you meant to assign + | while parsing the type for `x` + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/type-ascription-instead-of-initializer.rs:2:12 + | +LL | let x: Vec::with_capacity(10, 20); + | ^^^^^^^^^^^^^^^^^^ -- argument of type `{integer}` unexpected + | +note: associated function defined here + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub fn with_capacity(capacity: usize) -> Self { + | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL | let x: Vec::with_capacity(10); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.rs b/src/test/ui/type/type-ascription-instead-of-statement-end.rs new file mode 100644 index 000000000..1d5565ab5 --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.rs @@ -0,0 +1,10 @@ +#![feature(type_ascription)] + +fn main() { + println!("test"): + 0; //~ ERROR expected type, found `0` +} + +fn foo() { + println!("test"): 0; //~ ERROR expected type, found `0` +} diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr new file mode 100644 index 000000000..521ebcdf1 --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -0,0 +1,24 @@ +error: expected type, found `0` + --> $DIR/type-ascription-instead-of-statement-end.rs:5:5 + | +LL | println!("test"): + | - help: try using a semicolon: `;` +LL | 0; + | ^ expected type + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + +error: expected type, found `0` + --> $DIR/type-ascription-instead-of-statement-end.rs:9:23 + | +LL | println!("test"): 0; + | - ^ expected type + | | + | tried to parse a type due to this type ascription + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type/type-ascription-precedence.rs b/src/test/ui/type/type-ascription-precedence.rs new file mode 100644 index 000000000..d3aef929b --- /dev/null +++ b/src/test/ui/type/type-ascription-precedence.rs @@ -0,0 +1,54 @@ +// Operator precedence of type ascription +// Type ascription has very high precedence, the same as operator `as` + +#![feature(type_ascription)] + +use std::ops::*; + +struct S; +struct Z; + +impl Add<Z> for S { + type Output = S; + fn add(self, _rhs: Z) -> S { panic!() } +} +impl Mul<Z> for S { + type Output = S; + fn mul(self, _rhs: Z) -> S { panic!() } +} +impl Neg for S { + type Output = Z; + fn neg(self) -> Z { panic!() } +} +impl Deref for S { + type Target = Z; + fn deref(&self) -> &Z { panic!() } +} + +fn main() { + &S: &S; // OK + (&S): &S; // OK + &(S: &S); //~ ERROR mismatched types + + *S: Z; // OK + (*S): Z; // OK + *(S: Z); //~ ERROR mismatched types + //~^ ERROR type `Z` cannot be dereferenced + + -S: Z; // OK + (-S): Z; // OK + -(S: Z); //~ ERROR mismatched types + //~^ ERROR cannot apply unary operator `-` to type `Z` + + S + Z: Z; // OK + S + (Z: Z); // OK + (S + Z): Z; //~ ERROR mismatched types + + S * Z: Z; // OK + S * (Z: Z); // OK + (S * Z): Z; //~ ERROR mismatched types + + S .. S: S; // OK + S .. (S: S); // OK + (S .. S): S; //~ ERROR mismatched types +} diff --git a/src/test/ui/type/type-ascription-precedence.stderr b/src/test/ui/type/type-ascription-precedence.stderr new file mode 100644 index 000000000..a8139063d --- /dev/null +++ b/src/test/ui/type/type-ascription-precedence.stderr @@ -0,0 +1,66 @@ +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:31:7 + | +LL | &(S: &S); + | ^ expected `&S`, found struct `S` + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:35:7 + | +LL | *(S: Z); + | ^ expected struct `Z`, found struct `S` + +error[E0614]: type `Z` cannot be dereferenced + --> $DIR/type-ascription-precedence.rs:35:5 + | +LL | *(S: Z); + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:40:7 + | +LL | -(S: Z); + | ^ expected struct `Z`, found struct `S` + +error[E0600]: cannot apply unary operator `-` to type `Z` + --> $DIR/type-ascription-precedence.rs:40:5 + | +LL | -(S: Z); + | ^^^^^^^ cannot apply unary operator `-` + | +note: an implementation of `std::ops::Neg` might be missing for `Z` + --> $DIR/type-ascription-precedence.rs:9:1 + | +LL | struct Z; + | ^^^^^^^^ must implement `std::ops::Neg` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Neg { + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:45:5 + | +LL | (S + Z): Z; + | ^^^^^^^ expected struct `Z`, found struct `S` + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:49:5 + | +LL | (S * Z): Z; + | ^^^^^^^ expected struct `Z`, found struct `S` + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:53:5 + | +LL | (S .. S): S; + | ^^^^^^^^ expected struct `S`, found struct `std::ops::Range` + | + = note: expected struct `S` + found struct `std::ops::Range<S>` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0600, E0614. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-ascription-soundness.rs b/src/test/ui/type/type-ascription-soundness.rs new file mode 100644 index 000000000..d583fc213 --- /dev/null +++ b/src/test/ui/type/type-ascription-soundness.rs @@ -0,0 +1,13 @@ +// Type ascription doesn't lead to unsoundness + +#![feature(type_ascription)] + +fn main() { + let arr = &[1u8, 2, 3]; + let ref x = arr: &[u8]; //~ ERROR mismatched types + let ref mut x = arr: &[u8]; //~ ERROR mismatched types + match arr: &[u8] { //~ ERROR mismatched types + ref x => {} + } + let _len = (arr: &[u8]).len(); //~ ERROR mismatched types +} diff --git a/src/test/ui/type/type-ascription-soundness.stderr b/src/test/ui/type/type-ascription-soundness.stderr new file mode 100644 index 000000000..6ed940823 --- /dev/null +++ b/src/test/ui/type/type-ascription-soundness.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:7:17 + | +LL | let ref x = arr: &[u8]; + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:8:21 + | +LL | let ref mut x = arr: &[u8]; + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:9:11 + | +LL | match arr: &[u8] { + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:12:17 + | +LL | let _len = (arr: &[u8]).len(); + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-ascription-with-fn-call.fixed b/src/test/ui/type/type-ascription-with-fn-call.fixed new file mode 100644 index 000000000..6d96c4303 --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.fixed @@ -0,0 +1,9 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() ; + f(); //~ ERROR expected type, found function +} + +fn f() {} diff --git a/src/test/ui/type/type-ascription-with-fn-call.rs b/src/test/ui/type/type-ascription-with-fn-call.rs new file mode 100644 index 000000000..ed4f7c904 --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.rs @@ -0,0 +1,9 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() : + f(); //~ ERROR expected type, found function +} + +fn f() {} diff --git a/src/test/ui/type/type-ascription-with-fn-call.stderr b/src/test/ui/type/type-ascription-with-fn-call.stderr new file mode 100644 index 000000000..d78fd08fd --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.stderr @@ -0,0 +1,11 @@ +error[E0573]: expected type, found function `f` + --> $DIR/type-ascription-with-fn-call.rs:6:5 + | +LL | f() : + | - help: maybe you meant to write `;` here +LL | f(); + | ^^^ expecting a type here because of type ascription + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0573`. diff --git a/src/test/ui/type/type-ascription.rs b/src/test/ui/type/type-ascription.rs new file mode 100644 index 000000000..7adb07442 --- /dev/null +++ b/src/test/ui/type/type-ascription.rs @@ -0,0 +1,39 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +// Type ascription doesn't lead to unsoundness + +#![feature(type_ascription)] + +use std::mem; + +const C1: u8 = 10: u8; +const C2: [u8; 1: usize] = [1]; + +struct S { + a: u8 +} + +fn main() { + assert_eq!(C1.into(): i32, 10); + assert_eq!(C2[0], 1); + + let s = S { a: 10: u8 }; + let arr = &[1u8, 2, 3]; + + let mut v = arr.iter().cloned().collect(): Vec<_>; + v.push(4); + assert_eq!(v, [1, 2, 3, 4]); + + let a = 1: u8; + let b = a.into(): u16; + assert_eq!(v[a.into(): usize], 2); + assert_eq!(mem::size_of_val(&a), 1); + assert_eq!(mem::size_of_val(&b), 2); + assert_eq!(b, 1: u16); + + let mut v = Vec::new(); + v: Vec<u8> = vec![1, 2, 3]; // Place expression type ascription + assert_eq!(v, [1u8, 2, 3]); +} diff --git a/src/test/ui/type/type-check-defaults.rs b/src/test/ui/type/type-check-defaults.rs new file mode 100644 index 000000000..6a0a7ed33 --- /dev/null +++ b/src/test/ui/type/type-check-defaults.rs @@ -0,0 +1,27 @@ +use std::iter::FromIterator; +use std::vec::IntoIter; +use std::ops::Add; + +struct Foo<T, U: FromIterator<T>>(T, U); +struct WellFormed<Z = Foo<i32, i32>>(Z); +//~^ ERROR a value of type `i32` cannot be built from an iterator over elements of type `i32` +struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z); +//~^ ERROR a value of type `i32` cannot be built from an iterator over elements of type `i32` + +struct Bounds<T:Copy=String>(T); +//~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] + +struct WhereClause<T=String>(T) where T: Copy; +//~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] + +trait TraitBound<T:Copy=String> {} +//~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] + +trait Super<T: Copy> { } +trait Base<T = String>: Super<T> { } +//~^ ERROR the trait bound `T: Copy` is not satisfied [E0277] + +trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {} +//~^ ERROR cannot add `u8` to `i32` [E0277] + +fn main() { } diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr new file mode 100644 index 000000000..56a9b5317 --- /dev/null +++ b/src/test/ui/type/type-check-defaults.stderr @@ -0,0 +1,81 @@ +error[E0277]: a value of type `i32` cannot be built from an iterator over elements of type `i32` + --> $DIR/type-check-defaults.rs:6:19 + | +LL | struct WellFormed<Z = Foo<i32, i32>>(Z); + | ^^^^^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>` + | + = help: the trait `FromIterator<i32>` is not implemented for `i32` +note: required by a bound in `Foo` + --> $DIR/type-check-defaults.rs:5:18 + | +LL | struct Foo<T, U: FromIterator<T>>(T, U); + | ^^^^^^^^^^^^^^^ required by this bound in `Foo` + +error[E0277]: a value of type `i32` cannot be built from an iterator over elements of type `i32` + --> $DIR/type-check-defaults.rs:8:27 + | +LL | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z); + | ^^^^^^^^^^^^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>` + | + = help: the trait `FromIterator<i32>` is not implemented for `i32` +note: required by a bound in `Foo` + --> $DIR/type-check-defaults.rs:5:18 + | +LL | struct Foo<T, U: FromIterator<T>>(T, U); + | ^^^^^^^^^^^^^^^ required by this bound in `Foo` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:11:17 + | +LL | struct Bounds<T:Copy=String>(T); + | ^^^^ the trait `Copy` is not implemented for `String` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:14:42 + | +LL | struct WhereClause<T=String>(T) where T: Copy; + | ^^^^ the trait `Copy` is not implemented for `String` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:17:20 + | +LL | trait TraitBound<T:Copy=String> {} + | ^^^^ the trait `Copy` is not implemented for `String` + +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:21:25 + | +LL | trait Base<T = String>: Super<T> { } + | ^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `Super` + --> $DIR/type-check-defaults.rs:20:16 + | +LL | trait Super<T: Copy> { } + | ^^^^ required by this bound in `Super` +help: consider further restricting type parameter `T` + | +LL | trait Base<T = String>: Super<T> where T: std::marker::Copy { } + | ++++++++++++++++++++++++++ + +error[E0277]: cannot add `u8` to `i32` + --> $DIR/type-check-defaults.rs:24:66 + | +LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {} + | ^^^^^^^ no implementation for `i32 + u8` + | + = help: the trait `Add<u8>` is not implemented for `i32` + = help: the following other types implement trait `Add<Rhs>`: + <&'a f32 as Add<f32>> + <&'a f64 as Add<f64>> + <&'a i128 as Add<i128>> + <&'a i16 as Add<i16>> + <&'a i32 as Add<i32>> + <&'a i64 as Add<i64>> + <&'a i8 as Add<i8>> + <&'a isize as Add<isize>> + and 48 others + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type/type-check/assignment-expected-bool.rs b/src/test/ui/type/type-check/assignment-expected-bool.rs new file mode 100644 index 000000000..191939bdb --- /dev/null +++ b/src/test/ui/type/type-check/assignment-expected-bool.rs @@ -0,0 +1,34 @@ +// The purpose of this text is to ensure that we get good +// diagnostics when a `bool` is expected but that due to +// an assignment expression `x = y` the type is `()`. + +fn main() { + let _: bool = 0 = 0; //~ ERROR mismatched types [E0308] + + let _: bool = match 0 { + 0 => 0 = 0, //~ ERROR mismatched types [E0308] + _ => 0 = 0, //~ ERROR mismatched types [E0308] + }; + + let _: bool = match true { + true => 0 = 0, //~ ERROR mismatched types [E0308] + _ => (), + }; + + if 0 = 0 {} //~ ERROR mismatched types [E0308] + + let _: bool = if { 0 = 0 } { //~ ERROR mismatched types [E0308] + 0 = 0 //~ ERROR mismatched types [E0308] + } else { + 0 = 0 //~ ERROR mismatched types [E0308] + }; + + let _ = (0 = 0) //~ ERROR mismatched types [E0308] + && { 0 = 0 } //~ ERROR mismatched types [E0308] + || (0 = 0); //~ ERROR mismatched types [E0308] + + // A test to check that not expecting `bool` behaves well: + let _: usize = 0 = 0; + //~^ ERROR mismatched types [E0308] + //~| ERROR invalid left-hand side of assignment [E0070] +} diff --git a/src/test/ui/type/type-check/assignment-expected-bool.stderr b/src/test/ui/type/type-check/assignment-expected-bool.stderr new file mode 100644 index 000000000..e2b821f7b --- /dev/null +++ b/src/test/ui/type/type-check/assignment-expected-bool.stderr @@ -0,0 +1,141 @@ +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:6:19 + | +LL | let _: bool = 0 = 0; + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _: bool = 0 == 0; + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:9:14 + | +LL | 0 => 0 = 0, + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 => 0 == 0, + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:10:14 + | +LL | _ => 0 = 0, + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | _ => 0 == 0, + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:14:17 + | +LL | true => 0 = 0, + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | true => 0 == 0, + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:18:8 + | +LL | if 0 = 0 {} + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if 0 == 0 {} + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:20:24 + | +LL | let _: bool = if { 0 = 0 } { + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _: bool = if { 0 == 0 } { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:21:9 + | +LL | 0 = 0 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 == 0 + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:23:9 + | +LL | 0 = 0 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 == 0 + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:26:13 + | +LL | let _ = (0 = 0) + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _ = (0 == 0) + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:27:14 + | +LL | && { 0 = 0 } + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | && { 0 == 0 } + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:28:12 + | +LL | || (0 = 0); + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | || (0 == 0); + | ~~ + +error[E0070]: invalid left-hand side of assignment + --> $DIR/assignment-expected-bool.rs:31:22 + | +LL | let _: usize = 0 = 0; + | - ^ + | | + | cannot assign to this expression + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:31:20 + | +LL | let _: usize = 0 = 0; + | ----- ^^^^^ expected `usize`, found `()` + | | + | expected due to this + +error: aborting due to 13 previous errors + +Some errors have detailed explanations: E0070, E0308. +For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/type/type-check/assignment-in-if.rs b/src/test/ui/type/type-check/assignment-in-if.rs new file mode 100644 index 000000000..8da7b32b4 --- /dev/null +++ b/src/test/ui/type/type-check/assignment-in-if.rs @@ -0,0 +1,43 @@ +// Test that the parser does not attempt to parse struct literals +// within assignments in if expressions. + +#![allow(unused_parens)] + +struct Foo { + foo: usize +} + +fn main() { + let x = 1; + let y: Foo; + + // `x { ... }` should not be interpreted as a struct literal here + if x = x { + //~^ ERROR mismatched types + println!("{}", x); + } + // Explicit parentheses on the left should match behavior of above + if (x = x) { + //~^ ERROR mismatched types + println!("{}", x); + } + // The struct literal interpretation is fine with explicit parentheses on the right + if y = (Foo { foo: x }) { + //~^ ERROR mismatched types + println!("{}", x); + } + // "invalid left-hand side of assignment" error is suppresed + if 3 = x { + //~^ ERROR mismatched types + println!("{}", x); + } + if ( + if true { + x = 4 //~ ERROR mismatched types + } else { + x = 5 //~ ERROR mismatched types + } + ) { + println!("{}", x); + } +} diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr new file mode 100644 index 000000000..f4ef44e24 --- /dev/null +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -0,0 +1,69 @@ +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:15:8 + | +LL | if x = x { + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == x { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:20:8 + | +LL | if (x = x) { + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if (x == x) { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:25:8 + | +LL | if y = (Foo { foo: x }) { + | ^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if y == (Foo { foo: x }) { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:30:8 + | +LL | if 3 = x { + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if 3 == x { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:36:13 + | +LL | x = 4 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | x == 4 + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:38:13 + | +LL | x = 5 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | x == 5 + | ~~ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.rs b/src/test/ui/type/type-check/cannot_infer_local_or_array.rs new file mode 100644 index 000000000..af7552523 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.rs @@ -0,0 +1,3 @@ +fn main() { + let x = []; //~ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr new file mode 100644 index 000000000..e823bad26 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `[_; 0]` + --> $DIR/cannot_infer_local_or_array.rs:2:9 + | +LL | let x = []; + | ^ -- type must be known at this point + | +help: consider giving `x` an explicit type, where the placeholders `_` are specified + | +LL | let x: [_; 0] = []; + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.rs b/src/test/ui/type/type-check/cannot_infer_local_or_vec.rs new file mode 100644 index 000000000..e72ddabf3 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.rs @@ -0,0 +1,4 @@ +fn main() { + let x = vec![]; + //~^ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr new file mode 100644 index 000000000..b63d2a3b6 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `Vec<T>` + --> $DIR/cannot_infer_local_or_vec.rs:2:9 + | +LL | let x = vec![]; + | ^ + | +help: consider giving `x` an explicit type, where the type for type parameter `T` is specified + | +LL | let x: Vec<T> = vec![]; + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs new file mode 100644 index 000000000..d21456439 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs @@ -0,0 +1,4 @@ +fn main() { + let (x, ) = (vec![], ); + //~^ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr new file mode 100644 index 000000000..be60cda68 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `(Vec<T>,)` + --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9 + | +LL | let (x, ) = (vec![], ); + | ^^^^^ + | +help: consider giving this pattern a type, where the type for type parameter `T` is specified + | +LL | let (x, ): (Vec<T>,) = (vec![], ); + | +++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/issue-22897.rs b/src/test/ui/type/type-check/issue-22897.rs new file mode 100644 index 000000000..8171a0ef1 --- /dev/null +++ b/src/test/ui/type/type-check/issue-22897.rs @@ -0,0 +1,5 @@ +fn main() { } + +fn unconstrained_type() { + []; //~ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/issue-22897.stderr b/src/test/ui/type/type-check/issue-22897.stderr new file mode 100644 index 000000000..fae7b7926 --- /dev/null +++ b/src/test/ui/type/type-check/issue-22897.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/issue-22897.rs:4:5 + | +LL | []; + | ^^ cannot infer type for array `[_; 0]` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/issue-40294.rs b/src/test/ui/type/type-check/issue-40294.rs new file mode 100644 index 000000000..5493a4e5f --- /dev/null +++ b/src/test/ui/type/type-check/issue-40294.rs @@ -0,0 +1,13 @@ +trait Foo: Sized { + fn foo(self); +} + +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, //~ ERROR type annotations needed + &'b T : Foo +{ + x.foo(); + y.foo(); +} + +fn main() { } diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr new file mode 100644 index 000000000..75feb5698 --- /dev/null +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -0,0 +1,11 @@ +error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo` + --> $DIR/issue-40294.rs:6:19 + | +LL | where &'a T : Foo, + | ^^^ + | + = note: cannot satisfy `&'a T: Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type/type-check/issue-41314.rs b/src/test/ui/type/type-check/issue-41314.rs new file mode 100644 index 000000000..cbd39f5f9 --- /dev/null +++ b/src/test/ui/type/type-check/issue-41314.rs @@ -0,0 +1,10 @@ +enum X { + Y(u32) +} + +fn main() { + match X::Y(0) { + X::Y { number } => {} + //~^ ERROR tuple variant `X::Y` written as struct variant + } +} diff --git a/src/test/ui/type/type-check/issue-41314.stderr b/src/test/ui/type/type-check/issue-41314.stderr new file mode 100644 index 000000000..4a9bf6106 --- /dev/null +++ b/src/test/ui/type/type-check/issue-41314.stderr @@ -0,0 +1,14 @@ +error[E0769]: tuple variant `X::Y` written as struct variant + --> $DIR/issue-41314.rs:7:9 + | +LL | X::Y { number } => {} + | ^^^^^^^^^^^^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL | X::Y(number) => {} + | ~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0769`. diff --git a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs new file mode 100644 index 000000000..c39ab9544 --- /dev/null +++ b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs @@ -0,0 +1,27 @@ +fn main() { + let mut i: i64; + // Expected type is an inference variable `?T` + // because the `match` is used as a statement. + // This is the "initial" type of the `coercion`. + match i { + // Add `bool` to the overall `coercion`. + 0 => true, + + // Necessary to cause the ICE: + 1 => true, + + // Suppose that we had `let _: bool = match i { ... }`. + // In that case, as the expected type would be `bool`, + // we would suggest `i == 1` as a fix. + // + // However, no type error happens when checking `i = 1` because `expected == ?T`, + // which will unify with `typeof(i = 1) == ()`. + // + // However, in #67273, we would delay the unification of this arm with the above + // because we used the hitherto accumulated coercion as opposed to the "initial" type. + 2 => i = 1, + //~^ ERROR `match` arms have incompatible types + + _ => (), + } +} diff --git a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr new file mode 100644 index 000000000..a431fe89c --- /dev/null +++ b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr @@ -0,0 +1,22 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs:22:14 + | +LL | / match i { +LL | | // Add `bool` to the overall `coercion`. +LL | | 0 => true, + | | ---- this is found to be of type `bool` +LL | | +LL | | // Necessary to cause the ICE: +LL | | 1 => true, + | | ---- this is found to be of type `bool` +... | +LL | | 2 => i = 1, + | | ^^^^^ expected `bool`, found `()` +... | +LL | | _ => (), +LL | | } + | |_____- `match` arms have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs new file mode 100644 index 000000000..e50cc5865 --- /dev/null +++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs @@ -0,0 +1,12 @@ +macro_rules! many_args { + ([$($t:tt)*]#$($h:tt)*) => { + many_args!{[$($t)*$($t)*]$($h)*} + }; + ([$($t:tt)*]) => { + fn _f($($t: ()),*) {} //~ ERROR function can not have more than 65535 arguments + } +} + +many_args!{[_]########## ######} + +fn main() {} diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr new file mode 100644 index 000000000..615fd2ccb --- /dev/null +++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr @@ -0,0 +1,13 @@ +error: function can not have more than 65535 arguments + --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24 + | +LL | fn _f($($t: ()),*) {} + | ________________________^ +LL | | } +LL | | } +LL | | +LL | | many_args!{[_]########## ######} + | |____________^ + +error: aborting due to previous error + diff --git a/src/test/ui/type/type-check/missing_trait_impl.rs b/src/test/ui/type/type-check/missing_trait_impl.rs new file mode 100644 index 000000000..0e3e703a2 --- /dev/null +++ b/src/test/ui/type/type-check/missing_trait_impl.rs @@ -0,0 +1,16 @@ +fn main() { +} + +fn foo<T>(x: T, y: T) { + let z = x + y; //~ ERROR cannot add `T` to `T` +} + +fn bar<T>(x: T) { + x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T` +} + +fn baz<T>(x: T) { + let y = -x; //~ ERROR cannot apply unary operator `-` to type `T` + let y = !x; //~ ERROR cannot apply unary operator `!` to type `T` + let y = *x; //~ ERROR type `T` cannot be dereferenced +} diff --git a/src/test/ui/type/type-check/missing_trait_impl.stderr b/src/test/ui/type/type-check/missing_trait_impl.stderr new file mode 100644 index 000000000..2b58cd418 --- /dev/null +++ b/src/test/ui/type/type-check/missing_trait_impl.stderr @@ -0,0 +1,58 @@ +error[E0369]: cannot add `T` to `T` + --> $DIR/missing_trait_impl.rs:5:15 + | +LL | let z = x + y; + | - ^ - T + | | + | T + | +help: consider restricting type parameter `T` + | +LL | fn foo<T: std::ops::Add>(x: T, y: T) { + | +++++++++++++++ + +error[E0368]: binary assignment operation `+=` cannot be applied to type `T` + --> $DIR/missing_trait_impl.rs:9:5 + | +LL | x += x; + | -^^^^^ + | | + | cannot use `+=` on type `T` + | +help: consider restricting type parameter `T` + | +LL | fn bar<T: std::ops::AddAssign>(x: T) { + | +++++++++++++++++++++ + +error[E0600]: cannot apply unary operator `-` to type `T` + --> $DIR/missing_trait_impl.rs:13:13 + | +LL | let y = -x; + | ^^ cannot apply unary operator `-` + | +help: consider restricting type parameter `T` + | +LL | fn baz<T: std::ops::Neg>(x: T) { + | +++++++++++++++ + +error[E0600]: cannot apply unary operator `!` to type `T` + --> $DIR/missing_trait_impl.rs:14:13 + | +LL | let y = !x; + | ^^ cannot apply unary operator `!` + | +help: consider restricting type parameter `T` + | +LL | fn baz<T: std::ops::Not>(x: T) { + | +++++++++++++++ + +error[E0614]: type `T` cannot be dereferenced + --> $DIR/missing_trait_impl.rs:15:13 + | +LL | let y = *x; + | ^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0368, E0369, E0600, E0614. +For more information about an error, try `rustc --explain E0368`. diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.rs b/src/test/ui/type/type-check/unknown_type_for_closure.rs new file mode 100644 index 000000000..167687c18 --- /dev/null +++ b/src/test/ui/type/type-check/unknown_type_for_closure.rs @@ -0,0 +1,17 @@ +fn infer_in_arg() { + let x = |b: Vec<_>| {}; //~ ERROR E0282 +} + +fn empty_pattern() { + let x = |_| {}; //~ ERROR type annotations needed +} + +fn infer_ty() { + let x = |k: _| {}; //~ ERROR type annotations needed +} + +fn ambig_return() { + let x = || -> Vec<_> { Vec::new() }; //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.stderr b/src/test/ui/type/type-check/unknown_type_for_closure.stderr new file mode 100644 index 000000000..9ae97f390 --- /dev/null +++ b/src/test/ui/type/type-check/unknown_type_for_closure.stderr @@ -0,0 +1,37 @@ +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:2:13 + | +LL | let x = |b: Vec<_>| {}; + | ^^^^^^^^^^^^^^ cannot infer type for struct `Vec<_>` + +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:6:14 + | +LL | let x = |_| {}; + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | let x = |_: _| {}; + | +++ + +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:10:14 + | +LL | let x = |k: _| {}; + | ^ cannot infer type + +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:14:28 + | +LL | let x = || -> Vec<_> { Vec::new() }; + | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec` + | +help: consider specifying the generic argument + | +LL | let x = || -> Vec<_> { Vec::<T>::new() }; + | +++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs new file mode 100644 index 000000000..f37f093d9 --- /dev/null +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -0,0 +1,6 @@ +fn main() { + let v = vec![0]; + const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant + let s: [u32; l] = v.into_iter().collect(); + //~^ERROR evaluation of constant value failed +} diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr new file mode 100644 index 000000000..02f267c6c --- /dev/null +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -0,0 +1,18 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/type-dependent-def-issue-49241.rs:3:22 + | +LL | const l: usize = v.count(); + | ------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let l` + +error[E0080]: evaluation of constant value failed + --> $DIR/type-dependent-def-issue-49241.rs:4:18 + | +LL | let s: [u32; l] = v.into_iter().collect(); + | ^ referenced constant has errors + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0080, E0435. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/type/type-error-break-tail.rs b/src/test/ui/type/type-error-break-tail.rs new file mode 100644 index 000000000..d4e3e93d0 --- /dev/null +++ b/src/test/ui/type/type-error-break-tail.rs @@ -0,0 +1,8 @@ +fn loop_ending() -> i32 { + loop { + if false { break; } //~ ERROR mismatched types + return 42; + } +} + +fn main() {} diff --git a/src/test/ui/type/type-error-break-tail.stderr b/src/test/ui/type/type-error-break-tail.stderr new file mode 100644 index 000000000..16dc6475c --- /dev/null +++ b/src/test/ui/type/type-error-break-tail.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/type-error-break-tail.rs:3:20 + | +LL | fn loop_ending() -> i32 { + | --- expected `i32` because of return type +LL | loop { +LL | if false { break; } + | ^^^^^ + | | + | expected `i32`, found `()` + | help: give it a value of the expected type: `break 42` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch-multiple.rs b/src/test/ui/type/type-mismatch-multiple.rs new file mode 100644 index 000000000..55d6ceef1 --- /dev/null +++ b/src/test/ui/type/type-mismatch-multiple.rs @@ -0,0 +1,7 @@ +// Checking that the compiler reports multiple type errors at once + +fn main() { let a: bool = 1; let b: i32 = true; } +//~^ ERROR mismatched types +//~| expected `bool`, found integer +//~| ERROR mismatched types +//~| expected `i32`, found `bool` diff --git a/src/test/ui/type/type-mismatch-multiple.stderr b/src/test/ui/type/type-mismatch-multiple.stderr new file mode 100644 index 000000000..2e8654d31 --- /dev/null +++ b/src/test/ui/type/type-mismatch-multiple.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-multiple.rs:3:27 + | +LL | fn main() { let a: bool = 1; let b: i32 = true; } + | ---- ^ expected `bool`, found integer + | | + | expected due to this + +error[E0308]: mismatched types + --> $DIR/type-mismatch-multiple.rs:3:43 + | +LL | fn main() { let a: bool = 1; let b: i32 = true; } + | --- ^^^^ expected `i32`, found `bool` + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch-same-crate-name.rs b/src/test/ui/type/type-mismatch-same-crate-name.rs new file mode 100644 index 000000000..c9cdc874c --- /dev/null +++ b/src/test/ui/type/type-mismatch-same-crate-name.rs @@ -0,0 +1,27 @@ +// aux-build:crate_a1.rs +// aux-build:crate_a2.rs + +// This tests the extra note reported when a type error deals with +// seemingly identical types. +// The main use case of this error is when there are two crates +// (generally different versions of the same crate) with the same name +// causing a type mismatch. Here, we simulate that error using block-scoped +// aliased `extern crate` declarations. + +fn main() { + let foo2 = {extern crate crate_a2 as a; a::Foo}; + let bar2 = {extern crate crate_a2 as a; a::bar()}; + { + extern crate crate_a1 as a; + a::try_foo(foo2); + //~^ ERROR mismatched types + //~| perhaps two different versions of crate `crate_a1` + //~| expected struct `main::a::Foo` + a::try_bar(bar2); + //~^ ERROR mismatched types + //~| perhaps two different versions of crate `crate_a1` + //~| expected trait `main::a::Bar` + //~| expected struct `Box<(dyn main::a::Bar + 'static)>` + //~| found struct `Box<dyn main::a::Bar>` + } +} diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr new file mode 100644 index 000000000..783f747fa --- /dev/null +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-same-crate-name.rs:16:20 + | +LL | a::try_foo(foo2); + | ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo` + | | + | arguments to this function are incorrect + | + = note: perhaps two different versions of crate `crate_a1` are being used? +note: function defined here + --> $DIR/auxiliary/crate_a1.rs:10:8 + | +LL | pub fn try_foo(x: Foo){} + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-mismatch-same-crate-name.rs:20:20 + | +LL | a::try_bar(bar2); + | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<(dyn main::a::Bar + 'static)>` + found struct `Box<dyn main::a::Bar>` + = note: perhaps two different versions of crate `crate_a1` are being used? +note: function defined here + --> $DIR/auxiliary/crate_a1.rs:11:8 + | +LL | pub fn try_bar(x: Box<Bar>){} + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch.rs b/src/test/ui/type/type-mismatch.rs new file mode 100644 index 000000000..11bfa3a72 --- /dev/null +++ b/src/test/ui/type/type-mismatch.rs @@ -0,0 +1,78 @@ +#![allow(non_camel_case_types)] + +trait Qux {} +struct A; +struct B; +impl Qux for A {} +impl Qux for B {} + +struct Foo<T, U: Qux = A, V: Qux = B>(T, U, V); + +struct foo; +struct bar; + +fn want<T>(t: T) {} + +fn have_usize(f: usize) { + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types +} + +fn have_foo(f: foo) { + want::<usize>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types +} + +fn have_foo_foo(f: Foo<foo>) { + want::<usize>(f); //~ ERROR mismatched types + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types + want::<&Foo<foo>>(f); //~ ERROR mismatched types + want::<&Foo<foo, B>>(f); //~ ERROR mismatched types +} + +fn have_foo_foo_b(f: Foo<foo, B>) { + want::<usize>(f); //~ ERROR mismatched types + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types + want::<&Foo<foo>>(f); //~ ERROR mismatched types + want::<&Foo<foo, B>>(f); //~ ERROR mismatched types +} + +fn have_foo_foo_b_a(f: Foo<foo, B, A>) { + want::<usize>(f); //~ ERROR mismatched types + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types + want::<&Foo<foo>>(f); //~ ERROR mismatched types + want::<&Foo<foo, B>>(f); //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/type/type-mismatch.stderr b/src/test/ui/type/type-mismatch.stderr new file mode 100644 index 000000000..6c187bad0 --- /dev/null +++ b/src/test/ui/type/type-mismatch.stderr @@ -0,0 +1,751 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:17:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:18:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:19:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:20:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, B>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:21:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:22:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo, B>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:23:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:24:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, B>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:28:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:29:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:30:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:31:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, B>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:32:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:33:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo, B>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:34:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:35:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, B>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:39:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected type `usize` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:40:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `foo` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:41:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `bar` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:42:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:43:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, B>` + found struct `Foo<foo, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:44:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `B`, found struct `A` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, B>` + found struct `Foo<_, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:45:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:46:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, B>` + found struct `Foo<foo, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:47:23 + | +LL | want::<&Foo<foo>>(f); + | ----------------- ^ + | | | + | | expected `&Foo<foo>`, found struct `Foo` + | | help: consider borrowing here: `&f` + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:48:26 + | +LL | want::<&Foo<foo, B>>(f); + | -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo, B>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:52:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected type `usize` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:53:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `foo` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:54:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `bar` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:55:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, A>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:56:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, _>` + found struct `Foo<foo, _>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:57:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `A`, found struct `B` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, A>` + found struct `Foo<_, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:58:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, A>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:59:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, _>` + found struct `Foo<foo, _>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:60:23 + | +LL | want::<&Foo<foo>>(f); + | ----------------- ^ expected `&Foo<foo>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:61:26 + | +LL | want::<&Foo<foo, B>>(f); + | -------------------- ^ + | | | + | | expected `&Foo<foo, B>`, found struct `Foo` + | | help: consider borrowing here: `&f` + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo, B>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:65:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected type `usize` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:66:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `foo` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:67:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `bar` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:68:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, A, B>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:69:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, _, B>` + found struct `Foo<foo, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:70:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `A`, found struct `B` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, A, B>` + found struct `Foo<_, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:71:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `B`, found struct `A` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, _, B>` + found struct `Foo<_, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:72:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, A, B>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:73:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, _, B>` + found struct `Foo<foo, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:74:23 + | +LL | want::<&Foo<foo>>(f); + | ----------------- ^ expected `&Foo<foo>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:75:26 + | +LL | want::<&Foo<foo, B>>(f); + | -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo, B>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error: aborting due to 47 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs new file mode 100644 index 000000000..444453dc6 --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs @@ -0,0 +1,17 @@ +// Test a default that references `Self` which is then used in an +// object type. Issue #18956. In this case, the value is supplied by +// the user, but pretty-printing the type during the error message +// caused an ICE. + +trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; } + +impl MyAdd for i32 { + fn add(&self, other: &i32) -> i32 { *self + *other } +} + +fn main() { + let x: i32 = 5; + let y = x as dyn MyAdd<i32>; + //~^ ERROR E0038 + //~| ERROR cast to unsized type: `i32` as `dyn MyAdd<i32>` +} diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr new file mode 100644 index 000000000..8a296dc7e --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -0,0 +1,31 @@ +error[E0620]: cast to unsized type: `i32` as `dyn MyAdd<i32>` + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:13 + | +LL | let y = x as dyn MyAdd<i32>; + | ^^^^^^^^^^^^^^^^^^^ + | +help: consider using a box or reference as appropriate + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:13 + | +LL | let y = x as dyn MyAdd<i32>; + | ^ + +error[E0038]: the trait `MyAdd` cannot be made into an object + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 + | +LL | let y = x as dyn MyAdd<i32>; + | ^^^^^^^^^^^^^^ `MyAdd` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55 + | +LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; } + | ----- ^^^^ ...because method `add` references the `Self` type in its return type + | | + | this trait cannot be made into an object... + = help: consider moving `add` to another trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0620. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self.rs b/src/test/ui/type/type-parameter-defaults-referencing-Self.rs new file mode 100644 index 000000000..e5c81556e --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self.rs @@ -0,0 +1,11 @@ +// Test a default that references `Self` which is then used in an object type. +// Issue #18956. + +trait Foo<T=Self> { + fn method(&self); +} + +fn foo(x: &dyn Foo) { } +//~^ ERROR the type parameter `T` must be explicitly specified + +fn main() { } diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self.stderr new file mode 100644 index 000000000..67a4745b3 --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self.stderr @@ -0,0 +1,14 @@ +error[E0393]: the type parameter `T` must be explicitly specified + --> $DIR/type-parameter-defaults-referencing-Self.rs:8:16 + | +LL | trait Foo<T=Self> { + | ----------------- type parameter `T` must be specified for this +... +LL | fn foo(x: &dyn Foo) { } + | ^^^ help: set the type parameter to the desired type: `Foo<T>` + | + = note: because of the default `Self` reference, type parameters must be specified on object types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0393`. diff --git a/src/test/ui/type/type-parameter-names.rs b/src/test/ui/type/type-parameter-names.rs new file mode 100644 index 000000000..b54a3fae0 --- /dev/null +++ b/src/test/ui/type/type-parameter-names.rs @@ -0,0 +1,12 @@ +// Test that we print out the names of type parameters correctly in +// our error messages. + +fn foo<Foo, Bar>(x: Foo) -> Bar { + x +//~^ ERROR mismatched types +//~| expected type parameter `Bar`, found type parameter `Foo` +//~| expected type parameter `Bar` +//~| found type parameter `Foo` +} + +fn main() {} diff --git a/src/test/ui/type/type-parameter-names.stderr b/src/test/ui/type/type-parameter-names.stderr new file mode 100644 index 000000000..f0ca8afca --- /dev/null +++ b/src/test/ui/type/type-parameter-names.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/type-parameter-names.rs:5:5 + | +LL | fn foo<Foo, Bar>(x: Foo) -> Bar { + | --- --- --- expected `Bar` because of return type + | | | + | | expected type parameter + | found type parameter +LL | x + | ^ expected type parameter `Bar`, found type parameter `Foo` + | + = note: expected type parameter `Bar` + found type parameter `Foo` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-params-in-different-spaces-1.rs b/src/test/ui/type/type-params-in-different-spaces-1.rs new file mode 100644 index 000000000..6efd14d37 --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-1.rs @@ -0,0 +1,18 @@ +use std::ops::Add; + +trait BrokenAdd: Copy + Add<Output=Self> { + fn broken_add<T>(&self, rhs: T) -> Self { + *self + rhs //~ ERROR mismatched types + //~| expected type parameter `Self`, found type parameter `T` + //~| expected type parameter `Self` + //~| found type parameter `T` + } +} + +impl<T: Copy + Add<Output=T>> BrokenAdd for T {} + +pub fn main() { + let foo: u8 = 0; + let x: u8 = foo.broken_add("hello darkness my old friend".to_string()); + println!("{}", x); +} diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr new file mode 100644 index 000000000..4e73e10a3 --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/type-params-in-different-spaces-1.rs:5:17 + | +LL | trait BrokenAdd: Copy + Add<Output=Self> { + | ---------------------------------------- expected type parameter +LL | fn broken_add<T>(&self, rhs: T) -> Self { + | - found type parameter +LL | *self + rhs + | ^^^ expected type parameter `Self`, found type parameter `T` + | + = note: expected type parameter `Self` + found type parameter `T` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-params-in-different-spaces-2.rs b/src/test/ui/type/type-params-in-different-spaces-2.rs new file mode 100644 index 000000000..1211e465b --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-2.rs @@ -0,0 +1,21 @@ +// Test static calls to make sure that we align the Self and input +// type parameters on a trait correctly. + +trait Tr<T> : Sized { + fn op(_: T) -> Self; +} + +trait A: Tr<Self> { + fn test<U>(u: U) -> Self { + Tr::op(u) //~ ERROR E0277 + } +} + +trait B<T>: Tr<T> { + fn test<U>(u: U) -> Self { + Tr::op(u) //~ ERROR E0277 + } +} + +fn main() { +} diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr new file mode 100644 index 000000000..53610985f --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `Self: Tr<U>` is not satisfied + --> $DIR/type-params-in-different-spaces-2.rs:10:9 + | +LL | Tr::op(u) + | ^^^^^^ the trait `Tr<U>` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn test<U>(u: U) -> Self where Self: Tr<U> { + | +++++++++++++++++ + +error[E0277]: the trait bound `Self: Tr<U>` is not satisfied + --> $DIR/type-params-in-different-spaces-2.rs:16:9 + | +LL | Tr::op(u) + | ^^^^^^ the trait `Tr<U>` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn test<U>(u: U) -> Self where Self: Tr<U> { + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type/type-params-in-different-spaces-3.rs b/src/test/ui/type/type-params-in-different-spaces-3.rs new file mode 100644 index 000000000..ac7b0c11f --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-3.rs @@ -0,0 +1,7 @@ +trait Tr : Sized { + fn test<X>(u: X) -> Self { + u //~ ERROR mismatched types + } +} + +fn main() {} diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr new file mode 100644 index 000000000..c538d6731 --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/type-params-in-different-spaces-3.rs:3:9 + | +LL | trait Tr : Sized { + | ---------------- expected type parameter +LL | fn test<X>(u: X) -> Self { + | - ---- expected `Self` because of return type + | | + | found type parameter +LL | u + | ^ expected type parameter `Self`, found type parameter `X` + | + = note: expected type parameter `Self` + found type parameter `X` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-path-err-node-types.rs b/src/test/ui/type/type-path-err-node-types.rs new file mode 100644 index 000000000..b3795772e --- /dev/null +++ b/src/test/ui/type/type-path-err-node-types.rs @@ -0,0 +1,26 @@ +// Type arguments in unresolved entities (reporting errors before type checking) +// should have their types recorded. + +trait Tr<T> {} + +fn local_type() { + let _: Nonexistent<u8, Assoc = u16>; //~ ERROR cannot find type `Nonexistent` in this scope +} + +fn ufcs_trait() { + <u8 as Tr<u8>>::nonexistent(); //~ ERROR cannot find method or associated constant `nonexistent` +} + +fn ufcs_item() { + NonExistent::Assoc::<u8>; //~ ERROR undeclared type `NonExistent` +} + +fn method() { + nonexistent.nonexistent::<u8>(); //~ ERROR cannot find value `nonexistent` +} + +fn closure() { + let _ = |a, b: _| -> _ { 0 }; //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr new file mode 100644 index 000000000..c1ae10efa --- /dev/null +++ b/src/test/ui/type/type-path-err-node-types.stderr @@ -0,0 +1,39 @@ +error[E0433]: failed to resolve: use of undeclared type `NonExistent` + --> $DIR/type-path-err-node-types.rs:15:5 + | +LL | NonExistent::Assoc::<u8>; + | ^^^^^^^^^^^ use of undeclared type `NonExistent` + +error[E0412]: cannot find type `Nonexistent` in this scope + --> $DIR/type-path-err-node-types.rs:7:12 + | +LL | let _: Nonexistent<u8, Assoc = u16>; + | ^^^^^^^^^^^ not found in this scope + +error[E0576]: cannot find method or associated constant `nonexistent` in trait `Tr` + --> $DIR/type-path-err-node-types.rs:11:21 + | +LL | <u8 as Tr<u8>>::nonexistent(); + | ^^^^^^^^^^^ not found in `Tr` + +error[E0425]: cannot find value `nonexistent` in this scope + --> $DIR/type-path-err-node-types.rs:19:5 + | +LL | nonexistent.nonexistent::<u8>(); + | ^^^^^^^^^^^ not found in this scope + +error[E0282]: type annotations needed + --> $DIR/type-path-err-node-types.rs:23:14 + | +LL | let _ = |a, b: _| -> _ { 0 }; + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | let _ = |a: _, b: _| -> _ { 0 }; + | +++ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0282, E0412, E0425, E0433, E0576. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-recursive-box-shadowed.rs b/src/test/ui/type/type-recursive-box-shadowed.rs new file mode 100644 index 000000000..e141c2149 --- /dev/null +++ b/src/test/ui/type/type-recursive-box-shadowed.rs @@ -0,0 +1,12 @@ +//FIXME(compiler-errors): This fixup should suggest the full box path, not just `Box` + +struct Box<T> { + t: T, +} + +struct Foo { + //~^ ERROR recursive type `Foo` has infinite size + inner: Foo, +} + +fn main() {} diff --git a/src/test/ui/type/type-recursive-box-shadowed.stderr b/src/test/ui/type/type-recursive-box-shadowed.stderr new file mode 100644 index 000000000..c22d848f3 --- /dev/null +++ b/src/test/ui/type/type-recursive-box-shadowed.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `Foo` has infinite size + --> $DIR/type-recursive-box-shadowed.rs:7:1 + | +LL | struct Foo { + | ^^^^^^^^^^ recursive type has infinite size +LL | +LL | inner: Foo, + | --- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable + | +LL | inner: Box<Foo>, + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/type/type-recursive.rs b/src/test/ui/type/type-recursive.rs new file mode 100644 index 000000000..e8084f0d0 --- /dev/null +++ b/src/test/ui/type/type-recursive.rs @@ -0,0 +1,30 @@ +struct T1 { //~ ERROR E0072 + foo: isize, + foolish: T1, +} + +struct T2 { //~ ERROR E0072 + inner: Option<T2>, +} + +type OptionT3 = Option<T3>; + +struct T3 { //~ ERROR E0072 + inner: OptionT3, +} + +struct T4(Option<T4>); //~ ERROR E0072 + +enum T5 { //~ ERROR E0072 + Variant(Option<T5>), +} + +enum T6 { //~ ERROR E0072 + Variant{ field: Option<T6> }, +} + +struct T7 { //~ ERROR E0072 + foo: std::cell::Cell<Option<T7>>, +} + +fn main() { } diff --git a/src/test/ui/type/type-recursive.stderr b/src/test/ui/type/type-recursive.stderr new file mode 100644 index 000000000..320271028 --- /dev/null +++ b/src/test/ui/type/type-recursive.stderr @@ -0,0 +1,95 @@ +error[E0072]: recursive type `T1` has infinite size + --> $DIR/type-recursive.rs:1:1 + | +LL | struct T1 { + | ^^^^^^^^^ recursive type has infinite size +LL | foo: isize, +LL | foolish: T1, + | -- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T1` representable + | +LL | foolish: Box<T1>, + | ++++ + + +error[E0072]: recursive type `T2` has infinite size + --> $DIR/type-recursive.rs:6:1 + | +LL | struct T2 { + | ^^^^^^^^^ recursive type has infinite size +LL | inner: Option<T2>, + | ---------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T2` representable + | +LL | inner: Option<Box<T2>>, + | ++++ + + +error[E0072]: recursive type `T3` has infinite size + --> $DIR/type-recursive.rs:12:1 + | +LL | struct T3 { + | ^^^^^^^^^ recursive type has infinite size +LL | inner: OptionT3, + | -------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T3` representable + | +LL | inner: Box<OptionT3>, + | ++++ + + +error[E0072]: recursive type `T4` has infinite size + --> $DIR/type-recursive.rs:16:1 + | +LL | struct T4(Option<T4>); + | ^^^^^^^^^ ---------- recursive without indirection + | | + | recursive type has infinite size + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T4` representable + | +LL | struct T4(Option<Box<T4>>); + | ++++ + + +error[E0072]: recursive type `T5` has infinite size + --> $DIR/type-recursive.rs:18:1 + | +LL | enum T5 { + | ^^^^^^^ recursive type has infinite size +LL | Variant(Option<T5>), + | ---------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T5` representable + | +LL | Variant(Option<Box<T5>>), + | ++++ + + +error[E0072]: recursive type `T6` has infinite size + --> $DIR/type-recursive.rs:22:1 + | +LL | enum T6 { + | ^^^^^^^ recursive type has infinite size +LL | Variant{ field: Option<T6> }, + | ---------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T6` representable + | +LL | Variant{ field: Option<Box<T6>> }, + | ++++ + + +error[E0072]: recursive type `T7` has infinite size + --> $DIR/type-recursive.rs:26:1 + | +LL | struct T7 { + | ^^^^^^^^^ recursive type has infinite size +LL | foo: std::cell::Cell<Option<T7>>, + | --------------------------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T7` representable + | +LL | foo: Box<std::cell::Cell<Option<T7>>>, + | ++++ + + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/type/type-shadow.rs b/src/test/ui/type/type-shadow.rs new file mode 100644 index 000000000..48a68a390 --- /dev/null +++ b/src/test/ui/type/type-shadow.rs @@ -0,0 +1,8 @@ +fn main() { + type X = isize; + type Y = X; + if true { + type X = &'static str; + let y: Y = "hello"; //~ ERROR mismatched types + } +} diff --git a/src/test/ui/type/type-shadow.stderr b/src/test/ui/type/type-shadow.stderr new file mode 100644 index 000000000..25b4bff4d --- /dev/null +++ b/src/test/ui/type/type-shadow.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/type-shadow.rs:6:20 + | +LL | let y: Y = "hello"; + | - ^^^^^^^ expected `isize`, found `&str` + | | + | expected due to this + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-unsatisfiable.rs b/src/test/ui/type/type-unsatisfiable.rs new file mode 100644 index 000000000..7fbbb50dc --- /dev/null +++ b/src/test/ui/type/type-unsatisfiable.rs @@ -0,0 +1,59 @@ +// revisions: lib usage +//[lib] compile-flags: --crate-type=lib +//[lib] build-pass + +use std::ops::Sub; +trait Vector2 { + type ScalarType; + + fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self + where + Self: Sized; + + fn x(&self) -> Self::ScalarType; + fn y(&self) -> Self::ScalarType; +} + +impl<T> Sub for dyn Vector2<ScalarType = T> +where + T: Sub<Output = T>, + (dyn Vector2<ScalarType = T>): Sized, +{ + type Output = dyn Vector2<ScalarType = T>; + + fn sub(self, rhs: Self) -> Self::Output { + Self::from_values(self.x() - rhs.x(), self.y() - rhs.y()) + } +} + +struct Vec2 { + x: i32, + y: i32, +} + +impl Vector2 for Vec2 { + type ScalarType = i32; + + fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self + where + Self: Sized, + { + Self { x, y } + } + + fn x(&self) -> Self::ScalarType { + self.x + } + fn y(&self) -> Self::ScalarType { + self.y + } +} + +#[cfg(usage)] +fn main() { + let hey: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 }); + let word: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 }); + + let bar = *hey - *word; + //[usage]~^ ERROR cannot subtract +} diff --git a/src/test/ui/type/type-unsatisfiable.usage.stderr b/src/test/ui/type/type-unsatisfiable.usage.stderr new file mode 100644 index 000000000..56e2e30af --- /dev/null +++ b/src/test/ui/type/type-unsatisfiable.usage.stderr @@ -0,0 +1,11 @@ +error[E0369]: cannot subtract `(dyn Vector2<ScalarType = i32> + 'static)` from `dyn Vector2<ScalarType = i32>` + --> $DIR/type-unsatisfiable.rs:57:20 + | +LL | let bar = *hey - *word; + | ---- ^ ----- (dyn Vector2<ScalarType = i32> + 'static) + | | + | dyn Vector2<ScalarType = i32> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. |