diff options
Diffstat (limited to 'src/test/ui/traits/associated_type_bound')
16 files changed, 393 insertions, 0 deletions
diff --git a/src/test/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs b/src/test/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs new file mode 100644 index 000000000..471a6b836 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs @@ -0,0 +1,23 @@ +trait Bar { + type Baz; +} + +struct Foo<T> where T: Bar, <T as Bar>::Baz: String { //~ ERROR expected trait, found struct + t: T, +} + +struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String { //~ ERROR expected trait, found struct + t: &'a T, +} + +fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String { //~ ERROR expected trait, found struct +} + +fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { //~ ERROR expected trait, found +} + +fn issue_95327() where <u8 as Unresolved>::Assoc: String {} +//~^ ERROR expected trait, found struct +//~| ERROR use of undeclared type `Unresolved` + +fn main() {} diff --git a/src/test/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr b/src/test/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr new file mode 100644 index 000000000..9ca446a0a --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr @@ -0,0 +1,101 @@ +error[E0433]: failed to resolve: use of undeclared type `Unresolved` + --> $DIR/assoc_type_bound_with_struct.rs:19:31 + | +LL | fn issue_95327() where <u8 as Unresolved>::Assoc: String {} + | ^^^^^^^^^^ use of undeclared type `Unresolved` + +error[E0404]: expected trait, found struct `String` + --> $DIR/assoc_type_bound_with_struct.rs:5:46 + | +LL | struct Foo<T> where T: Bar, <T as Bar>::Baz: String { + | ^^^^^^ not a trait + | + ::: $SRC_DIR/alloc/src/string.rs:LL:COL + | +LL | pub trait ToString { + | ------------------ similarly named trait `ToString` defined here + | +help: constrain the associated type to `String` + | +LL | struct Foo<T> where T: Bar, T: Bar<Baz = String> { + | ~~~~~~~~~~~~~~~~~~~~ +help: a trait with a similar name exists + | +LL | struct Foo<T> where T: Bar, <T as Bar>::Baz: ToString { + | ~~~~~~~~ + +error[E0404]: expected trait, found struct `String` + --> $DIR/assoc_type_bound_with_struct.rs:9:54 + | +LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String { + | ^^^^^^ not a trait + | + ::: $SRC_DIR/alloc/src/string.rs:LL:COL + | +LL | pub trait ToString { + | ------------------ similarly named trait `ToString` defined here + | +help: constrain the associated type to `String` + | +LL | struct Qux<'a, T> where T: Bar, &'a T: Bar<Baz = String> { + | ~~~~~~~~~~~~~~~~~~~~~~~~ +help: a trait with a similar name exists + | +LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: ToString { + | ~~~~~~~~ + +error[E0404]: expected trait, found struct `String` + --> $DIR/assoc_type_bound_with_struct.rs:13:45 + | +LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String { + | ^^^^^^ not a trait + | + ::: $SRC_DIR/alloc/src/string.rs:LL:COL + | +LL | pub trait ToString { + | ------------------ similarly named trait `ToString` defined here + | +help: constrain the associated type to `String` + | +LL | fn foo<T: Bar>(_: T) where T: Bar<Baz = String> { + | ~~~~~~~~~~~~~~~~~~~~ +help: a trait with a similar name exists + | +LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: ToString { + | ~~~~~~~~ + +error[E0404]: expected trait, found struct `String` + --> $DIR/assoc_type_bound_with_struct.rs:16:57 + | +LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { + | ^^^^^^ not a trait + | + ::: $SRC_DIR/alloc/src/string.rs:LL:COL + | +LL | pub trait ToString { + | ------------------ similarly named trait `ToString` defined here + | +help: constrain the associated type to `String` + | +LL | fn qux<'a, T: Bar>(_: &'a T) where &'a T: Bar<Baz = String> { + | ~~~~~~~~~~~~~~~~~~~~~~~~ +help: a trait with a similar name exists + | +LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: ToString { + | ~~~~~~~~ + +error[E0404]: expected trait, found struct `String` + --> $DIR/assoc_type_bound_with_struct.rs:19:51 + | +LL | fn issue_95327() where <u8 as Unresolved>::Assoc: String {} + | ^^^^^^ help: a trait with a similar name exists: `ToString` + | + ::: $SRC_DIR/alloc/src/string.rs:LL:COL + | +LL | pub trait ToString { + | ------------------ similarly named trait `ToString` defined here + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0404, E0433. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.rs new file mode 100644 index 000000000..b1f124c7e --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.rs @@ -0,0 +1,14 @@ +// Check that we validate associated type bounds for trait objects + +trait X { + type Y: Clone; +} + +fn f<T: X + ?Sized>() { + None::<T::Y>.clone(); +} + +fn main() { + f::<dyn X<Y = str>>(); + //~^ ERROR the trait bound `str: Clone` is not satisfied +} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr new file mode 100644 index 000000000..bfbbe7fd2 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/check-trait-object-bounds-1.rs:12:5 + | +LL | f::<dyn X<Y = str>>(); + | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `f` + --> $DIR/check-trait-object-bounds-1.rs:7:9 + | +LL | fn f<T: X + ?Sized>() { + | ^ required by this bound in `f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2-ok.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2-ok.rs new file mode 100644 index 000000000..1422dda27 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2-ok.rs @@ -0,0 +1,15 @@ +// Make sure that we're handling bound lifetimes correctly when validating trait +// bounds. +// run-pass + +trait X<'a> { + type F: FnOnce(&i32) -> &'a i32; +} + +fn f<T: for<'r> X<'r> + ?Sized>() { + None::<T::F>.map(|f| f(&0)); +} + +fn main() { + f::<dyn for<'x> X<'x, F = fn(&i32) -> &'x i32>>(); +} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.rs new file mode 100644 index 000000000..eb2fb6e84 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.rs @@ -0,0 +1,15 @@ +// Check that we validate associated type bounds for trait objects when they +// have bound lifetimes + +trait X<'a> { + type F: FnOnce(&i32) -> &'a i32; +} + +fn f<T: for<'r> X<'r> + ?Sized>() { + None::<T::F>.map(|f| f(&0)); +} + +fn main() { + f::<dyn for<'x> X<'x, F = i32>>(); + //~^ expected a `FnOnce<(&i32,)>` closure, found `i32` +} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr new file mode 100644 index 000000000..46e8ce788 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr @@ -0,0 +1,16 @@ +error[E0277]: expected a `FnOnce<(&i32,)>` closure, found `i32` + --> $DIR/check-trait-object-bounds-2.rs:13:5 + | +LL | f::<dyn for<'x> X<'x, F = i32>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32` + | + = help: the trait `for<'r> FnOnce<(&'r i32,)>` is not implemented for `i32` +note: required by a bound in `f` + --> $DIR/check-trait-object-bounds-2.rs:8:9 + | +LL | fn f<T: for<'r> X<'r> + ?Sized>() { + | ^^^^^^^^^^^^^ required by this bound in `f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-3.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-3.rs new file mode 100644 index 000000000..ba04fd93a --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-3.rs @@ -0,0 +1,20 @@ +// Check that we validate associated type bounds for trait objects + +trait X<'a> { + type Y: Into<&'static str> + From<&'a str>; +} + +fn f<'a, T: X<'a> + ?Sized>(s: &'a str) -> &'static str { + T::Y::from(s).into() +} + +pub fn main() { + let z; + { + let s = String::from("abcdef"); + z = f::<dyn X<Y = &str>>(&s); + //~^ ERROR `s` does not live long enough + } + + println!("{}", z) +} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr new file mode 100644 index 000000000..ade552c4b --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr @@ -0,0 +1,15 @@ +error[E0597]: `s` does not live long enough + --> $DIR/check-trait-object-bounds-3.rs:15:34 + | +LL | z = f::<dyn X<Y = &str>>(&s); + | ---------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `s` is borrowed for `'static` +LL | +LL | } + | - `s` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.rs new file mode 100644 index 000000000..e9ca1563f --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.rs @@ -0,0 +1,17 @@ +// Check that we validate associated type bounds on super traits for trait +// objects + +trait Super { + type Y: Clone; +} + +trait X: Super {} + +fn f<T: X + ?Sized>() { + None::<T::Y>.clone(); +} + +fn main() { + f::<dyn X<Y = str>>(); + //~^ ERROR the trait bound `str: Clone` is not satisfied +} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr new file mode 100644 index 000000000..3ca36d5d2 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/check-trait-object-bounds-4.rs:15:5 + | +LL | f::<dyn X<Y = str>>(); + | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `f` + --> $DIR/check-trait-object-bounds-4.rs:10:9 + | +LL | fn f<T: X + ?Sized>() { + | ^ required by this bound in `f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.rs new file mode 100644 index 000000000..7d733ad26 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.rs @@ -0,0 +1,27 @@ +// Check that we validate associated type bounds on super traits for trait +// objects + +trait Is { + type T; +} + +impl<U> Is for U { + type T = U; +} + +trait Super { + type V; +} + +trait Obj: Super { + type U: Is<T = Self::V>; +} + +fn is_obj<T: ?Sized + Obj>(_: &T) {} + +fn f(x: &dyn Obj<U = i32, V = i64>) { + is_obj(x) + //~^ type mismatch resolving `<i32 as Is>::T == i64` +} + +fn main() {} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr new file mode 100644 index 000000000..4251c1a1e --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr @@ -0,0 +1,20 @@ +error[E0271]: type mismatch resolving `<i32 as Is>::T == i64` + --> $DIR/check-trait-object-bounds-5.rs:23:5 + | +LL | is_obj(x) + | ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64` + | +note: expected this to be `i64` + --> $DIR/check-trait-object-bounds-5.rs:9:14 + | +LL | type T = U; + | ^ +note: required by a bound in `is_obj` + --> $DIR/check-trait-object-bounds-5.rs:20:23 + | +LL | fn is_obj<T: ?Sized + Obj>(_: &T) {} + | ^^^ required by this bound in `is_obj` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.rs b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.rs new file mode 100644 index 000000000..cb196d67f --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.rs @@ -0,0 +1,24 @@ +// Check that we validate associated type bounds on super traits for trait +// objects + +trait Is { + type T; +} + +impl<U> Is for U { + type T = U; +} + +trait Obj { + type U: Is<T = Self::V>; + type V; +} + +fn is_obj<T: ?Sized + Obj>(_: &T) {} + +fn f(x: &dyn Obj<U = i32, V = i64>) { + is_obj(x) + //~^ ERROR type mismatch resolving `<i32 as Is>::T == i64` +} + +fn main() {} diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr new file mode 100644 index 000000000..5b23a513e --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr @@ -0,0 +1,20 @@ +error[E0271]: type mismatch resolving `<i32 as Is>::T == i64` + --> $DIR/check-trait-object-bounds-6.rs:20:5 + | +LL | is_obj(x) + | ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64` + | +note: expected this to be `i64` + --> $DIR/check-trait-object-bounds-6.rs:9:14 + | +LL | type T = U; + | ^ +note: required by a bound in `is_obj` + --> $DIR/check-trait-object-bounds-6.rs:17:23 + | +LL | fn is_obj<T: ?Sized + Obj>(_: &T) {} + | ^^^ required by this bound in `is_obj` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/traits/associated_type_bound/issue-51446.rs b/src/test/ui/traits/associated_type_bound/issue-51446.rs new file mode 100644 index 000000000..7dd95de73 --- /dev/null +++ b/src/test/ui/traits/associated_type_bound/issue-51446.rs @@ -0,0 +1,34 @@ +// Regression test for #51446. +// check-pass + +trait Foo { + type Item; + fn get(&self) -> Self::Item; +} + +fn blah<T, F>(x: T, f: F) -> B<T::Item, impl Fn(T::Item)> +where + T: Foo, + F: Fn(T::Item), +{ + B { x: x.get(), f } +} + +pub struct B<T, F> +where + F: Fn(T), +{ + pub x: T, + pub f: F, +} + +impl Foo for i32 { + type Item = i32; + fn get(&self) -> i32 { + *self + } +} + +fn main() { + let _ = blah(0, |_| ()); +} |