Skip to content

More helpful output for slightly-wrong dyn with multiple traits. #84772

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
jonhoo opened this issue May 1, 2021 · 1 comment · Fixed by #84896
Open

More helpful output for slightly-wrong dyn with multiple traits. #84772

jonhoo opened this issue May 1, 2021 · 1 comment · Fixed by #84896
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The lexing & parsing of Rust source code to an AST D-confusing Diagnostics: Confusing error or lint that should be reworked. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jonhoo
Copy link
Contributor

jonhoo commented May 1, 2021

I recently tried to demonstrate why dyn Trait1 + Trait2 doesn't work. I ended up writing (all examples below on playground):

pub fn foo1(_: &dyn Drop + AsRef<str>) {}

and because I was in my editor, I only saw the first part of the error: "ambiguous + in a type". As a result, rather than follow the helpful compiler error

1 | pub fn foo1(_: &dyn Drop + AsRef<str>) {}
  |                 ^^^^^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(dyn Drop + AsRef<str>)`

I went ahead and tried to fix the syntax myself. Unfortunately, those only gave me worse error messages. I tried:


pub fn foo2(_: &dyn (Drop + AsRef<str>)) {}

which gives

error: expected one of `(`, `)`, `::`, or `<`, found `+`
 --> src/lib.rs:3:27
  |
3 | pub fn foo2(_: &dyn (Drop + AsRef<str>)) {}
  |                           ^ expected one of `(`, `)`, `::`, or `<`

error: expected one of `->`, `;`, `where`, or `{`, found `)`
 --> src/lib.rs:3:40
  |
3 | pub fn foo2(_: &dyn (Drop + AsRef<str>)) {}
  |                                        ^ expected one of `->`, `;`, `where`, or `{`

I tried:

pub fn foo3(_: &dyn {Drop + AsRef<str>}) {}

Which gives

error: expected parameter name, found `{`
 --> src/lib.rs:5:21
  |
5 | pub fn foo3(_: &dyn {Drop + AsRef<str>}) {}
  |                     ^ expected parameter name

error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, lifetime, or path, found `{`
 --> src/lib.rs:5:21
  |
5 | pub fn foo3(_: &dyn {Drop + AsRef<str>}) {}
  |                    -^ expected one of 8 possible tokens
  |                    |
  |                    help: missing `,`

error[E0224]: at least one trait is required for an object type
 --> src/lib.rs:5:17
  |
5 | pub fn foo3(_: &dyn {Drop + AsRef<str>}) {}

This one is particularly egregious as it suggests there's a missing ,.


I tried:

pub fn foo4(_: &dyn <Drop + AsRef<str>>) {}

Which gives

error: expected identifier, found `<`
 --> src/lib.rs:7:21
  |
7 | pub fn foo4(_: &dyn <Drop + AsRef<str>>) {}
  |                     ^ expected identifier

I tried:

pub fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}

Which gives

error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, lifetime, or path, found keyword `dyn`
 --> src/lib.rs:9:29
  |
9 | pub fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
  |                            -^^^ expected one of 8 possible tokens
  |                            |
  |                            help: missing `,`

error[E0277]: the size for values of type `dyn Drop` cannot be known at compilation time
 --> src/lib.rs:9:16
  |
9 | pub fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `dyn Drop`
  = note: only the last element of a tuple may have a dynamically sized type

This one is even more problematic as it not only suggests there's a missing ,, but also suggests that dyn Drop is the problem.


Ideally, all of these cases should point out that I probably meant &(dyn Drop + AsRef<str>), and also give the friendly "only auto traits can be used as additional traits in a trait object" message.

The error messages are (currently) all the same on nightly.

See also discussion on Twitter.

@jonhoo jonhoo added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 1, 2021
@estebank estebank added A-parser Area: The lexing & parsing of Rust source code to an AST D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. labels May 1, 2021
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue May 5, 2021
Handle incorrect placement of parentheses in trait bounds more gracefully

Fix rust-lang#84772.

CC `@jonhoo`
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue May 5, 2021
Handle incorrect placement of parentheses in trait bounds more gracefully

Fix rust-lang#84772.

CC ``@jonhoo``
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
Handle incorrect placement of parentheses in trait bounds more gracefully

Fix rust-lang#84772.

CC ```@jonhoo```
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
Handle incorrect placement of parentheses in trait bounds more gracefully

Fix rust-lang#84772.

CC ````@jonhoo````
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
Handle incorrect placement of parentheses in trait bounds more gracefully

Fix rust-lang#84772.

CC `````@jonhoo`````
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
Handle incorrect placement of parentheses in trait bounds more gracefully

Fix rust-lang#84772.

CC ``````@jonhoo``````
@bors bors closed this as completed in 6b64202 May 7, 2021
@estebank
Copy link
Contributor

estebank commented May 7, 2021

Reopening and keeping around for a single unhandled case left: pub fn foo3(_: &dyn {Drop + AsRef<str>}) {}

@estebank estebank reopened this May 7, 2021
@estebank estebank added P-low Low priority and removed D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. labels May 7, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The lexing & parsing of Rust source code to an AST D-confusing Diagnostics: Confusing error or lint that should be reworked. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants