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

Rustc suggesting to add a already existing trait bound, instead of relaxing an entirely different one #98539

Closed
onestacked opened this issue Jun 26, 2022 · 1 comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@onestacked
Copy link
Contributor

onestacked commented Jun 26, 2022

I tried this code:

struct Victim<'a, T: Perpetrator + ?Sized>
where
  Self: Sized // rustc suggests adding this trait bound, even if it already exists, however this is absolutely not needed
{
  value: u8,
  perp: &'a T,
}

trait VictimTrait {
  type Ret;
  fn get(self) -> Self::Ret;
}

// Actual fix is here
impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
  type Ret = u8;
  fn get(self) -> Self::Ret {
    self.value
  }
}

trait Perpetrator {
  fn getter<'a>(&'a self) -> Victim<'a, Self> {
    Victim {
      value: 0,
      perp: self,
    }
  }

  fn trigger(&self) {
    self.getter().get();
  }
}

This does not compile with the following error message:

error[[E0599]](https://doc.rust-lang.org/stable/error-index.html#E0599): the method `get` exists for struct `Victim<'_, Self>`, but its trait bounds were not satisfied
  --> src/main.rs:31:19
   |
1  | / struct Victim<'a, T: Perpetrator + ?Sized>
2  | | where
3  | |   Self: Sized // rustc sugests adding this trait bound, even if it already exists
4  | | {
5  | |   value: u8,
6  | |   perp: &'a T,
7  | | }
   | | -
   | | |
   | |_method `get` not found for this
   |   doesn't satisfy `Victim<'_, Self>: VictimTrait`
...
31 |       self.getter().get();
   |                     ^^^ method cannot be called on `Victim<'_, Self>` due to unsatisfied trait bounds
   |
note: trait bound `Self: Sized` was not satisfied
  --> src/main.rs:15:10
   |
15 | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
   |          ^                            -----------     -------------
   |          |
   |          unsatisfied trait bound introduced here
help: consider restricting the type parameter to satisfy the trait bound
   |
3  |   Self: Sized, Self: Sized // rustc sugests adding this trait bound, even if it already exists
   |              +++++++++++++

For more information about this error, try `rustc --explain E0599`.

This message is misleading, instruction you to add an (possibly) already existing trait bound instead of the actual fix, which is commented out in the code

Meta

This bug currently exists both in stable 1.61.0 and nightly 1.64.0-nightly(2022-06-25 20a6f3a).

playground link
gist link

@onestacked onestacked added the C-bug Category: This is a bug. label Jun 26, 2022
@TaKO8Ki TaKO8Ki added the A-diagnostics Area: Messages for errors, warnings, and lints label Jun 26, 2022
@onestacked onestacked changed the title Rustc sugesting to add a already existing trait bound, instead of relaxing an entirely different one Rustc suggesting to add a already existing trait bound, instead of relaxing an entirely different one Jun 26, 2022
@estebank estebank added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels Jun 27, 2022
@estebank
Copy link
Contributor

estebank commented Jul 2, 2022

I got a reasonable PR to suggest the appropriate fix, but removing the improper suggestion is gonna be hard because it's too naïve and flat out incorrect in cases like these where the obligation doesn't come directly from the impl'd trait:

error[E0599]: the method `get` exists for struct `Victim<'_, Self>`, but its trait bounds were not satisfied
  --> src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.rs:31:19
   |
1  | / struct Victim<'a, T: Perpetrator + ?Sized>
2  | | where
3  | |   Self: Sized
4  | | {
5  | |   value: u8,
6  | |   perp: &'a T,
7  | | }
   | | -
   | | |
   | |_method `get` not found for this
   |   doesn't satisfy `Victim<'_, Self>: VictimTrait`
...
31 |       self.getter().get();
   |                     ^^^ method cannot be called on `Victim<'_, Self>` due to unsatisfied trait bounds
   |
note: trait bound `Self: Sized` was not satisfied
  --> src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.rs:15:10
   |
15 | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
   |          ^                            -----------     -------------
   |          |
   |          unsatisfied trait bound introduced here
help: consider relaxing the type parameter's implicit `?Sized` bound
   |
15 | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
   |             ++++++++
help: consider restricting the type parameter to satisfy the trait bound
   |
3  |   Self: Sized, Self: Sized
   |              +++++++++++++

error: aborting due to previous error

estebank added a commit to estebank/rust that referenced this issue Jul 7, 2022
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 8, 2022
Track implicit `Sized` obligations in type params

When we evaluate `ty::GenericPredicates` we introduce the implicit
`Sized` predicate of type params, but we do so with only the `Predicate`
its `Span` as context, we don't have an `Obligation` or
`ObligationCauseCode` we could influence. To try and carry this
information through, we add a new field to `ty::GenericPredicates` that
tracks both which predicates come from a type param and whether that
param has any bounds already (to use in suggestions).

We also suggest adding a `?Sized` bound if appropriate on E0599.

Address part of rust-lang#98539.
@bors bors closed this as completed in af10a45 Jul 9, 2022
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 C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants