Skip to content

rustc should first suggest adding a trait bound on generic impl block when inherent method name bound by that trait collides with methods from unintended traits in scope #120568

Open
@zjp-CN

Description

Code

pub struct Scroll<L>(L);

pub trait Bound {}

impl<L: Bound> Scroll<L> {
    // happens to be the same name with methods in ATraitSomewhere
    pub fn f(&self) -> usize {
        0
    }
}

impl<L> Scroll<L> { // Line12
    pub fn call(&self) {
        self.f(); // meant to call an inherent method
    }
}

// Say an accidental trait is brought into scope via asterisk wildcard
// import syntax or std's prelude or somthing, bad error occurs with
// the following code beacuse it doesn't give the obvious fix by
// patching `L: Bound` on Line12 at all.
#[allow(unused_imports)] use __::ATraitSomewhere;

mod __ {
    pub trait ATraitSomewhere {
        fn f(&self) {}
    }
    impl<T: B> ATraitSomewhere for &T {}
    pub trait B {}
}

Current output

error[E0599]: the method `f` exists for reference `&Scroll<L>`, but its trait bounds were not satisfied
  --> src/lib.rs:14:14
   |
1  | pub struct Scroll<L>(L);
   | -------------------- doesn't satisfy `Scroll<L>: B`
...
14 |         self.f(); // meant to call an inherent method
   |              ^ method cannot be called on `&Scroll<L>` due to unsatisfied trait bounds
   |
note: trait bound `L: Bound` was not satisfied
  --> src/lib.rs:5:9
   |
5  | impl<L: Bound> Scroll<L> {
   |         ^^^^^  ---------
   |         |
   |         unsatisfied trait bound introduced here
note: trait bound `Scroll<L>: B` was not satisfied
  --> src/lib.rs:29:13
   |
29 |     impl<T: B> ATraitSomewhere for &T {}
   |             ^  ---------------     --
   |             |
   |             unsatisfied trait bound introduced here
note: the trait `B` must be implemented
  --> src/lib.rs:30:5
   |
30 |     pub trait B {}
   |     ^^^^^^^^^^^

Desired output

error[E0599]: the method `f` exists for reference `&Scroll<L>`, but its trait bounds were not satisfied
  --> f100.rs:14:14
   |
1  | struct Scroll<L>(L);
   | ---------------- doesn't satisfy `Scroll<L>: B`
...
14 |         self.f(); // meant to call an inherent method
   |              ^ method cannot be called on `&Scroll<L>` due to unsatisfied trait bounds

   |
note: trait bound `L: Bound` was not satisfied
  --> f100.rs:5:9
   |
5  | impl<L: Bound> Scroll<L> {
   |         ^^^^^  ---------
   |         |
   |         unsatisfied trait bound introduced here
note: the method `f` can be called with trait bound `L: Bound` satisfied
  --> f100.rs:12:6
   |
12 |     impl<L> Scroll<L> { // Line12
   |          ^  ---------
   |          |
   |          = help: consider adding `: Bound`
note: trait bound `Scroll<L>: B` was not satisfied
  --> f100.rs:29:13
   |
29 |     impl<T: B> ATraitSomewhere for &T {}
   |             ^  ---------------     --
   |             |
   |             unsatisfied trait bound introduced here
note: the trait `B` must be implemented
  --> f100.rs:30:5
   |
30 |     pub trait B {}
   |     ^^^^^^^^^^^
   = help: items from traits can only be used if the trait is implemented and in scope
note: `ATraitSomewhere` defines an item `f`, perhaps you need to implement it
  --> f100.rs:26:5
   |
26 |     pub trait ATraitSomewhere {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^

Rationale and extra context

The code closer to what I met is the following as I posted in URLO

struct Scroll<L>(L);
struct Line;

impl<L: AsRef<[Line]>> Scroll<L> {
    fn len(&self) -> usize { self.0.as_ref().len() }
}

impl<L: AsMut<[Line]>> Scroll<L> {
    fn f1(&mut self) { self.len(); }
}
// current error
error[E0599]: the method `len` exists for mutable reference `&mut Scroll<L>`, but its trait bounds were not satisfied
  --> src/lib.rs:9:29
   |
1  | struct Scroll<L>(L);
   | ---------------- doesn't satisfy `Scroll<L>: ExactSizeIterator`
...
9  |     fn f1(&mut self) { self.len(); }
   |                             ^^^ method cannot be called on `&mut Scroll<L>` due to unsatisfied trait bounds
   |
note: trait bound `L: AsRef<[Line]>` was not satisfied
  --> src/lib.rs:4:9
   |
4  | impl<L: AsRef<[Line]>> Scroll<L> {
   |         ^^^^^^^^^^^^^  ---------
   |         |
   |         unsatisfied trait bound introduced here
   = note: the following trait bounds were not satisfied:
           `Scroll<L>: ExactSizeIterator`
           which is required by `&mut Scroll<L>: ExactSizeIterator`
note: the trait `ExactSizeIterator` must be implemented
  --> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/exact_size.rs:86:1
   |
86 | pub trait ExactSizeIterator: Iterator {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Rustc doesn't report the obvious fix by add L: AsRef<[Line]> bound on the call site block,
so it'd be great if we have it

note: trait bound `L: AsRef<[Line]>` was not satisfied
  --> src/lib.rs:4:9
   |
4  | impl<L: AsRef<[Line]>> Scroll<L> {
   |         ^^^^^^^^^^^^^  ---------
   |         |
   |         unsatisfied trait bound introduced here
+note: the method `len` can be called with trait bound `L: AsRef<[Line]>` satisfied
+8  | impl<L: AsMut<[Line]>> Scroll<L> {
+   |      ^
+   |      |
+   |      help: consider adding `L: AsRef<[Line]>`
+   |
note: the following trait bounds were not satisfied:
      `Scroll<L>: ExactSizeIterator`
      which is required by `&mut Scroll<L>: ExactSizeIterator`

Other cases

No response

Rust Version

rustc 1.75.0 (82e1608df 2023-12-21)
binary: rustc
commit-hash: 82e1608dfa6e0b5569232559e3d385fea5a93112
commit-date: 2023-12-21
host: x86_64-unknown-linux-gnu
release: 1.75.0
LLVM version: 17.0.6

Anything else?

Some similar issues but the lack of trait bounds happens on functions, not on generic impl blocks.

So I think this issue would be a different case.

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions