diff options
| author | bors <bors@rust-lang.org> | 2020-10-10 23:27:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-10-10 23:27:28 +0000 |
| commit | 08764ad1638d49ee8303a8e5b1a9e439cbbc87f6 (patch) | |
| tree | 770af02a1069537634eb478c8af07cccf9c9f755 /src | |
| parent | b1af43bc63bc7417938df056f7f25d456cc11b0e (diff) | |
| parent | 4ae8f6ec7c75b3098ee3f8897254f5b8d12d75dc (diff) | |
| download | rust-08764ad1638d49ee8303a8e5b1a9e439cbbc87f6.tar.gz rust-08764ad1638d49ee8303a8e5b1a9e439cbbc87f6.zip | |
Auto merge of #77087 - estebank:issue-45817, r=matthewjasper
Provide structured suggestions when finding structs when expecting a trait When finding an ADT in a trait object definition provide some solutions. Fix #45817. Given `<Param as Trait>::Assoc: Ty` suggest `Param: Trait<Assoc = Ty>`. Fix #75829.
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/ui/traits/assoc_type_bound_with_struct.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/traits/assoc_type_bound_with_struct.stderr | 83 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-bounds-not-on-struct.rs | 33 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-bounds-not-on-struct.stderr | 165 |
4 files changed, 292 insertions, 8 deletions
diff --git a/src/test/ui/traits/assoc_type_bound_with_struct.rs b/src/test/ui/traits/assoc_type_bound_with_struct.rs new file mode 100644 index 00000000000..c66009fe24c --- /dev/null +++ b/src/test/ui/traits/assoc_type_bound_with_struct.rs @@ -0,0 +1,19 @@ +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 main() {} diff --git a/src/test/ui/traits/assoc_type_bound_with_struct.stderr b/src/test/ui/traits/assoc_type_bound_with_struct.stderr new file mode 100644 index 00000000000..7cf872eb6ac --- /dev/null +++ b/src/test/ui/traits/assoc_type_bound_with_struct.stderr @@ -0,0 +1,83 @@ +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: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/traits/trait-bounds-not-on-struct.rs b/src/test/ui/traits/trait-bounds-not-on-struct.rs index c6e93e75525..8633e9d7a4c 100644 --- a/src/test/ui/traits/trait-bounds-not-on-struct.rs +++ b/src/test/ui/traits/trait-bounds-not-on-struct.rs @@ -1,9 +1,38 @@ +// We don't need those errors. Ideally we would silence them, but to do so we need to move the +// lint from being an early-lint during parsing to a late-lint, because it needs to be aware of +// the types involved. #![allow(bare_trait_objects)] struct Foo; fn foo(_x: Box<Foo + Send>) { } //~ ERROR expected trait, found struct `Foo` -type A<T> = Box<dyn Vec<T>>; //~ ERROR expected trait, found struct `Vec` +type TypeAlias<T> = Box<dyn Vec<T>>; //~ ERROR expected trait, found struct `Vec` -fn main() { } +struct A; +fn a() -> A + 'static { //~ ERROR expected trait, found + A +} +fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) { //~ ERROR expected trait, found + panic!() +} +fn c() -> 'static + A { //~ ERROR expected trait, found + A +} +fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) { //~ ERROR expected trait, found + panic!() +} +fn e() -> 'static + A + 'static { //~ ERROR expected trait, found +//~^ ERROR only a single explicit lifetime bound is permitted + A +} +fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) { //~ ERROR expected trait, found +//~^ ERROR only a single explicit lifetime bound is permitted + panic!() +} +struct Traitor; +trait Trait {} +fn g() -> Traitor + 'static { //~ ERROR expected trait, found struct `Traitor` + A +} +fn main() {} diff --git a/src/test/ui/traits/trait-bounds-not-on-struct.stderr b/src/test/ui/traits/trait-bounds-not-on-struct.stderr index a649a4eee55..0f97e3bdf18 100644 --- a/src/test/ui/traits/trait-bounds-not-on-struct.stderr +++ b/src/test/ui/traits/trait-bounds-not-on-struct.stderr @@ -1,15 +1,168 @@ +error[E0226]: only a single explicit lifetime bound is permitted + --> $DIR/trait-bounds-not-on-struct.rs:25:25 + | +LL | fn e() -> 'static + A + 'static { + | ^^^^^^^ + +error[E0226]: only a single explicit lifetime bound is permitted + --> $DIR/trait-bounds-not-on-struct.rs:29:53 + | +LL | fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) { + | ^^ + error[E0404]: expected trait, found struct `Foo` - --> $DIR/trait-bounds-not-on-struct.rs:5:16 + --> $DIR/trait-bounds-not-on-struct.rs:8:16 | LL | fn foo(_x: Box<Foo + Send>) { } | ^^^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:8:22 + | +LL | fn foo(_x: Box<Foo + Send>) { } + | --- ^^^^ ...because of this bound + | | + | expected this type to be a trait... error[E0404]: expected trait, found struct `Vec` - --> $DIR/trait-bounds-not-on-struct.rs:7:21 + --> $DIR/trait-bounds-not-on-struct.rs:10:29 + | +LL | type TypeAlias<T> = Box<dyn Vec<T>>; + | ^^^^^^ not a trait + +error[E0404]: expected trait, found struct `A` + --> $DIR/trait-bounds-not-on-struct.rs:13:11 + | +LL | fn a() -> A + 'static { + | ^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:13:15 + | +LL | fn a() -> A + 'static { + | - ^^^^^^^ ...because of this bound + | | + | expected this type to be a trait... +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn a() -> A { + | -- + +error[E0404]: expected trait, found enum `Result` + --> $DIR/trait-bounds-not-on-struct.rs:16:34 + | +LL | fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) { + | ^^^^^^^^^^^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:16:48 + | +LL | fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) { + | ----------- ^^ ...because of this bound + | | + | expected this type to be a trait... +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn b<'a,T,E>(iter: Iterator<Item=Result<T,E>>) { + | -- + +error[E0404]: expected trait, found struct `A` + --> $DIR/trait-bounds-not-on-struct.rs:19:21 + | +LL | fn c() -> 'static + A { + | ^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:19:11 + | +LL | fn c() -> 'static + A { + | ^^^^^^^ - expected this type to be a trait... + | | + | ...because of this bound +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn c() -> A { + | -- + +error[E0404]: expected trait, found enum `Result` + --> $DIR/trait-bounds-not-on-struct.rs:22:39 + | +LL | fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) { + | ^^^^^^^^^^^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:22:34 + | +LL | fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) { + | ^^ ----------- expected this type to be a trait... + | | + | ...because of this bound +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn d<'a,T,E>(iter: Iterator<Item=Result<T,E>>) { + | -- + +error[E0404]: expected trait, found struct `A` + --> $DIR/trait-bounds-not-on-struct.rs:25:21 + | +LL | fn e() -> 'static + A + 'static { + | ^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:25:11 + | +LL | fn e() -> 'static + A + 'static { + | ^^^^^^^ - ^^^^^^^ ...because of these bounds + | | + | expected this type to be a trait... +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn e() -> A { + | --- + +error[E0404]: expected trait, found enum `Result` + --> $DIR/trait-bounds-not-on-struct.rs:29:39 + | +LL | fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) { + | ^^^^^^^^^^^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:29:34 + | +LL | fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) { + | ^^ ----------- ^^ ...because of these bounds + | | + | expected this type to be a trait... +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn f<'a,T,E>(iter: Iterator<Item=Result<T,E>>) { + | -- -- + +error[E0404]: expected trait, found struct `Traitor` + --> $DIR/trait-bounds-not-on-struct.rs:35:11 + | +LL | trait Trait {} + | ----------- similarly named trait `Trait` defined here +LL | fn g() -> Traitor + 'static { + | ^^^^^^^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:35:21 + | +LL | fn g() -> Traitor + 'static { + | ------- ^^^^^^^ ...because of this bound + | | + | expected this type to be a trait... +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn g() -> Traitor { + | -- +help: a trait with a similar name exists | -LL | type A<T> = Box<dyn Vec<T>>; - | ^^^^^^ not a trait +LL | fn g() -> Trait + 'static { + | ^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 11 previous errors -For more information about this error, try `rustc --explain E0404`. +Some errors have detailed explanations: E0226, E0404. +For more information about an error, try `rustc --explain E0226`. |
