diff options
| author | León Orell Valerian Liehr <me@fmease.dev> | 2024-10-09 23:31:01 +0200 |
|---|---|---|
| committer | León Orell Valerian Liehr <me@fmease.dev> | 2024-10-10 01:13:29 +0200 |
| commit | 20cebae31203a9781f99081b075abe0dc2504a98 (patch) | |
| tree | 8cde6f126d8cbfdce885dbf10cc56318dd6afeaa /tests/ui/dyn-compatibility | |
| parent | 2e7a52b22fe222316a48093547f6312252c20f0f (diff) | |
| download | rust-20cebae31203a9781f99081b075abe0dc2504a98.tar.gz rust-20cebae31203a9781f99081b075abe0dc2504a98.zip | |
UI tests: Rename "object safe" to "dyn compatible"
Diffstat (limited to 'tests/ui/dyn-compatibility')
75 files changed, 2993 insertions, 0 deletions
diff --git a/tests/ui/dyn-compatibility/almost-supertrait-associated-type.rs b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.rs new file mode 100644 index 00000000000..83076f7d5fc --- /dev/null +++ b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.rs @@ -0,0 +1,60 @@ +// Test for fixed unsoundness in #126079. +// Enforces that the associated types that are dyn-compatible. + +use std::marker::PhantomData; + +fn transmute<T, U>(t: T) -> U { + (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t) + //~^ ERROR the trait `Foo` cannot be made into an object + //~| ERROR the trait `Foo` cannot be made into an object +} + +struct ActuallySuper; +struct NotActuallySuper; +trait Super<Q> { + type Assoc; +} + +trait Dyn { + type Out; +} +impl<T, U> Dyn for dyn Foo<T, U> + '_ { +//~^ ERROR the trait `Foo` cannot be made into an object + type Out = U; +} +impl<S: Dyn<Out = U> + ?Sized, U> Super<NotActuallySuper> for S { + type Assoc = U; +} + +trait Foo<T, U>: Super<ActuallySuper, Assoc = T> +where + <Self as Mirror>::Assoc: Super<NotActuallySuper> +{ + fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc; +} + +trait Mirror { + type Assoc: ?Sized; +} +impl<T: ?Sized> Mirror for T { + type Assoc = T; +} + +impl<T, U> Foo<T, U> for PhantomData<T> { + fn transmute(&self, t: T) -> T { + t + } +} +impl<T> Super<ActuallySuper> for PhantomData<T> { + type Assoc = T; +} +impl<T> Super<NotActuallySuper> for PhantomData<T> { + type Assoc = T; +} + +fn main() { + let x = String::from("hello, world"); + let s = transmute::<&str, &'static str>(x.as_str()); + drop(x); + println!("> {s}"); +} diff --git a/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr new file mode 100644 index 00000000000..99bcccc20c0 --- /dev/null +++ b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr @@ -0,0 +1,55 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/almost-supertrait-associated-type.rs:21:20 + | +LL | impl<T, U> Dyn for dyn Foo<T, U> + '_ { + | ^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/almost-supertrait-associated-type.rs:33:34 + | +LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> + | --- this trait cannot be made into an object... +... +LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type + = help: consider moving `transmute` to another trait + = help: only type `std::marker::PhantomData<T>` implements the trait, consider using it directly instead + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/almost-supertrait-associated-type.rs:7:27 + | +LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t) + | ^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/almost-supertrait-associated-type.rs:33:34 + | +LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> + | --- this trait cannot be made into an object... +... +LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type + = help: consider moving `transmute` to another trait + = help: only type `std::marker::PhantomData<T>` implements the trait, consider using it directly instead + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/almost-supertrait-associated-type.rs:7:6 + | +LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t) + | ^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/almost-supertrait-associated-type.rs:33:34 + | +LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> + | --- this trait cannot be made into an object... +... +LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type + = help: consider moving `transmute` to another trait + = help: only type `std::marker::PhantomData<T>` implements the trait, consider using it directly instead + = note: required for the cast from `&PhantomData<T>` to `&dyn Foo<T, U>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/assoc_const_bounds.rs b/tests/ui/dyn-compatibility/assoc_const_bounds.rs new file mode 100644 index 00000000000..32c4de1981b --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_const_bounds.rs @@ -0,0 +1,18 @@ +#![feature(generic_const_items)] +#![allow(incomplete_features, dead_code)] + +//@ check-pass + +trait Foo<T> { + const BAR: bool + where + Self: Sized; +} + +trait Cake {} +impl Cake for () {} + +fn foo(_: &dyn Foo<()>) {} +fn bar(_: &dyn Foo<i32>) {} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_const_bounds_sized.rs b/tests/ui/dyn-compatibility/assoc_const_bounds_sized.rs new file mode 100644 index 00000000000..1272a735e83 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_const_bounds_sized.rs @@ -0,0 +1,14 @@ +#![feature(generic_const_items)] +#![allow(incomplete_features, dead_code)] + +//@ check-pass + +trait Foo { + const BAR: bool + where + Self: Sized; +} + +fn foo(_: &dyn Foo) {} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds.rs b/tests/ui/dyn-compatibility/assoc_type_bounds.rs new file mode 100644 index 00000000000..8634ba626a1 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds.rs @@ -0,0 +1,13 @@ +trait Foo<T> { + type Bar + where + T: Cake; +} + +trait Cake {} +impl Cake for () {} + +fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified +fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds.stderr new file mode 100644 index 00000000000..3d5482625af --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds.stderr @@ -0,0 +1,21 @@ +error[E0191]: the value of the associated type `Bar` in `Foo` must be specified + --> $DIR/assoc_type_bounds.rs:10:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn foo(_: &dyn Foo<()>) {} + | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>` + +error[E0191]: the value of the associated type `Bar` in `Foo` must be specified + --> $DIR/assoc_type_bounds.rs:11:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn bar(_: &dyn Foo<i32>) {} + | ^^^^^^^^ help: specify the associated type: `Foo<i32, Bar = Type>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds2.rs b/tests/ui/dyn-compatibility/assoc_type_bounds2.rs new file mode 100644 index 00000000000..f7dc2fb8839 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds2.rs @@ -0,0 +1,13 @@ +trait Foo<T> { + type Bar + where + Self: Foo<()>; +} + +trait Cake {} +impl Cake for () {} + +fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified +fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` in `Foo` must be specified + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr new file mode 100644 index 00000000000..815747436bf --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr @@ -0,0 +1,21 @@ +error[E0191]: the value of the associated type `Bar` in `Foo` must be specified + --> $DIR/assoc_type_bounds2.rs:10:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn foo(_: &dyn Foo<()>) {} + | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>` + +error[E0191]: the value of the associated type `Bar` in `Foo` must be specified + --> $DIR/assoc_type_bounds2.rs:11:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn bar(_: &dyn Foo<i32>) {} + | ^^^^^^^^ help: specify the associated type: `Foo<i32, Bar = Type>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.fixed b/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.fixed new file mode 100644 index 00000000000..88697bad4d7 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.fixed @@ -0,0 +1,11 @@ +//@ run-rustfix +#![allow(dead_code)] +trait TraitWithAType { + type Item: ?Sized; +} +trait Trait {} +struct A {} +impl TraitWithAType for A { + type Item = dyn Trait; //~ ERROR E0277 +} +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.rs b/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.rs new file mode 100644 index 00000000000..944b296aa4d --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.rs @@ -0,0 +1,11 @@ +//@ run-rustfix +#![allow(dead_code)] +trait TraitWithAType { + type Item; +} +trait Trait {} +struct A {} +impl TraitWithAType for A { + type Item = dyn Trait; //~ ERROR E0277 +} +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.stderr new file mode 100644 index 00000000000..9bb770ce431 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_implicit_sized.stderr @@ -0,0 +1,20 @@ +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/assoc_type_bounds_implicit_sized.rs:9:17 + | +LL | type Item = dyn Trait; + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)` +note: required by a bound in `TraitWithAType::Item` + --> $DIR/assoc_type_bounds_implicit_sized.rs:4:5 + | +LL | type Item; + | ^^^^^^^^^^ required by this bound in `TraitWithAType::Item` +help: consider relaxing the implicit `Sized` restriction + | +LL | type Item: ?Sized; + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized.rs b/tests/ui/dyn-compatibility/assoc_type_bounds_sized.rs new file mode 100644 index 00000000000..7535871afe5 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized.rs @@ -0,0 +1,24 @@ +//! This test checks that associated types only need to be +//! mentioned in trait objects, if they don't require `Self: Sized`. + +//@ check-pass + +trait Foo { + type Bar + where + Self: Sized; +} + +fn foo(_: &dyn Foo) {} + +trait Other: Sized {} + +trait Boo { + type Assoc + where + Self: Other; +} + +fn boo(_: &dyn Boo) {} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.rs b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.rs new file mode 100644 index 00000000000..5b07bc92f32 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.rs @@ -0,0 +1,25 @@ +//! This test checks that even if some associated types have +//! `where Self: Sized` bounds, those without still need to be +//! mentioned in trait objects. + +trait Foo { + type Bar + where + Self: Sized; + type Bop; +} + +fn foo(_: &dyn Foo) {} +//~^ ERROR the value of the associated type `Bop` in `Foo` must be specified + +trait Bar { + type Bop; + type Bar + where + Self: Sized; +} + +fn bar(_: &dyn Bar) {} +//~^ ERROR the value of the associated type `Bop` in `Bar` must be specified + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr new file mode 100644 index 00000000000..5438faaaf05 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr @@ -0,0 +1,21 @@ +error[E0191]: the value of the associated type `Bop` in `Foo` must be specified + --> $DIR/assoc_type_bounds_sized_others.rs:12:16 + | +LL | type Bop; + | -------- `Bop` defined here +... +LL | fn foo(_: &dyn Foo) {} + | ^^^ help: specify the associated type: `Foo<Bop = Type>` + +error[E0191]: the value of the associated type `Bop` in `Bar` must be specified + --> $DIR/assoc_type_bounds_sized_others.rs:22:16 + | +LL | type Bop; + | -------- `Bop` defined here +... +LL | fn bar(_: &dyn Bar) {} + | ^^^ help: specify the associated type: `Bar<Bop = Type>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_unnecessary.rs b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_unnecessary.rs new file mode 100644 index 00000000000..e9216da5927 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_unnecessary.rs @@ -0,0 +1,15 @@ +//@ check-pass + +trait Foo { + type Bar + where + Self: Sized; +} + +fn foo(_: &dyn Foo<Bar = ()>) {} +//~^ WARN: unnecessary associated type bound for dyn-incompatible associated type + +#[allow(unused_associated_type_bounds)] +fn bar(_: &dyn Foo<Bar = ()>) {} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_unnecessary.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_unnecessary.stderr new file mode 100644 index 00000000000..aaadc4ed7b1 --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_unnecessary.stderr @@ -0,0 +1,11 @@ +warning: unnecessary associated type bound for dyn-incompatible associated type + --> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20 + | +LL | fn foo(_: &dyn Foo<Bar = ()>) {} + | ^^^^^^^^ help: remove this bound + | + = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized` + = note: `#[warn(unused_associated_type_bounds)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.rs b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.rs new file mode 100644 index 00000000000..d59fc1712ea --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.rs @@ -0,0 +1,18 @@ +//! This test checks that associated types with `Self: Sized` cannot be projected +//! from a `dyn Trait`. + +trait Bop { + type Bar: Default + where + Self: Sized; +} + +fn bop<T: Bop + ?Sized>() { + let _ = <T as Bop>::Bar::default(); + //~^ ERROR: trait bounds were not satisfied + //~| ERROR: the size for values of type `T` cannot be known at compilation time +} + +fn main() { + bop::<dyn Bop>(); +} diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr new file mode 100644 index 00000000000..b67a1244ece --- /dev/null +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_used.stderr @@ -0,0 +1,44 @@ +error[E0599]: the function or associated item `default` exists for associated type `<T as Bop>::Bar`, but its trait bounds were not satisfied + --> $DIR/assoc_type_bounds_sized_used.rs:11:30 + | +LL | let _ = <T as Bop>::Bar::default(); + | ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `T: Sized` + which is required by `<T as Bop>::Bar: Default` +help: consider restricting the type parameter to satisfy the trait bound + | +LL | fn bop<T: Bop + ?Sized>() where T: Sized { + | ++++++++++++++ + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/assoc_type_bounds_sized_used.rs:11:14 + | +LL | fn bop<T: Bop + ?Sized>() { + | - this type parameter needs to be `Sized` +LL | let _ = <T as Bop>::Bar::default(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `Bop::Bar` + --> $DIR/assoc_type_bounds_sized_used.rs:7:15 + | +LL | type Bar: Default + | --- required by a bound in this associated type +LL | where +LL | Self: Sized; + | ^^^^^ required by this bound in `Bop::Bar` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn bop<T: Bop + ?Sized>() { +LL + fn bop<T: Bop>() { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | type Bar: Default + ?Sized + | ++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/dyn-compatibility/associated-consts.curr.stderr b/tests/ui/dyn-compatibility/associated-consts.curr.stderr new file mode 100644 index 00000000000..17d184942c7 --- /dev/null +++ b/tests/ui/dyn-compatibility/associated-consts.curr.stderr @@ -0,0 +1,34 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/associated-consts.rs:12:31 + | +LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/associated-consts.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..cc5120232c2 --- /dev/null +++ b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,19 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/associated-consts.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/associated-consts.rs b/tests/ui/dyn-compatibility/associated-consts.rs new file mode 100644 index 00000000000..fc7b372b782 --- /dev/null +++ b/tests/ui/dyn-compatibility/associated-consts.rs @@ -0,0 +1,19 @@ +// Check that we correctly prevent users from making trait objects +// from traits with associated consts. +// +//@ revisions: curr dyn_compatible_for_dispatch + +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] + +trait Bar { + const X: usize; +} + +fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //~^ ERROR E0038 +} + +fn main() { +} diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr new file mode 100644 index 00000000000..4e3d2ebebad --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr @@ -0,0 +1,41 @@ +error[E0038]: the trait `Copy` cannot be made into an object + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id<F>(f: Copy) -> usize { + | ^^^^ `Copy` cannot be made into an object + | + = note: the trait cannot be made into an object because it requires `Self: Sized` + = note: for a trait to be "dyn-compatible" 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> + +error[E0618]: expected function, found `(dyn Copy + 'static)` + --> $DIR/avoid-ice-on-warning-2.rs:11:5 + | +LL | fn id<F>(f: Copy) -> usize { + | - `f` has type `(dyn Copy + 'static)` +... +LL | f() + | ^-- + | | + | call expression requires function + +error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id<F>(f: Copy) -> usize { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` + = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn id<F>(f: impl Copy) -> usize { + | ++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn id<F>(f: &dyn Copy) -> usize { + | ++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0277, E0618. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr new file mode 100644 index 00000000000..180cd679dea --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr @@ -0,0 +1,69 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id<F>(f: Copy) -> usize { + | ^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | fn id<F>(f: dyn Copy) -> usize { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id<F>(f: Copy) -> usize { + | ^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is a dyn-compatible trait, use `dyn` + | +LL | fn id<F>(f: dyn Copy) -> usize { + | +++ + +error[E0038]: the trait `Copy` cannot be made into an object + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id<F>(f: Copy) -> usize { + | ^^^^ `Copy` cannot be made into an object + | + = note: the trait cannot be made into an object because it requires `Self: Sized` + = note: for a trait to be "dyn-compatible" 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> + +error[E0618]: expected function, found `(dyn Copy + 'static)` + --> $DIR/avoid-ice-on-warning-2.rs:11:5 + | +LL | fn id<F>(f: Copy) -> usize { + | - `f` has type `(dyn Copy + 'static)` +... +LL | f() + | ^-- + | | + | call expression requires function + +error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id<F>(f: Copy) -> usize { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` + = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn id<F>(f: impl Copy) -> usize { + | ++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn id<F>(f: &dyn Copy) -> usize { + | ++++ + +error: aborting due to 3 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0038, E0277, E0618. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs new file mode 100644 index 00000000000..db2f4aea05b --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs @@ -0,0 +1,14 @@ +//@ revisions: old new +//@[old] edition:2015 +//@[new] edition:2021 +fn id<F>(f: Copy) -> usize { +//~^ ERROR the trait `Copy` cannot be made into an object +//~| ERROR: the size for values of type `(dyn Copy + 'static)` +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + f() + //~^ ERROR: expected function, found `(dyn Copy + 'static)` +} +fn main() {} diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr new file mode 100644 index 00000000000..fdd3e8ab507 --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr @@ -0,0 +1,47 @@ +error[E0038]: the trait `A` cannot be made into an object + --> $DIR/avoid-ice-on-warning-3.rs:4:19 + | +LL | trait B { fn f(a: A) -> A; } + | ^ `A` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/avoid-ice-on-warning-3.rs:12:14 + | +LL | trait A { fn g(b: B) -> B; } + | - ^ ...because associated function `g` has no `self` parameter + | | + | this trait cannot be made into an object... +help: consider turning `g` into a method by giving it a `&self` argument + | +LL | trait A { fn g(&self, b: B) -> B; } + | ++++++ +help: alternatively, consider constraining `g` so it does not apply to trait objects + | +LL | trait A { fn g(b: B) -> B where Self: Sized; } + | +++++++++++++++++ + +error[E0038]: the trait `B` cannot be made into an object + --> $DIR/avoid-ice-on-warning-3.rs:12:19 + | +LL | trait A { fn g(b: B) -> B; } + | ^ `B` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/avoid-ice-on-warning-3.rs:4:14 + | +LL | trait B { fn f(a: A) -> A; } + | - ^ ...because associated function `f` has no `self` parameter + | | + | this trait cannot be made into an object... +help: consider turning `f` into a method by giving it a `&self` argument + | +LL | trait B { fn f(&self, a: A) -> A; } + | ++++++ +help: alternatively, consider constraining `f` so it does not apply to trait objects + | +LL | trait B { fn f(a: A) -> A where Self: Sized; } + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr new file mode 100644 index 00000000000..bd362abb355 --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr @@ -0,0 +1,128 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:4:19 + | +LL | trait B { fn f(a: A) -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait B { fn f(a: dyn A) -> A; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:4:25 + | +LL | trait B { fn f(a: A) -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait B { fn f(a: A) -> dyn A; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:12:19 + | +LL | trait A { fn g(b: B) -> B; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait A { fn g(b: dyn B) -> B; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:12:25 + | +LL | trait A { fn g(b: B) -> B; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait A { fn g(b: B) -> dyn B; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:4:19 + | +LL | trait B { fn f(a: A) -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait B { fn f(a: dyn A) -> A; } + | +++ + +error[E0038]: the trait `A` cannot be made into an object + --> $DIR/avoid-ice-on-warning-3.rs:4:19 + | +LL | trait B { fn f(a: A) -> A; } + | ^ `A` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/avoid-ice-on-warning-3.rs:12:14 + | +LL | trait A { fn g(b: B) -> B; } + | - ^ ...because associated function `g` has no `self` parameter + | | + | this trait cannot be made into an object... +help: consider turning `g` into a method by giving it a `&self` argument + | +LL | trait A { fn g(&self, b: B) -> B; } + | ++++++ +help: alternatively, consider constraining `g` so it does not apply to trait objects + | +LL | trait A { fn g(b: B) -> B where Self: Sized; } + | +++++++++++++++++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:12:19 + | +LL | trait A { fn g(b: B) -> B; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait A { fn g(b: dyn B) -> B; } + | +++ + +error[E0038]: the trait `B` cannot be made into an object + --> $DIR/avoid-ice-on-warning-3.rs:12:19 + | +LL | trait A { fn g(b: B) -> B; } + | ^ `B` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/avoid-ice-on-warning-3.rs:4:14 + | +LL | trait B { fn f(a: A) -> A; } + | - ^ ...because associated function `f` has no `self` parameter + | | + | this trait cannot be made into an object... +help: consider turning `f` into a method by giving it a `&self` argument + | +LL | trait B { fn f(&self, a: A) -> A; } + | ++++++ +help: alternatively, consider constraining `f` so it does not apply to trait objects + | +LL | trait B { fn f(a: A) -> A where Self: Sized; } + | +++++++++++++++++ + +error: aborting due to 2 previous errors; 6 warnings emitted + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs new file mode 100644 index 00000000000..38bee8142bb --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs @@ -0,0 +1,20 @@ +//@ revisions: old new +//@[old] edition:2015 +//@[new] edition:2021 +trait B { fn f(a: A) -> A; } +//~^ ERROR the trait `A` cannot be made into an object +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition +trait A { fn g(b: B) -> B; } +//~^ ERROR the trait `B` cannot be made into an object +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition +fn main() {} diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr new file mode 100644 index 00000000000..4ff45d7a848 --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr @@ -0,0 +1,20 @@ +error: return types are denoted using `->` + --> $DIR/avoid-ice-on-warning.rs:4:23 + | +LL | fn call_this<F>(f: F) : Fn(&str) + call_that {} + | ^ + | +help: use `->` instead + | +LL | fn call_this<F>(f: F) -> Fn(&str) + call_that {} + | ~~ + +error[E0405]: cannot find trait `call_that` in this scope + --> $DIR/avoid-ice-on-warning.rs:4:36 + | +LL | fn call_this<F>(f: F) : Fn(&str) + call_that {} + | ^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr new file mode 100644 index 00000000000..646fb57af9e --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr @@ -0,0 +1,34 @@ +error: return types are denoted using `->` + --> $DIR/avoid-ice-on-warning.rs:4:23 + | +LL | fn call_this<F>(f: F) : Fn(&str) + call_that {} + | ^ + | +help: use `->` instead + | +LL | fn call_this<F>(f: F) -> Fn(&str) + call_that {} + | ~~ + +error[E0405]: cannot find trait `call_that` in this scope + --> $DIR/avoid-ice-on-warning.rs:4:36 + | +LL | fn call_this<F>(f: F) : Fn(&str) + call_that {} + | ^^^^^^^^^ not found in this scope + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning.rs:4:25 + | +LL | fn call_this<F>(f: F) : Fn(&str) + call_that {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {} + | +++ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs b/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs new file mode 100644 index 00000000000..b90d8911d50 --- /dev/null +++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs @@ -0,0 +1,9 @@ +//@ revisions: old new +//@[old] edition:2015 +//@[new] edition:2021 +fn call_this<F>(f: F) : Fn(&str) + call_that {} +//~^ ERROR return types are denoted using `->` +//~| ERROR cannot find trait `call_that` in this scope +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +fn main() {} diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed new file mode 100644 index 00000000000..4f5310082e1 --- /dev/null +++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed @@ -0,0 +1,14 @@ +//@ revisions: old new +//@[old] edition:2015 +//@[new] edition:2021 +//@[new] run-rustfix +#![deny(bare_trait_objects)] +fn ord_prefer_dot(s: String) -> impl Ord { + //~^ ERROR the trait `Ord` cannot be made into an object + //[old]~| ERROR trait objects without an explicit `dyn` are deprecated + //[old]~| WARNING this is accepted in the current edition (Rust 2015) + (s.starts_with("."), s) +} +fn main() { + let _ = ord_prefer_dot(String::new()); +} diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr new file mode 100644 index 00000000000..bb2bf6ddcda --- /dev/null +++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr @@ -0,0 +1,21 @@ +error[E0038]: the trait `Ord` cannot be made into an object + --> $DIR/bare-trait-dont-suggest-dyn.rs:6:33 + | +LL | fn ord_prefer_dot(s: String) -> Ord { + | ^^^ `Ord` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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> + --> $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter +help: consider using an opaque type instead + | +LL | fn ord_prefer_dot(s: String) -> impl Ord { + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr new file mode 100644 index 00000000000..45c9b0ce5d9 --- /dev/null +++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr @@ -0,0 +1,39 @@ +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/bare-trait-dont-suggest-dyn.rs:6:33 + | +LL | fn ord_prefer_dot(s: String) -> Ord { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +note: the lint level is defined here + --> $DIR/bare-trait-dont-suggest-dyn.rs:5:9 + | +LL | #![deny(bare_trait_objects)] + | ^^^^^^^^^^^^^^^^^^ +help: if this is a dyn-compatible trait, use `dyn` + | +LL | fn ord_prefer_dot(s: String) -> dyn Ord { + | +++ + +error[E0038]: the trait `Ord` cannot be made into an object + --> $DIR/bare-trait-dont-suggest-dyn.rs:6:33 + | +LL | fn ord_prefer_dot(s: String) -> Ord { + | ^^^ `Ord` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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> + --> $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter +help: consider using an opaque type instead + | +LL | fn ord_prefer_dot(s: String) -> impl Ord { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs new file mode 100644 index 00000000000..cb5a305eab0 --- /dev/null +++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs @@ -0,0 +1,14 @@ +//@ revisions: old new +//@[old] edition:2015 +//@[new] edition:2021 +//@[new] run-rustfix +#![deny(bare_trait_objects)] +fn ord_prefer_dot(s: String) -> Ord { + //~^ ERROR the trait `Ord` cannot be made into an object + //[old]~| ERROR trait objects without an explicit `dyn` are deprecated + //[old]~| WARNING this is accepted in the current edition (Rust 2015) + (s.starts_with("."), s) +} +fn main() { + let _ = ord_prefer_dot(String::new()); +} diff --git a/tests/ui/dyn-compatibility/bounds.rs b/tests/ui/dyn-compatibility/bounds.rs new file mode 100644 index 00000000000..1e04d11c516 --- /dev/null +++ b/tests/ui/dyn-compatibility/bounds.rs @@ -0,0 +1,12 @@ +// Traits with bounds mentioning `Self` are dyn-incompatible. + +trait X { + type U: PartialEq<Self>; +} + +fn f() -> Box<dyn X<U = u32>> { + //~^ ERROR the trait `X` cannot be made into an object + loop {} +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/bounds.stderr b/tests/ui/dyn-compatibility/bounds.stderr new file mode 100644 index 00000000000..9231d524fd1 --- /dev/null +++ b/tests/ui/dyn-compatibility/bounds.stderr @@ -0,0 +1,17 @@ +error[E0038]: the trait `X` cannot be made into an object + --> $DIR/bounds.rs:7:15 + | +LL | fn f() -> Box<dyn X<U = u32>> { + | ^^^^^^^^^^^^^^ `X` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/bounds.rs:4:13 + | +LL | trait X { + | - this trait cannot be made into an object... +LL | type U: PartialEq<Self>; + | ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/by-value-self-use.rs b/tests/ui/dyn-compatibility/by-value-self-use.rs new file mode 100644 index 00000000000..3c04ec0cd88 --- /dev/null +++ b/tests/ui/dyn-compatibility/by-value-self-use.rs @@ -0,0 +1,18 @@ +// Check that while a trait with by-value self is dyn-compatible, we +// can't actually invoke it from an object (yet...?). + +#![feature(rustc_attrs)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +fn use_bar(t: Box<dyn Bar>) { + t.bar() //~ ERROR cannot move a value of type `dyn Bar` +} + +fn main() { } diff --git a/tests/ui/dyn-compatibility/by-value-self-use.stderr b/tests/ui/dyn-compatibility/by-value-self-use.stderr new file mode 100644 index 00000000000..14785b982a3 --- /dev/null +++ b/tests/ui/dyn-compatibility/by-value-self-use.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type `dyn Bar` + --> $DIR/by-value-self-use.rs:15:5 + | +LL | t.bar() + | ^ the size of `dyn Bar` cannot be statically determined + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0161`. diff --git a/tests/ui/dyn-compatibility/by-value-self.rs b/tests/ui/dyn-compatibility/by-value-self.rs new file mode 100644 index 00000000000..a057a7ff0b5 --- /dev/null +++ b/tests/ui/dyn-compatibility/by-value-self.rs @@ -0,0 +1,46 @@ +// Check that a trait with by-value self is considered dyn-compatible. + +//@ build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +#![allow(trivial_casts)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +trait Quux { + // Legal because of the where clause: + fn baz(self: Self) where Self : Sized; +} + +fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + t // legal +} + +fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { + t as &dyn Bar // legal +} + +fn make_baz<T:Baz>(t: &T) -> &dyn Baz { + t // legal +} + +fn make_baz_explicit<T:Baz>(t: &T) -> &dyn Baz { + t as &dyn Baz // legal +} + +fn make_quux<T:Quux>(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux { + t as &dyn Quux +} + + +fn main() { +} diff --git a/tests/ui/dyn-compatibility/call-when-assoc-ty-is-sized.rs b/tests/ui/dyn-compatibility/call-when-assoc-ty-is-sized.rs new file mode 100644 index 00000000000..7a3a7f3ca2f --- /dev/null +++ b/tests/ui/dyn-compatibility/call-when-assoc-ty-is-sized.rs @@ -0,0 +1,26 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +trait Foo { + type Bar<'a> + where + Self: Sized; + + fn test(&self); +} + +impl Foo for () { + type Bar<'a> = () where Self: Sized; + + fn test(&self) {} +} + +fn test(x: &dyn Foo) { + x.test(); +} + +fn main() { + test(&()); +} diff --git a/tests/ui/dyn-compatibility/elaborated-predicates-ordering.rs b/tests/ui/dyn-compatibility/elaborated-predicates-ordering.rs new file mode 100644 index 00000000000..d3c3963a673 --- /dev/null +++ b/tests/ui/dyn-compatibility/elaborated-predicates-ordering.rs @@ -0,0 +1,26 @@ +//@ check-pass +// issue: rust-lang/rust#102933 + +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/tests/ui/dyn-compatibility/erroneous_signature.rs b/tests/ui/dyn-compatibility/erroneous_signature.rs new file mode 100644 index 00000000000..cc1841cc4b2 --- /dev/null +++ b/tests/ui/dyn-compatibility/erroneous_signature.rs @@ -0,0 +1,17 @@ +trait Foo { + fn err(&self) -> MissingType; + //~^ ERROR cannot find type `MissingType` in this scope +} + +impl Foo for i32 { + fn err(&self) -> MissingType { + //~^ ERROR cannot find type `MissingType` in this scope + 0 + } +} + +fn coerce(x: &i32) -> &dyn Foo { + x +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/erroneous_signature.stderr b/tests/ui/dyn-compatibility/erroneous_signature.stderr new file mode 100644 index 00000000000..f3b14ffe34c --- /dev/null +++ b/tests/ui/dyn-compatibility/erroneous_signature.stderr @@ -0,0 +1,15 @@ +error[E0412]: cannot find type `MissingType` in this scope + --> $DIR/erroneous_signature.rs:2:22 + | +LL | fn err(&self) -> MissingType; + | ^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `MissingType` in this scope + --> $DIR/erroneous_signature.rs:7:22 + | +LL | fn err(&self) -> MissingType { + | ^^^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/dyn-compatibility/generics.curr.stderr b/tests/ui/dyn-compatibility/generics.curr.stderr new file mode 100644 index 00000000000..c63db38a080 --- /dev/null +++ b/tests/ui/dyn-compatibility/generics.curr.stderr @@ -0,0 +1,80 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:18:31 + | +LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:25:40 + | +LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:20:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:27:10 + | +LL | t as &dyn Bar + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:27:5 + | +LL | t as &dyn Bar + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..ba2546ef2dc --- /dev/null +++ b/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,35 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:20:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/generics.rs:27:5 + | +LL | t as &dyn Bar + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/generics.rs b/tests/ui/dyn-compatibility/generics.rs new file mode 100644 index 00000000000..b51555aa500 --- /dev/null +++ b/tests/ui/dyn-compatibility/generics.rs @@ -0,0 +1,42 @@ +// Check that we correctly prevent users from making trait objects +// from traits with generic methods, unless `where Self : Sized` is +// present. +//@ revisions: curr dyn_compatible_for_dispatch + +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] + + +trait Bar { + fn bar<T>(&self, t: T); +} + +trait Quux { + fn bar<T>(&self, t: T) + where Self : Sized; +} + +fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //[dyn_compatible_for_dispatch]~^ ERROR E0038 + //[curr]~^^ ERROR E0038 +} + +fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t as &dyn Bar + //[dyn_compatible_for_dispatch]~^ ERROR E0038 + //[curr]~^^ ERROR E0038 + //[curr]~| ERROR E0038 +} + +fn make_quux<T:Quux>(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux { + t as &dyn Quux +} + +fn main() { +} diff --git a/tests/ui/dyn-compatibility/impossible-predicates-multiple_supertrait_upcastable-check.rs b/tests/ui/dyn-compatibility/impossible-predicates-multiple_supertrait_upcastable-check.rs new file mode 100644 index 00000000000..c2b8ecc141d --- /dev/null +++ b/tests/ui/dyn-compatibility/impossible-predicates-multiple_supertrait_upcastable-check.rs @@ -0,0 +1,8 @@ +//@ check-pass +// issue: rust-lang/rust#106247 + +pub trait Trait { + fn method(&self) where Self: Sync; +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/item-bounds-can-reference-self.rs b/tests/ui/dyn-compatibility/item-bounds-can-reference-self.rs new file mode 100644 index 00000000000..4ae982e8f95 --- /dev/null +++ b/tests/ui/dyn-compatibility/item-bounds-can-reference-self.rs @@ -0,0 +1,11 @@ +//@ check-pass + +pub trait Foo { + type X: PartialEq; + type Y: PartialEq<Self::Y>; + type Z: PartialEq<Self::Y>; +} + +fn uwu(x: &dyn Foo<X = i32, Y = i32, Z = i32>) {} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.rs b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.rs new file mode 100644 index 00000000000..1289d2d7874 --- /dev/null +++ b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.rs @@ -0,0 +1,22 @@ +// issue: rust-lang/rust#19538 + +trait Foo { + fn foo<T>(&self, val: T); +} + +trait Bar: Foo { } + +pub struct Thing; + +impl Foo for Thing { + fn foo<T>(&self, val: T) { } +} + +impl Bar for Thing { } + +fn main() { + let mut thing = Thing; + let test: &mut dyn Bar = &mut thing; + //~^ ERROR E0038 + //~| ERROR E0038 +} diff --git a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr new file mode 100644 index 00000000000..7378ec023c9 --- /dev/null +++ b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr @@ -0,0 +1,38 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:15 + | +LL | let test: &mut dyn Bar = &mut thing; + | ^^^^^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mention-correct-dyn-incompatible-trait.rs:4:8 + | +LL | fn foo<T>(&self, val: T); + | ^^^ ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + = help: only type `Thing` implements the trait, consider using it directly instead + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:30 + | +LL | let test: &mut dyn Bar = &mut thing; + | ^^^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mention-correct-dyn-incompatible-trait.rs:4:8 + | +LL | fn foo<T>(&self, val: T); + | ^^^ ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + = help: only type `Thing` implements the trait, consider using it directly instead + = note: required for the cast from `&mut Thing` to `&mut dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.rs b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.rs new file mode 100644 index 00000000000..c9ec44cc0b8 --- /dev/null +++ b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.rs @@ -0,0 +1,44 @@ +// Regression test for #22040. + +use std::fmt::Debug; + +trait Expr: Debug + PartialEq { + fn print_element_count(&self); +} + +//#[derive(PartialEq)] +#[derive(Debug)] +struct SExpr<'x> { + elements: Vec<Box<dyn Expr + 'x>>, + //~^ ERROR E0038 +} + +impl<'x> PartialEq for SExpr<'x> { + fn eq(&self, other:&SExpr<'x>) -> bool { + println!("L1: {} L2: {}", self.elements.len(), other.elements.len()); + + let result = self.elements.len() == other.elements.len(); + + println!("Got compare {}", result); + return result; + } +} + +impl <'x> SExpr<'x> { + fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; } +} + +impl <'x> Expr for SExpr<'x> { + fn print_element_count(&self) { + println!("element count: {}", self.elements.len()); + } +} + +fn main() { + let a: Box<dyn Expr> = Box::new(SExpr::new()); + //~^ ERROR: `Expr` cannot be made into an object + let b: Box<dyn Expr> = Box::new(SExpr::new()); + //~^ ERROR: `Expr` cannot be made into an object + + // assert_eq!(a , b); +} diff --git a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr new file mode 100644 index 00000000000..7578edce7d1 --- /dev/null +++ b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr @@ -0,0 +1,48 @@ +error[E0038]: the trait `Expr` cannot be made into an object + --> $DIR/mentions-Self-in-super-predicates.rs:12:23 + | +LL | elements: Vec<Box<dyn Expr + 'x>>, + | ^^^^^^^^^^^^^ `Expr` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self-in-super-predicates.rs:5:21 + | +LL | trait Expr: Debug + PartialEq { + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + = help: only type `SExpr<'x>` implements the trait, consider using it directly instead + +error[E0038]: the trait `Expr` cannot be made into an object + --> $DIR/mentions-Self-in-super-predicates.rs:38:16 + | +LL | let a: Box<dyn Expr> = Box::new(SExpr::new()); + | ^^^^^^^^ `Expr` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self-in-super-predicates.rs:5:21 + | +LL | trait Expr: Debug + PartialEq { + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + = help: only type `SExpr<'x>` implements the trait, consider using it directly instead + +error[E0038]: the trait `Expr` cannot be made into an object + --> $DIR/mentions-Self-in-super-predicates.rs:40:16 + | +LL | let b: Box<dyn Expr> = Box::new(SExpr::new()); + | ^^^^^^^^ `Expr` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self-in-super-predicates.rs:5:21 + | +LL | trait Expr: Debug + PartialEq { + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + = help: only type `SExpr<'x>` implements the trait, consider using it directly instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr new file mode 100644 index 00000000000..434e41cf218 --- /dev/null +++ b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr @@ -0,0 +1,65 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/mentions-Self.rs:22:31 + | +LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/mentions-Self.rs:28:31 + | +LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { + | ^^^^^^^ `Baz` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/mentions-Self.rs:24:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +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 for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/mentions-Self.rs:30:5 + | +LL | t + | ^ `Baz` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +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 for the cast from `&T` to `&dyn Baz` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..dc2d1f87eb7 --- /dev/null +++ b/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,35 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/mentions-Self.rs:24:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +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 for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/mentions-Self.rs:30:5 + | +LL | t + | ^ `Baz` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +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 for the cast from `&T` to `&dyn Baz` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/mentions-Self.rs b/tests/ui/dyn-compatibility/mentions-Self.rs new file mode 100644 index 00000000000..84c229e252d --- /dev/null +++ b/tests/ui/dyn-compatibility/mentions-Self.rs @@ -0,0 +1,42 @@ +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return +// position, unless `where Self : Sized` is present.. +// +//@ revisions: curr dyn_compatible_for_dispatch + +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] + + +trait Bar { + fn bar(&self, x: &Self); +} + +trait Baz { + fn baz(&self) -> Self; +} + +trait Quux { + fn quux(&self, s: &Self) -> Self where Self : Sized; +} + +fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //~^ ERROR E0038 +} + +fn make_baz<T:Baz>(t: &T) -> &dyn Baz { + //[curr]~^ ERROR E0038 + t + //~^ ERROR E0038 +} + +fn make_quux<T:Quux>(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux { + t as &dyn Quux +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.rs b/tests/ui/dyn-compatibility/missing-assoc-type.rs new file mode 100644 index 00000000000..c83be544c0a --- /dev/null +++ b/tests/ui/dyn-compatibility/missing-assoc-type.rs @@ -0,0 +1,10 @@ +trait Foo { + type Bar<T>; +} + +fn bar(x: &dyn Foo) {} //~ ERROR the trait `Foo` cannot be made into an object +//~^ ERROR the trait `Foo` cannot be made into an object +//~| ERROR the trait `Foo` cannot be made into an object +//~| ERROR the trait `Foo` cannot be made into an object + +fn main() {} diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.stderr b/tests/ui/dyn-compatibility/missing-assoc-type.stderr new file mode 100644 index 00000000000..f8450ba212d --- /dev/null +++ b/tests/ui/dyn-compatibility/missing-assoc-type.stderr @@ -0,0 +1,65 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/missing-assoc-type.rs:5:16 + | +LL | fn bar(x: &dyn Foo) {} + | ^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type Bar<T>; + | ^^^ ...because it contains the generic associated type `Bar` + = help: consider moving `Bar` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/missing-assoc-type.rs:5:16 + | +LL | fn bar(x: &dyn Foo) {} + | ^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type Bar<T>; + | ^^^ ...because it contains the generic associated type `Bar` + = help: consider moving `Bar` to another trait + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/missing-assoc-type.rs:5:16 + | +LL | fn bar(x: &dyn Foo) {} + | ^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type Bar<T>; + | ^^^ ...because it contains the generic associated type `Bar` + = help: consider moving `Bar` to another trait + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/missing-assoc-type.rs:5:12 + | +LL | fn bar(x: &dyn Foo) {} + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type Bar<T>; + | ^^^ ...because it contains the generic associated type `Bar` + = help: consider moving `Bar` to another trait + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/no-static.curr.stderr b/tests/ui/dyn-compatibility/no-static.curr.stderr new file mode 100644 index 00000000000..584db779855 --- /dev/null +++ b/tests/ui/dyn-compatibility/no-static.curr.stderr @@ -0,0 +1,73 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/no-static.rs:12:22 + | +LL | fn diverges() -> Box<dyn Foo> { + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/no-static.rs:22:12 + | +LL | let b: Box<dyn Foo> = Box::new(Bar); + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/no-static.rs:22:27 + | +LL | let b: Box<dyn Foo> = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead + = note: required for the cast from `Box<Bar>` to `Box<dyn Foo>` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..f2deb3b8d84 --- /dev/null +++ b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,27 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/no-static.rs:22:27 + | +LL | let b: Box<dyn Foo> = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead + = note: required for the cast from `Box<Bar>` to `Box<dyn Foo>` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/no-static.rs b/tests/ui/dyn-compatibility/no-static.rs new file mode 100644 index 00000000000..54af16fe18e --- /dev/null +++ b/tests/ui/dyn-compatibility/no-static.rs @@ -0,0 +1,25 @@ +// Check that we correctly prevent users from making trait objects +// from traits with static methods. +// +//@ revisions: curr dyn_compatible_for_dispatch + +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] + +trait Foo { + fn foo() {} +} + +fn diverges() -> Box<dyn Foo> { + //[curr]~^ ERROR E0038 + loop { } +} + +struct Bar; + +impl Foo for Bar {} + +fn main() { + let b: Box<dyn Foo> = Box::new(Bar); + //~^ ERROR E0038 + //[curr]~| ERROR E0038 +} diff --git a/tests/ui/dyn-compatibility/phantom-fn.rs b/tests/ui/dyn-compatibility/phantom-fn.rs new file mode 100644 index 00000000000..9e410da82ee --- /dev/null +++ b/tests/ui/dyn-compatibility/phantom-fn.rs @@ -0,0 +1,22 @@ +// Check that `Self` appearing in a phantom fn does not make a trait dyn-incompatible. + +//@ build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] + +trait Baz { +} + +trait Bar<T> { +} + +fn make_bar<T:Bar<u32>>(t: &T) -> &dyn Bar<u32> { + t +} + +fn make_baz<T:Baz>(t: &T) -> &dyn Baz { + t +} + + +fn main() { +} diff --git a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs new file mode 100644 index 00000000000..dabaa309c16 --- /dev/null +++ b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs @@ -0,0 +1,142 @@ +//@ edition:2021 + +trait Trait {} + +struct IceCream; + +impl IceCream { + fn foo(_: &Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bar(self, _: &'a Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + //~| ERROR: use of undeclared lifetime name + + fn alice<'a>(&self, _: &Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bob<'a>(_: &'a Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + + fn cat() -> &Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn dog<'a>() -> &Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn kitten() -> &'a Trait { + //~^ ERROR: use of undeclared lifetime name + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn puppy<'a>() -> &'a Trait { + //~^ ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn parrot() -> &mut Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &mut Type + //~^ ERROR: cannot return reference to temporary value + } +} + +trait Sing { + fn foo(_: &Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bar(_: &'a Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + //~| ERROR: use of undeclared lifetime name + + fn alice<'a>(_: &Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bob<'a>(_: &'a Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + + fn cat() -> &Trait; + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + + fn dog<'a>() -> &Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn kitten() -> &'a Trait { + //~^ ERROR: use of undeclared lifetime name + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn puppy<'a>() -> &'a Trait { + //~^ ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn parrot() -> &mut Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &mut Type + //~^ ERROR: cannot return reference to temporary value + } +} + +fn foo(_: &Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword + +fn bar(_: &'a Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword +//~| ERROR: use of undeclared lifetime name + +fn alice<'a>(_: &Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword + +fn bob<'a>(_: &'a Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword + +struct Type; + +impl Trait for Type {} + +fn cat() -> &Trait { +//~^ ERROR: missing lifetime specifier +//~| ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn dog<'a>() -> &Trait { +//~^ ERROR: missing lifetime specifier +//~| ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn kitten() -> &'a Trait { +//~^ ERROR: use of undeclared lifetime name +//~| ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn puppy<'a>() -> &'a Trait { +//~^ ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn parrot() -> &mut Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &mut Type + //~^ ERROR: cannot return reference to temporary value +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr new file mode 100644 index 00000000000..8bdfea7766e --- /dev/null +++ b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr @@ -0,0 +1,673 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:22 + | +LL | fn bar(self, _: &'a Trait) {} + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn bar<'a>(self, _: &'a Trait) {} + | ++++ +help: consider introducing lifetime `'a` here + | +LL | impl<'a> IceCream { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:17 + | +LL | fn cat() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn cat() -> &'static Trait { + | +++++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:21 + | +LL | fn dog<'a>() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'a` lifetime + | +LL | fn dog<'a>() -> &'a Trait { + | ++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:21 + | +LL | fn kitten() -> &'a Trait { + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn kitten<'a>() -> &'a Trait { + | ++++ +help: consider introducing lifetime `'a` here + | +LL | impl<'a> IceCream { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:20 + | +LL | fn parrot() -> &mut Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn parrot() -> &'static mut Trait { + | +++++++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:16 + | +LL | fn bar(_: &'a Trait); + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn bar<'a>(_: &'a Trait); + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Sing<'a> { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:17 + | +LL | fn cat() -> &Trait; + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn cat() -> &'static Trait; + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - fn cat() -> &Trait; +LL + fn cat() -> Trait; + | + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:21 + | +LL | fn dog<'a>() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'a` lifetime + | +LL | fn dog<'a>() -> &'a Trait { + | ++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:21 + | +LL | fn kitten() -> &'a Trait { + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn kitten<'a>() -> &'a Trait { + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Sing<'a> { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:20 + | +LL | fn parrot() -> &mut Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn parrot() -> &'static mut Trait { + | +++++++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:12 + | +LL | fn bar(_: &'a Trait) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:13 + | +LL | fn cat() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn cat() -> &'static Trait { + | +++++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:17 + | +LL | fn dog<'a>() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'a` lifetime + | +LL | fn dog<'a>() -> &'a Trait { + | ++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:17 + | +LL | fn kitten() -> &'a Trait { + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:16 + | +LL | fn parrot() -> &mut Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn parrot() -> &'static mut Trait { + | +++++++ + +error[E0515]: cannot return reference to temporary value + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:47:9 + | +LL | &mut Type + | ^^^^^---- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:90:9 + | +LL | &mut Type + | ^^^^^---- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:138:5 + | +LL | &mut Type + | ^^^^^---- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:53:16 + | +LL | fn foo(_: &Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn foo<T: Trait>(_: &T); + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn foo(_: &impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn foo(_: &dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:19 + | +LL | fn bar(_: &'a Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bar<T: Trait>(_: &'a T); + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bar(_: &'a impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bar(_: &'a dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:60:22 + | +LL | fn alice<'a>(_: &Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn alice<'a, T: Trait>(_: &T); + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn alice<'a>(_: &impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn alice<'a>(_: &dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:63:23 + | +LL | fn bob<'a>(_: &'a Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bob<'a, T: Trait>(_: &'a T); + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bob<'a>(_: &'a impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bob<'a>(_: &'a dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:18 + | +LL | fn cat() -> &Trait; + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn cat() -> &impl Trait; + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn cat() -> Box<dyn Trait>; + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:22 + | +LL | fn dog<'a>() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn dog<'a>() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn dog<'a>() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:24 + | +LL | fn kitten() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn kitten() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn kitten() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:82:27 + | +LL | fn puppy<'a>() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn puppy<'a>() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn puppy<'a>() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:25 + | +LL | fn parrot() -> &mut Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn parrot() -> &mut impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn parrot() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:95:12 + | +LL | fn foo(_: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn foo<T: Trait>(_: &T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn foo(_: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn foo(_: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:15 + | +LL | fn bar(_: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bar<T: Trait>(_: &'a T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bar(_: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bar(_: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:102:18 + | +LL | fn alice<'a>(_: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn alice<'a, T: Trait>(_: &T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn alice<'a>(_: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn alice<'a>(_: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:105:19 + | +LL | fn bob<'a>(_: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bob<'a, T: Trait>(_: &'a T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bob<'a>(_: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bob<'a>(_: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:14 + | +LL | fn cat() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn cat() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn cat() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:18 + | +LL | fn dog<'a>() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn dog<'a>() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn dog<'a>() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:20 + | +LL | fn kitten() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn kitten() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn kitten() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:130:23 + | +LL | fn puppy<'a>() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn puppy<'a>() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn puppy<'a>() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:21 + | +LL | fn parrot() -> &mut Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn parrot() -> &mut impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn parrot() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:8:16 + | +LL | fn foo(_: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn foo<T: Trait>(_: &T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn foo(_: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn foo(_: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:25 + | +LL | fn bar(self, _: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bar<T: Trait>(self, _: &'a T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bar(self, _: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bar(self, _: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:15:29 + | +LL | fn alice<'a>(&self, _: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn alice<'a, T: Trait>(&self, _: &T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn alice<'a>(&self, _: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn alice<'a>(&self, _: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:18:23 + | +LL | fn bob<'a>(_: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bob<'a, T: Trait>(_: &'a T) {} + | ++++++++++ ~ +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bob<'a>(_: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bob<'a>(_: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:18 + | +LL | fn cat() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn cat() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn cat() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:22 + | +LL | fn dog<'a>() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn dog<'a>() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn dog<'a>() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:24 + | +LL | fn kitten() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn kitten() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn kitten() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:39:27 + | +LL | fn puppy<'a>() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn puppy<'a>() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn puppy<'a>() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:25 + | +LL | fn parrot() -> &mut Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn parrot() -> &mut impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn parrot() -> Box<dyn Trait> { + | ~~~~~~~~~~~~~~ + +error: aborting due to 45 previous errors + +Some errors have detailed explanations: E0106, E0261, E0515, E0782. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/dyn-compatibility/sized-2.curr.stderr b/tests/ui/dyn-compatibility/sized-2.curr.stderr new file mode 100644 index 00000000000..1017fde53d3 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized-2.curr.stderr @@ -0,0 +1,32 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/sized-2.rs:14:31 + | +LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/sized-2.rs:16:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..534cf0f1b03 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/sized-2.rs:16:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized-2.rs b/tests/ui/dyn-compatibility/sized-2.rs new file mode 100644 index 00000000000..f5edd287f24 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized-2.rs @@ -0,0 +1,21 @@ +// Check that we correctly prevent users from making trait objects +// from traits where `Self : Sized`. +// +//@ revisions: curr dyn_compatible_for_dispatch + +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] + +trait Bar + where Self : Sized +{ + fn bar<T>(&self, t: T); +} + +fn make_bar<T:Bar>(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //~^ ERROR E0038 +} + +fn main() { +} diff --git a/tests/ui/dyn-compatibility/sized.curr.stderr b/tests/ui/dyn-compatibility/sized.curr.stderr new file mode 100644 index 00000000000..613833aad12 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized.curr.stderr @@ -0,0 +1,32 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/sized.rs:12:32 + | +LL | fn make_bar<T: Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/sized.rs:8:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/sized.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/sized.rs:8:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..cf847bc1577 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/sized.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/sized.rs:8:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized.rs b/tests/ui/dyn-compatibility/sized.rs new file mode 100644 index 00000000000..4c4fe3f8f25 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized.rs @@ -0,0 +1,18 @@ +// Check that we correctly prevent users from making trait objects +// from traits where `Self : Sized`. +// +//@ revisions: curr dyn_compatible_for_dispatch + +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] + +trait Bar: Sized { + fn bar<T>(&self, t: T); +} + +fn make_bar<T: Bar>(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //~^ ERROR E0038 +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.rs b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.rs new file mode 100644 index 00000000000..14e00d2ef32 --- /dev/null +++ b/tests/ui/dyn-compatibility/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/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr new file mode 100644 index 00000000000..ac5a5b28d94 --- /dev/null +++ b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr @@ -0,0 +1,42 @@ +error[E0311]: the parameter type `Self` may not live long enough + | +note: ...that is required by this bound + --> $DIR/supertrait-mentions-GAT.rs:6:15 + | +LL | Self: 'a; + | ^^ + = help: consider adding an explicit lifetime bound `Self: 'a`... + +error: associated item referring to unboxed trait object for its own trait + --> $DIR/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/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 "dyn-compatible" 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/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`. diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-Self.rs b/tests/ui/dyn-compatibility/supertrait-mentions-Self.rs new file mode 100644 index 00000000000..d96c7ba72a3 --- /dev/null +++ b/tests/ui/dyn-compatibility/supertrait-mentions-Self.rs @@ -0,0 +1,22 @@ +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return position. + +trait Bar<T> { + fn bar(&self, x: &T); +} + +trait Baz : Bar<Self> { + //~^ ERROR the size for values of type `Self` cannot be known +} + +fn make_bar<T:Bar<u32>>(t: &T) -> &dyn Bar<u32> { + t +} + +fn make_baz<T:Baz>(t: &T) -> &dyn Baz { + //~^ ERROR E0038 + t +} + +fn main() { +} diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr new file mode 100644 index 00000000000..6474b115c46 --- /dev/null +++ b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr @@ -0,0 +1,42 @@ +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/supertrait-mentions-Self.rs:8:13 + | +LL | trait Baz : Bar<Self> { + | ^^^^^^^^^ doesn't have a size known at compile-time + | +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/supertrait-mentions-Self.rs:4:11 + | +LL | trait Bar<T> { + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: consider further restricting `Self` + | +LL | trait Baz : Bar<Self> + Sized { + | +++++++ +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Bar<T: ?Sized> { + | ++++++++ + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/supertrait-mentions-Self.rs:16:31 + | +LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { + | ^^^^^^^ `Baz` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/supertrait-mentions-Self.rs:8:13 + | +LL | trait Baz : Bar<Self> { + | --- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... +help: consider using an opaque type instead + | +LL | fn make_baz<T:Baz>(t: &T) -> &impl Baz { + | ~~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.rs b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.rs new file mode 100644 index 00000000000..5c71bd7769c --- /dev/null +++ b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.rs @@ -0,0 +1,29 @@ +//@ compile-flags: --crate-type=lib +// This test checks that the `where_clauses_object_safety` lint does not cause +// other dyn-compatibility *hard errors* to be suppressed, because we currently +// only emit one dyn-compatibility error per trait... +// issue: rust-lang/rust#102762 + +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(); + //~^ ERROR the trait `Fetcher` cannot be made into an object + let _ = fetcher.get(); + //~^ ERROR the trait `Fetcher` cannot be made into an object +} diff --git a/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr new file mode 100644 index 00000000000..8d62ac9d923 --- /dev/null +++ b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr @@ -0,0 +1,54 @@ +error[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:19: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 "dyn-compatible" 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/undispatchable-receiver-and-wc-references-Self.rs:11: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[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:25:19 + | +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 | let fetcher = fetcher(); + | ^^^^^^^^^ `Fetcher` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/undispatchable-receiver-and-wc-references-Self.rs:11: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[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:27:13 + | +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 | let _ = fetcher.get(); + | ^^^^^^^^^^^^^ `Fetcher` cannot be made into an object + | +note: for a trait to be "dyn-compatible" 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/undispatchable-receiver-and-wc-references-Self.rs:11: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 3 previous errors + +For more information about this error, try `rustc --explain E0038`. |
