Skip to content

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

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

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
# 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-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