Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Suboptimal diagnostics when trying to create a trait object for a trait with GATs #103155

Closed
PatchMixolydic opened this issue Oct 17, 2022 · 0 comments · Fixed by #116405
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-GATs Area: Generic associated types (GATs) D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@PatchMixolydic
Copy link
Contributor

PatchMixolydic commented Oct 17, 2022

Given the following code (playground 1):

trait Foo {
    type Bar<T>;
}

fn bar(x: &dyn Foo) {}

The current output is:

error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified
 --> src/lib.rs:5:16
  |
2 |     type Bar<T>;
  |     ----------- `Bar` defined here
...
5 | fn bar(x: &dyn Foo) {}
  |                ^^^ help: specify the associated type: `Foo<Bar = Type>`

Following this suggestion (playground 2)...

trait Foo {
    type Bar<T>;
}

fn bar(x: &dyn Foo<Bar = i32>) {}

... produces another diagnostic:

error[E0107]: missing generics for associated type `Foo::Bar`
 --> src/lib.rs:5:20
  |
5 | fn bar(x: &dyn Foo<Bar = i32>) {}
  |                    ^^^ expected 1 generic argument
  |
note: associated type defined here, with 1 generic parameter: `T`
 --> src/lib.rs:2:10
  |
2 |     type Bar<T>;
  |          ^^^ -
help: add missing generic argument
  |
5 | fn bar(x: &dyn Foo<Bar<T> = i32>) {}
  |                    ~~~~~~

Finally, specifying the generic argument for Bar (playground 3)...

trait Foo {
    type Bar<T>;
}

fn bar(x: &dyn Foo<Bar<i32> = i32>) {}

... reveals that our struggle was all for naught:

error[E0038]: the trait `Foo` cannot be made into an object
 --> src/lib.rs:5:12
  |
5 | fn bar(x: &dyn Foo<Bar<i32> = i32>) {}
  |            ^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
  |
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 --> src/lib.rs:2:10
  |
1 | trait Foo {
  |       --- this trait cannot be made into an object...
2 |     type Bar<T>;
  |          ^^^ ...because it contains the generic associated type `Bar`
  = help: consider moving `Bar` to another trait

Ideally, the first snippet should produce an object safety error right away:

error[E0038]: the trait `Foo` cannot be made into an object
 --> src/lib.rs:5:12
  |
5 | fn bar(x: &dyn Foo) {}
  |            ^^^^^^^ `Foo` cannot be made into an object
  |
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 --> src/lib.rs:2:10
  |
1 | trait Foo {
  |       --- this trait cannot be made into an object...
2 |     type Bar<T>;
  |          ^^^ ...because it contains the generic associated type `Bar`
  = help: consider moving `Bar` to another trait

In case #![feature(generic_associated_types_extended)] is enabled, E0191 should still be emitted, but the suggestion should include the generic argument for Bar:

error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified
 --> src/lib.rs:5:16
  |
2 |     type Bar<T>;
  |     ----------- `Bar` defined here
...
5 | fn bar(x: &dyn Foo) {}
  |                ^^^ help: specify the associated type: `Foo<Bar<T> = Type>`

@rustbot modify labels +D-terse +F-generic_associated_types

@PatchMixolydic PatchMixolydic 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 Oct 17, 2022
@rustbot rustbot added D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs labels Oct 17, 2022
@PatchMixolydic PatchMixolydic changed the title Poor diagnostics when trying to create a trait object for a trait with GATs Suboptimal diagnostics when trying to create a trait object for a trait with GATs Oct 17, 2022
@compiler-errors compiler-errors self-assigned this Oct 17, 2022
@compiler-errors compiler-errors removed their assignment Jan 5, 2023
estebank added a commit to estebank/rust that referenced this issue Oct 4, 2023
When an associated type with GATs isn't specified in a `dyn Trait`, emit
an object safety error instead of only complaining about the missing
associated type, as it will lead the user down a path of three different
errors before letting them know that what they were trying to do is
impossible to begin with.

Fix rust-lang#103155.
estebank added a commit to estebank/rust that referenced this issue Oct 18, 2023
When an associated type with GATs isn't specified in a `dyn Trait`, emit
an object safety error instead of only complaining about the missing
associated type, as it will lead the user down a path of three different
errors before letting them know that what they were trying to do is
impossible to begin with.

Fix rust-lang#103155.
estebank added a commit to estebank/rust that referenced this issue Oct 26, 2023
When an associated type with GATs isn't specified in a `dyn Trait`, emit
an object safety error instead of only complaining about the missing
associated type, as it will lead the user down a path of three different
errors before letting them know that what they were trying to do is
impossible to begin with.

Fix rust-lang#103155.
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 28, 2023
Detect object safety errors when assoc type is missing

When an associated type with GATs isn't specified in a `dyn Trait`, emit an object safety error instead of only complaining about the missing associated type, as it will lead the user down a path of three different errors before letting them know that what they were trying to do is impossible to begin with.

Fix rust-lang#103155.
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 30, 2023
Detect object safety errors when assoc type is missing

When an associated type with GATs isn't specified in a `dyn Trait`, emit an object safety error instead of only complaining about the missing associated type, as it will lead the user down a path of three different errors before letting them know that what they were trying to do is impossible to begin with.

Fix rust-lang#103155.
@bors bors closed this as completed in 17a6ae2 Oct 31, 2023
@fmease fmease added the A-GATs Area: Generic associated types (GATs) label Nov 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-GATs Area: Generic associated types (GATs) D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs 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.

4 participants