about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-12-20 00:37:57 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-01-03 18:59:42 +0000
commit048750077676190a0733112d8f700e76a0553f60 (patch)
treef92c004a42f15bc9a4dad76118af770227951ebd /tests
parent1a47f5b448f1e023e7ffd2eb57d473d619d2c04d (diff)
downloadrust-048750077676190a0733112d8f700e76a0553f60.tar.gz
rust-048750077676190a0733112d8f700e76a0553f60.zip
Provide better suggestions when encountering a bare trait as a type
Add the following suggestions:

```
error[E0782]: trait objects must include the `dyn` keyword
  --> $DIR/not-on-bare-trait-2021.rs:11:11
   |
LL | fn bar(x: Foo) -> Foo {
   |           ^^^
   |
help: use a generic type parameter, constrained by the trait `Foo`
   |
LL | fn bar<T: Foo>(x: T) -> Foo {
   |       ++++++++    ~
help: you can also use `impl Foo`, but users won't be able to specify the type paramer when calling the `fn`, having to rely exclusively on type inference
   |
LL | fn bar(x: impl Foo) -> Foo {
   |           ++++
help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch
   |
LL | fn bar(x: &dyn Foo) -> Foo {
   |           ++++

error[E0782]: trait objects must include the `dyn` keyword
  --> $DIR/not-on-bare-trait-2021.rs:11:19
   |
LL | fn bar(x: Foo) -> Foo {
   |                   ^^^
   |
help: use `impl Foo` to return an opaque type, as long as you return a single underlying type
   |
LL | fn bar(x: Foo) -> impl Foo {
   |                   ++++
help: alternatively, you can return an owned trait object
   |
LL | fn bar(x: Foo) -> Box<dyn Foo> {
   |                   +++++++    +
```
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait-2021.rs17
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait-2021.stderr56
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait.stderr14
3 files changed, 84 insertions, 3 deletions
diff --git a/tests/ui/traits/bound/not-on-bare-trait-2021.rs b/tests/ui/traits/bound/not-on-bare-trait-2021.rs
new file mode 100644
index 00000000000..3d97bddb4a4
--- /dev/null
+++ b/tests/ui/traits/bound/not-on-bare-trait-2021.rs
@@ -0,0 +1,17 @@
+// edition:2021
+trait Foo {
+    fn dummy(&self) {}
+}
+
+// This should emit the less confusing error, not the more confusing one.
+
+fn foo(_x: Foo + Send) {
+    //~^ ERROR trait objects must include the `dyn` keyword
+}
+fn bar(x: Foo) -> Foo {
+    //~^ ERROR trait objects must include the `dyn` keyword
+    //~| ERROR trait objects must include the `dyn` keyword
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/traits/bound/not-on-bare-trait-2021.stderr b/tests/ui/traits/bound/not-on-bare-trait-2021.stderr
new file mode 100644
index 00000000000..6f41f872e4c
--- /dev/null
+++ b/tests/ui/traits/bound/not-on-bare-trait-2021.stderr
@@ -0,0 +1,56 @@
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/not-on-bare-trait-2021.rs:8:12
+   |
+LL | fn foo(_x: Foo + Send) {
+   |            ^^^^^^^^^^
+   |
+help: use a new generic type parameter, constrained by `Foo + Send`
+   |
+LL | fn foo<T: Foo + Send>(_x: 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(_x: impl Foo + Send) {
+   |            ++++
+help: alternatively, use a trait object to accept any type that implements `Foo + Send`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn foo(_x: &(dyn Foo + Send)) {
+   |            +++++           +
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/not-on-bare-trait-2021.rs:11:11
+   |
+LL | fn bar(x: Foo) -> Foo {
+   |           ^^^
+   |
+help: use a new generic type parameter, constrained by `Foo`
+   |
+LL | fn bar<T: Foo>(x: T) -> Foo {
+   |       ++++++++    ~
+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(x: impl Foo) -> Foo {
+   |           ++++
+help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn bar(x: &dyn Foo) -> Foo {
+   |           ++++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/not-on-bare-trait-2021.rs:11:19
+   |
+LL | fn bar(x: Foo) -> Foo {
+   |                   ^^^
+   |
+help: use `impl Foo` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn bar(x: Foo) -> impl Foo {
+   |                   ++++
+help: alternatively, you can return an owned trait object
+   |
+LL | fn bar(x: Foo) -> Box<dyn Foo> {
+   |                   +++++++    +
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr
index 1d97bf3d8f9..976dd6a1bc5 100644
--- a/tests/ui/traits/bound/not-on-bare-trait.stderr
+++ b/tests/ui/traits/bound/not-on-bare-trait.stderr
@@ -7,10 +7,18 @@ LL | fn foo(_x: Foo + Send) {
    = 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: use `dyn`
+help: use a new generic type parameter, constrained by `Foo + Send`
    |
-LL | fn foo(_x: dyn Foo + Send) {
-   |            +++
+LL | fn foo<T: Foo + Send>(_x: 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(_x: impl Foo + Send) {
+   |            ++++
+help: alternatively, use a trait object to accept any type that implements `Foo + Send`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn foo(_x: &(dyn Foo + Send)) {
+   |            +++++           +
 
 error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
   --> $DIR/not-on-bare-trait.rs:7:8