about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-01-20 09:37:27 +0100
committerGitHub <noreply@github.com>2024-01-20 09:37:27 +0100
commit177d51372cf1b6bedc634f18a74c2052d8921d9b (patch)
tree9c15067f1f383632b043ec619a543ac45c915ac1 /tests
parent2de5ca25d2aa658553e75eedcdb6968a0d53d969 (diff)
parent7edbc95c27664428ba22c448ca85ee4bd4de05dc (diff)
downloadrust-177d51372cf1b6bedc634f18a74c2052d8921d9b.tar.gz
rust-177d51372cf1b6bedc634f18a74c2052d8921d9b.zip
Rollup merge of #119752 - estebank:ice-ice, r=fmease
Avoid ICEs in trait names without `dyn`

Check diagnostic is error before downgrading. Fix #119633.

 Account for traits using self-trait by name without `dyn`. Fix #119652.
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-2.rs9
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-2.stderr50
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-3.rs17
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-3.stderr148
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning.rs6
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning.stderr29
-rw-r--r--tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.rs23
-rw-r--r--tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.stderr168
-rw-r--r--tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.rs17
-rw-r--r--tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.stderr65
10 files changed, 532 insertions, 0 deletions
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.rs b/tests/ui/object-safety/avoid-ice-on-warning-2.rs
new file mode 100644
index 00000000000..cd34362d3dd
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.rs
@@ -0,0 +1,9 @@
+fn id<F>(f: Copy) -> usize {
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+//~| ERROR the trait `Copy` cannot be made into an object
+    f()
+}
+fn main() {}
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.stderr
new file mode 100644
index 00000000000..2755eee6f35
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.stderr
@@ -0,0 +1,50 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-2.rs:1: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: `Copy` it is not object safe, so it can't be `dyn`
+   = note: `#[warn(bare_trait_objects)]` on by default
+help: use a new generic type parameter, constrained by `Copy`
+   |
+LL | fn id<F, T: Copy>(f: T) -> usize {
+   |        +++++++++     ~
+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 id<F>(f: impl Copy) -> usize {
+   |             ++++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-2.rs:1: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: `Copy` it is not object safe, so it can't be `dyn`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: use a new generic type parameter, constrained by `Copy`
+   |
+LL | fn id<F, T: Copy>(f: T) -> usize {
+   |        +++++++++     ~
+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 id<F>(f: impl Copy) -> usize {
+   |             ++++
+
+error[E0038]: the trait `Copy` cannot be made into an object
+  --> $DIR/avoid-ice-on-warning-2.rs:1: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 "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+error: aborting due to 1 previous error; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.rs b/tests/ui/object-safety/avoid-ice-on-warning-3.rs
new file mode 100644
index 00000000000..caaf4d0fd99
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.rs
@@ -0,0 +1,17 @@
+trait B { fn f(a: A) -> A; }
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
+//~| ERROR the trait `A` cannot be made into an object
+trait A { fn g(b: B) -> B; }
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
+//~| ERROR the trait `B` cannot be made into an object
+fn main() {}
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.stderr
new file mode 100644
index 00000000000..0fc67770b96
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.stderr
@@ -0,0 +1,148 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-3.rs:9: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: `B` it is not object safe, so it can't be `dyn`
+   = note: `#[warn(bare_trait_objects)]` on by default
+help: use a new generic type parameter, constrained by `B`
+   |
+LL | trait A { fn g<T: B>(b: T) -> B; }
+   |               ++++++    ~
+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 | trait A { fn g(b: impl B) -> B; }
+   |                   ++++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-3.rs:9: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: `B` is not object safe, use `impl B` to return an opaque type, as long as you return a single underlying type
+   |
+LL | trait A { fn g(b: B) -> impl B; }
+   |                         ++++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-3.rs:1: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: `A` it is not object safe, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `A`
+   |
+LL | trait B { fn f<T: A>(a: T) -> A; }
+   |               ++++++    ~
+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 | trait B { fn f(a: impl A) -> A; }
+   |                   ++++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-3.rs:1: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: `A` is not object safe, use `impl A` to return an opaque type, as long as you return a single underlying type
+   |
+LL | trait B { fn f(a: A) -> impl A; }
+   |                         ++++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/avoid-ice-on-warning-3.rs:1: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: `A` it is not object safe, so it can't be `dyn`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: use a new generic type parameter, constrained by `A`
+   |
+LL | trait B { fn f<T: A>(a: T) -> A; }
+   |               ++++++    ~
+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 | trait B { fn f(a: impl A) -> A; }
+   |                   ++++
+
+error[E0038]: the trait `A` cannot be made into an object
+  --> $DIR/avoid-ice-on-warning-3.rs:1:19
+   |
+LL | trait B { fn f(a: A) -> A; }
+   |                   ^ `A` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/avoid-ice-on-warning-3.rs:9: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:9: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: `B` it is not object safe, so it can't be `dyn`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: use a new generic type parameter, constrained by `B`
+   |
+LL | trait A { fn g<T: B>(b: T) -> B; }
+   |               ++++++    ~
+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 | trait A { fn g(b: impl B) -> B; }
+   |                   ++++
+
+error[E0038]: the trait `B` cannot be made into an object
+  --> $DIR/avoid-ice-on-warning-3.rs:9:19
+   |
+LL | trait A { fn g(b: B) -> B; }
+   |                   ^ `B` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/avoid-ice-on-warning-3.rs:1: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/object-safety/avoid-ice-on-warning.rs b/tests/ui/object-safety/avoid-ice-on-warning.rs
new file mode 100644
index 00000000000..d2a1eeb5286
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning.rs
@@ -0,0 +1,6 @@
+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
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| 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/object-safety/avoid-ice-on-warning.stderr b/tests/ui/object-safety/avoid-ice-on-warning.stderr
new file mode 100644
index 00000000000..1046f177e82
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning.stderr
@@ -0,0 +1,29 @@
+error: return types are denoted using `->`
+  --> $DIR/avoid-ice-on-warning.rs:1:23
+   |
+LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
+   |                       ^ help: use `->` instead
+
+error[E0405]: cannot find trait `call_that` in this scope
+  --> $DIR/avoid-ice-on-warning.rs:1: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:1: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: `Fn(&str) + call_that` is not object safe, use `impl Fn(&str) + call_that` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn call_this<F>(f: F) : impl 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/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.rs b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.rs
new file mode 100644
index 00000000000..f48c3d124dd
--- /dev/null
+++ b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.rs
@@ -0,0 +1,23 @@
+// edition:2021
+#![allow(bare_trait_objects)]
+trait A: Sized {
+    fn f(a: A) -> A;
+    //~^ ERROR trait objects must include the `dyn` keyword
+    //~| ERROR trait objects must include the `dyn` keyword
+    //~| ERROR associated item referring to unboxed trait object for its own trait
+    //~| ERROR the trait `A` cannot be made into an object
+}
+trait B {
+    fn f(a: B) -> B;
+    //~^ ERROR trait objects must include the `dyn` keyword
+    //~| ERROR trait objects must include the `dyn` keyword
+    //~| ERROR associated item referring to unboxed trait object for its own trait
+    //~| ERROR the trait `B` cannot be made into an object
+}
+trait C {
+    fn f(&self, a: C) -> C;
+    //~^ ERROR trait objects must include the `dyn` keyword
+    //~| ERROR trait objects must include the `dyn` keyword
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.stderr b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.stderr
new file mode 100644
index 00000000000..73d5a24f831
--- /dev/null
+++ b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021-without-dyn.stderr
@@ -0,0 +1,168 @@
+error: associated item referring to unboxed trait object for its own trait
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:4:13
+   |
+LL | trait A: Sized {
+   |       - in this trait
+LL |     fn f(a: A) -> A;
+   |             ^     ^
+   |
+help: you might have meant to use `Self` to refer to the implementing type
+   |
+LL |     fn f(a: Self) -> Self;
+   |             ~~~~     ~~~~
+
+error[E0038]: the trait `A` cannot be made into an object
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:4:13
+   |
+LL |     fn f(a: A) -> A;
+   |             ^ `A` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:3:10
+   |
+LL | trait A: Sized {
+   |       -  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+
+error: associated item referring to unboxed trait object for its own trait
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:11:13
+   |
+LL | trait B {
+   |       - in this trait
+LL |     fn f(a: B) -> B;
+   |             ^     ^
+   |
+help: you might have meant to use `Self` to refer to the implementing type
+   |
+LL |     fn f(a: Self) -> Self;
+   |             ~~~~     ~~~~
+
+error[E0038]: the trait `B` cannot be made into an object
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:11:13
+   |
+LL |     fn f(a: B) -> B;
+   |             ^ `B` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:11:8
+   |
+LL | trait B {
+   |       - this trait cannot be made into an object...
+LL |     fn f(a: B) -> B;
+   |        ^ ...because associated function `f` has no `self` parameter
+help: consider turning `f` into a method by giving it a `&self` argument
+   |
+LL |     fn f(&self, a: B) -> B;
+   |          ++++++
+help: alternatively, consider constraining `f` so it does not apply to trait objects
+   |
+LL |     fn f(a: B) -> B where Self: Sized;
+   |                     +++++++++++++++++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:4:13
+   |
+LL |     fn f(a: A) -> A;
+   |             ^
+   |
+help: use a new generic type parameter, constrained by `A`
+   |
+LL |     fn f<T: A>(a: T) -> A;
+   |         ++++++    ~
+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 f(a: impl A) -> A;
+   |             ++++
+help: alternatively, use a trait object to accept any type that implements `A`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn f(a: &dyn A) -> A;
+   |             ++++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:4:19
+   |
+LL |     fn f(a: A) -> A;
+   |                   ^
+   |
+help: use `impl A` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn f(a: A) -> impl A;
+   |                   ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn f(a: A) -> Box<dyn A>;
+   |                   +++++++  +
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:11:13
+   |
+LL |     fn f(a: B) -> B;
+   |             ^
+   |
+help: use a new generic type parameter, constrained by `B`
+   |
+LL |     fn f<T: B>(a: T) -> B;
+   |         ++++++    ~
+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 f(a: impl B) -> B;
+   |             ++++
+help: alternatively, use a trait object to accept any type that implements `B`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn f(a: &dyn B) -> B;
+   |             ++++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:11:19
+   |
+LL |     fn f(a: B) -> B;
+   |                   ^
+   |
+help: use `impl B` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn f(a: B) -> impl B;
+   |                   ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn f(a: B) -> Box<dyn B>;
+   |                   +++++++  +
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:18:20
+   |
+LL |     fn f(&self, a: C) -> C;
+   |                    ^
+   |
+help: use a new generic type parameter, constrained by `C`
+   |
+LL |     fn f<T: C>(&self, a: T) -> C;
+   |         ++++++           ~
+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 f(&self, a: impl C) -> C;
+   |                    ++++
+help: alternatively, use a trait object to accept any type that implements `C`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn f(&self, a: &dyn C) -> C;
+   |                    ++++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/object-unsafe-trait-should-use-self-2021-without-dyn.rs:18:26
+   |
+LL |     fn f(&self, a: C) -> C;
+   |                          ^
+   |
+help: use `impl C` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn f(&self, a: C) -> impl C;
+   |                          ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn f(&self, a: C) -> Box<dyn C>;
+   |                          +++++++  +
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0038, E0782.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.rs b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.rs
new file mode 100644
index 00000000000..a598e883f3f
--- /dev/null
+++ b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.rs
@@ -0,0 +1,17 @@
+// edition:2021
+#![allow(bare_trait_objects)]
+trait A: Sized {
+    fn f(a: dyn A) -> dyn A;
+    //~^ ERROR associated item referring to unboxed trait object for its own trait
+    //~| ERROR the trait `A` cannot be made into an object
+}
+trait B {
+    fn f(a: dyn B) -> dyn B;
+    //~^ ERROR associated item referring to unboxed trait object for its own trait
+    //~| ERROR the trait `B` cannot be made into an object
+}
+trait C {
+    fn f(&self, a: dyn C) -> dyn C;
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.stderr b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.stderr
new file mode 100644
index 00000000000..d6376be9c04
--- /dev/null
+++ b/tests/ui/suggestions/object-unsafe-trait-should-use-self-2021.stderr
@@ -0,0 +1,65 @@
+error: associated item referring to unboxed trait object for its own trait
+  --> $DIR/object-unsafe-trait-should-use-self-2021.rs:4:13
+   |
+LL | trait A: Sized {
+   |       - in this trait
+LL |     fn f(a: dyn A) -> dyn A;
+   |             ^^^^^     ^^^^^
+   |
+help: you might have meant to use `Self` to refer to the implementing type
+   |
+LL |     fn f(a: Self) -> Self;
+   |             ~~~~     ~~~~
+
+error[E0038]: the trait `A` cannot be made into an object
+  --> $DIR/object-unsafe-trait-should-use-self-2021.rs:4:13
+   |
+LL |     fn f(a: dyn A) -> dyn A;
+   |             ^^^^^ `A` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-self-2021.rs:3:10
+   |
+LL | trait A: Sized {
+   |       -  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+
+error: associated item referring to unboxed trait object for its own trait
+  --> $DIR/object-unsafe-trait-should-use-self-2021.rs:9:13
+   |
+LL | trait B {
+   |       - in this trait
+LL |     fn f(a: dyn B) -> dyn B;
+   |             ^^^^^     ^^^^^
+   |
+help: you might have meant to use `Self` to refer to the implementing type
+   |
+LL |     fn f(a: Self) -> Self;
+   |             ~~~~     ~~~~
+
+error[E0038]: the trait `B` cannot be made into an object
+  --> $DIR/object-unsafe-trait-should-use-self-2021.rs:9:13
+   |
+LL |     fn f(a: dyn B) -> dyn B;
+   |             ^^^^^ `B` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-self-2021.rs:9:8
+   |
+LL | trait B {
+   |       - this trait cannot be made into an object...
+LL |     fn f(a: dyn B) -> dyn B;
+   |        ^ ...because associated function `f` has no `self` parameter
+help: consider turning `f` into a method by giving it a `&self` argument
+   |
+LL |     fn f(&self, a: dyn B) -> dyn B;
+   |          ++++++
+help: alternatively, consider constraining `f` so it does not apply to trait objects
+   |
+LL |     fn f(a: dyn B) -> dyn B where Self: Sized;
+   |                             +++++++++++++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0038`.