It took me ten minutes to figure out the point in error LOL

Look at the following error

same error but in text
error[E0599]: the method `len` exists for mutable reference `&mut Scrollable<Line>`, but its trait bounds were not satisfied
  --> src/bin/ui/scrollable/interaction.rs:49:24
   |
49 |         let len = self.len();
   |                        ^^^ method cannot be called on `&mut Scrollable<Line>` due to unsatisfied trait bounds
   |
  ::: src/bin/ui/scrollable/mod.rs:12:1
   |
12 | pub struct Scrollable<Lines> {
   | ---------------------------- doesn't satisfy `Scrollable<Line>: ExactSizeIterator`
   |
note: trait bound `Line: AsRef<[TreeLine]>` was not satisfied
  --> src/bin/ui/scrollable/mod.rs:27:12
   |
27 | impl<Line: AsRef<[TreeLine]>> Scrollable<Line> {
   |            ^^^^^^^^^^^^^^^^^  ----------------
   |            |
   |            unsatisfied trait bound introduced here
   = note: the following trait bounds were not satisfied:
           `Scrollable<Line>: ExactSizeIterator`
           which is required by `&mut Scrollable<Line>: ExactSizeIterator`
note: the trait `ExactSizeIterator` must be implemented
  --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/exact_size.rs:86:1
   |
86 | pub trait ExactSizeIterator: Iterator {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

What could be wrong when you saw the colorful error msg above? Make a decision.
(Unhelpful error hints may prevent you far from the correct solution.)

  • error[E0599]: the method len exists for mutable reference &mut Scrollable<Line>, but its trait bounds were not satisfied
  • pub struct Scrollable doesn't satisfy Scrollable<Line>: ExactSizeIterator
  • note: trait bound Line: AsRef<[TreeLine]> was not satisfied
  • note: the trait ExactSizeIterator must be implemented
  • Scrollable<Line>: ExactSizeIterator which is required by &mut Scrollable<Line>: ExactSizeIterator
0 voters
Hint

Well, if you want the minimum reproducible code, here you are.
If you write it locally, rust-analyzer reports the unimportant ui::scrollable::Scrollable<Line>: std::iter::ExactSizeIterator at the call site which will be like the one I got in my project:


Hint

If you still don't know which option is the most helpful one, I won't blame you because the typo AsMut bound is never shown in there!

I'm not sure what I'm voting for. The error(s) that I think is the real problem? The error(s) that I think aren't mentioned by the compiler? What are we voting for?

I've seen these kinds of error before (I haven't read your spoilers yet). Usually there's a trait not implemented because some other trait isn't implemented for the type.

I actually raised an issue for the case where a (missing) blanket Fn impl is reported as the primary cause of the error which seems silly when it's the trait impl that the blanket impl provides which is primarily missing!

Your error seems reasonable at first glance but I'm sure I'm missing a problem with it :slight_smile:

2 Likes

Likewise with the issue you raised: the most important information for user is the lack of
direct trait bound requirements, not the indirect/heuristic ones, but rustc reports the latter more than/before the former.

For context in my OP and based on the reproducible code given in spoiler:

1  | struct Scroll<L>(L);
   | ---------------- doesn't satisfy `Scroll<L>: ExactSizeIterator`

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
  1. The most words is ExactSizeIterator, but it's never introduced in scope, so rustc overstates here.
  2. unsatisfied trait bound introduced here reads wrong for me here, because the fact is that method len is defined is under L: AsRef<[Line]> bound, but it's wrong to call len under L: AsMut<[Line]> bound. Rustc doesn't show anything about AsMut in errors, instead it shoud highlight the direct cause
   | impl<L: AsMut<[Line]>> Scroll<L> { // Not for L: AsRef<[Line]>
   |         ^^^^^^^^^^^^^  ---------
   |         |
   |         unsatisfied trait bound introduced here
  1. as a result, rust-analyzer complains lack of ExactSizeIterator bound in call/definition sites without mentioning a single word of AsMut

It's interesting, if you reduce the error to either of its components (either deleting the len method, or renaming it and the call from "len" to something that doesn't match ExactSizeIterator API) the error message is more sensible, but having both like this mixes the parts in a somewhat weird way.

I don't think it should point at the AsMut since that trait has nothing to do with the problem. It could point to the place where Line is introduced (in your case right next to the AsMut bound) and perhaps suggest bounds that could be added there.

It should also be a lot more clear that two distinct len methods were found and neither has satisfied trait bounds (then go on and clarify each of the cases).

3 Likes

Can anyone explain what the hell is happening here? I don't get the error at all.

One further complication is probably that the len method from ExactSizeIterator comes before the inherent one in method resolution order. The former has receiver type & &mut _, matching the shape of the type & &mut Scrollable<Lines>, the latter wants & Scrollable<_>, which is 3 steps further in the method resolution chain.

One could argue "why should ExactSizeIterator be relevant at all?", on the other hand

  • there is an explicit implementation of ExactSizeIterator for &mut T in the standard library. So &mut T kind-of has a len method, as long as T satisfies a particular bound (T: ExactSizeIterator)
  • the trait ExactSizeIterator is imported and in scope. It's an implicit import, since it comes from the prelude, but still...

I would guess (haven't tested it) that both factors above (trait in scope, and (conditionally) implemented for the type in question, which happens to be &mut T) are necessary for the error to even mention the trait (ExactSizeIterator) in the first place.

I'd also say that diagnostics improvements could be had in not showing the method candidates from a generic impl<T: SomeTrait> SomeTrait for &mut T (or &T or Box<T>) implementation, at least when T doesn't have any SomeTrait implementations itself.

2 Likes
struct Scroll<L>(L);

trait Bound {}

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

impl<L> Scroll<L> { // Line12
    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.
use __::ATraitSomewhere as _;  

mod __ {
    pub trait ATraitSomewhere {
        fn f(&self) {}
    }
    impl<T: B> ATraitSomewhere for &T {}
    pub trait B {}
}
current error
error[E0599]: the method `f` exists for reference `&Scroll<L>`, but its trait bounds were not satisfied
  --> src/lib.rs:15:14
   |
1  | struct Scroll<L>(L);
   | ---------------- doesn't satisfy `Scroll<L>: B`
...
15 |         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:6:9
   |
6  | impl<L: Bound> Scroll<L> {
   |         ^^^^^  ---------
   |         |
   |         unsatisfied trait bound introduced here
note: trait bound `Scroll<L>: B` was not satisfied
  --> src/lib.rs:27:13
   |
27 |     impl<T: B> ATraitSomewhere for &T {}
   |             ^  ---------------     --
   |             |
   |             unsatisfied trait bound introduced here
note: the trait `B` must be implemented
  --> src/lib.rs:28:5
   |
28 |     pub trait B {}
   |     ^^^^^^^^^^^
2 Likes

Wow had to read this like 5 times to get it. Thanks that made it very clear.
Yeah the error mixes two possible method canditates which is very confusing. Also with the error and note syntax it all seems to be grouped into one logical group.

2 Likes

Well, I would have though it were hard to find a similar issue for this.

It turns out searching by is:issue is:open label:A-diagnostics bound, the second one opened two weeks ago is exactly the target.

Thankfully, @ekuber is working on it :heart:

3 Likes

Is this the same thing as discussed in this thread?

I was actually a bit surprised myself recently to learn that AsMut is not a subtrait of AsRef the way DerefMut is a subtrait of Deref.

Before that PR:

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: 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 {}
   |     ^^^^^^^^^^^

After:

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: 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 {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^

Wouldn't say your case if handled yet. Would you mind filing a new ticket?

4 Likes

@ekuber I've opened an issue for the problem :smiley:

5 Likes