diff options
Diffstat (limited to 'src/test/ui/object-safety')
19 files changed, 156 insertions, 27 deletions
diff --git a/src/test/ui/object-safety/issue-102762.rs b/src/test/ui/object-safety/issue-102762.rs new file mode 100644 index 000000000..4f4c36345 --- /dev/null +++ b/src/test/ui/object-safety/issue-102762.rs @@ -0,0 +1,26 @@ +// compile-flags: --crate-type=lib +// This test checks that the `where_clauses_object_safety` lint does not cause +// other object safety *hard errors* to be suppressed, because we currently +// only emit one object safety error per trait... + +use std::future::Future; +use std::pin::Pin; + +pub trait Fetcher: Send + Sync { + fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + where + Self: Sync, + { + todo!() + } +} + +fn fetcher() -> Box<dyn Fetcher> { + //~^ ERROR the trait `Fetcher` cannot be made into an object + todo!() +} + +pub fn foo() { + let fetcher = fetcher(); + let _ = fetcher.get(); +} diff --git a/src/test/ui/object-safety/issue-102762.stderr b/src/test/ui/object-safety/issue-102762.stderr new file mode 100644 index 000000000..5041ebe77 --- /dev/null +++ b/src/test/ui/object-safety/issue-102762.stderr @@ -0,0 +1,20 @@ +error[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/issue-102762.rs:18:21 + | +LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + | ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self` +... +LL | fn fetcher() -> Box<dyn Fetcher> { + | ^^^^^^^^^^^ `Fetcher` 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/issue-102762.rs:10:22 + | +LL | pub trait Fetcher: Send + Sync { + | ------- this trait cannot be made into an object... +LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + | ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/issue-102933.rs b/src/test/ui/object-safety/issue-102933.rs new file mode 100644 index 000000000..843391cff --- /dev/null +++ b/src/test/ui/object-safety/issue-102933.rs @@ -0,0 +1,25 @@ +// check-pass + +use std::future::Future; + +pub trait Service { + type Response; + type Future: Future<Output = Self::Response>; +} + +pub trait A1: Service<Response = i32> {} + +pub trait A2: Service<Future = Box<dyn Future<Output = i32>>> + A1 { + fn foo(&self) {} +} + +pub trait B1: Service<Future = Box<dyn Future<Output = i32>>> {} + +pub trait B2: Service<Response = i32> + B1 { + fn foo(&self) {} +} + +fn main() { + let x: &dyn A2 = todo!(); + let x: &dyn B2 = todo!(); +} diff --git a/src/test/ui/object-safety/issue-19538.stderr b/src/test/ui/object-safety/issue-19538.stderr index 7b37e1f95..8420637b3 100644 --- a/src/test/ui/object-safety/issue-19538.stderr +++ b/src/test/ui/object-safety/issue-19538.stderr @@ -29,7 +29,7 @@ LL | fn foo<T>(&self, val: T); LL | trait Bar: Foo { } | --- this trait cannot be made into an object... = help: consider moving `foo` to another trait - = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing` + = note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>` = note: required by cast to type `&mut dyn Bar` error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index 9dd144fee..5f94c9284 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-associated-consts.rs:12:30 + --> $DIR/object-safety-associated-consts.rs:12:31 | LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` 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/object-safety-associated-consts.rs:9:11 diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index 9ba3b251e..f44de07d5 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -12,7 +12,7 @@ LL | trait Bar { LL | const X: usize; | ^ ...because it contains this associated `const` = help: consider moving `X` to another trait - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` = note: required by cast to type `&dyn Bar` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-bounds.stderr b/src/test/ui/object-safety/object-safety-bounds.stderr index 89c4f8ced..29ffb5448 100644 --- a/src/test/ui/object-safety/object-safety-bounds.stderr +++ b/src/test/ui/object-safety/object-safety-bounds.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `X` cannot be made into an object - --> $DIR/object-safety-bounds.rs:7:11 + --> $DIR/object-safety-bounds.rs:7:15 | LL | fn f() -> Box<dyn X<U = u32>> { - | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object + | ^^^^^^^^^^^^^^ `X` 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/object-safety-bounds.rs:4:13 diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 345950f1a..458103752 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:18:30 + --> $DIR/object-safety-generics.rs:18:31 | LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` 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/object-safety-generics.rs:10:8 @@ -14,10 +14,10 @@ LL | fn bar<T>(&self, t: T); = help: consider moving `bar` to another trait error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:24:39 + --> $DIR/object-safety-generics.rs:24:40 | LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` 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/object-safety-generics.rs:10:8 diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index 86355627c..9a2d472d5 100644 --- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -12,7 +12,7 @@ LL | trait Bar { LL | fn bar<T>(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object @@ -29,7 +29,7 @@ LL | trait Bar { LL | fn bar<T>(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` = note: required by cast to type `&dyn Bar` error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index f91c9b985..de430a89b 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:22:30 + --> $DIR/object-safety-mentions-Self.rs:22:31 | LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` 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/object-safety-mentions-Self.rs:11:22 @@ -14,10 +14,10 @@ LL | fn bar(&self, x: &Self); = help: consider moving `bar` to another trait error[E0038]: the trait `Baz` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:28:30 + --> $DIR/object-safety-mentions-Self.rs:28:31 | LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { - | ^^^^^^^^ `Baz` cannot be made into an object + | ^^^^^^^ `Baz` 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/object-safety-mentions-Self.rs:15:22 diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index f48628c9d..40a298bd1 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -12,7 +12,7 @@ LL | trait Bar { LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter = help: consider moving `bar` to another trait - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Baz` cannot be made into an object @@ -29,7 +29,7 @@ LL | trait Baz { LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type = help: consider moving `baz` to another trait - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Baz>` = note: required by cast to type `&dyn Baz` error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index bd8cf4e30..1b025229e 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety-no-static.rs:12:18 + --> $DIR/object-safety-no-static.rs:12:22 | LL | fn diverges() -> Box<dyn Foo> { - | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | ^^^^^^^ `Foo` 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/object-safety-no-static.rs:9:8 diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index ea1c575ff..da87b58c9 100644 --- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -11,7 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} | ^^^ ...because associated function `foo` has no `self` parameter - = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<Bar>` + = note: required for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>` = note: required by cast to type `Box<dyn Foo>` help: consider turning `foo` into a method by giving it a `&self` argument | diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 71236c8e3..b01926412 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized-2.rs:14:30 + --> $DIR/object-safety-sized-2.rs:14:31 | LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` 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/object-safety-sized-2.rs:9:18 diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index b6e4903b0..6c29c8d5f 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -11,7 +11,7 @@ LL | trait Bar | --- this trait cannot be made into an object... LL | where Self : Sized | ^^^^^ ...because it requires `Self: Sized` - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` = note: required by cast to type `&dyn Bar` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 94b06ee93..974813121 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized.rs:12:30 + --> $DIR/object-safety-sized.rs:12:31 | LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` 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/object-safety-sized.rs:8:13 diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 645852c7e..70a44ed61 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -11,7 +11,7 @@ LL | trait Bar : Sized { | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` = note: required by cast to type `&dyn Bar` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.rs b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.rs new file mode 100644 index 000000000..14e00d2ef --- /dev/null +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.rs @@ -0,0 +1,15 @@ +//~ ERROR the parameter type `Self` may not live long enough + +trait GatTrait { + type Gat<'a> + where + Self: 'a; +} + +trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { + fn c(&self) -> dyn SuperTrait<T>; + //~^ ERROR associated item referring to unboxed trait object for its own trait + //~| ERROR the trait `SuperTrait` cannot be made into an object +} + +fn main() {} diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr new file mode 100644 index 000000000..c1aaad31e --- /dev/null +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr @@ -0,0 +1,43 @@ +error[E0311]: the parameter type `Self` may not live long enough + | + = help: consider adding an explicit lifetime bound `Self: 'a`... + = note: ...so that the type `Self` will meet its required lifetime bounds... +note: ...that is required by this bound + --> $DIR/object-safety-supertrait-mentions-GAT.rs:9:39 + | +LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { + | ^^^^^^^^^^^ + +error: associated item referring to unboxed trait object for its own trait + --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20 + | +LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { + | ---------- in this trait +LL | fn c(&self) -> dyn SuperTrait<T>; + | ^^^^^^^^^^^^^^^^^ + | +help: you might have meant to use `Self` to refer to the implementing type + | +LL | fn c(&self) -> Self; + | ~~~~ + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20 + | +LL | fn c(&self) -> dyn SuperTrait<T>; + | ^^^^^^^^^^^^^^^^^ `SuperTrait` 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/object-safety-supertrait-mentions-GAT.rs:4:10 + | +LL | type Gat<'a> + | ^^^ ...because it contains the generic associated type `Gat` +... +LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { + | ---------- this trait cannot be made into an object... + = help: consider moving `Gat` to another trait + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0311. +For more information about an error, try `rustc --explain E0038`. |