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

E0277 focuses on the wrong part of the line. #100560

Closed
Lokathor opened this issue Aug 15, 2022 · 7 comments · Fixed by #100654
Closed

E0277 focuses on the wrong part of the line. #100560

Lokathor opened this issue Aug 15, 2022 · 7 comments · Fixed by #100654
Assignees
Labels
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.

Comments

@Lokathor
Copy link
Contributor

Lokathor commented Aug 15, 2022

So i've got some code like this:

#[derive(Debug, Clone, Default, PartialEq, Eq)]
struct ProgramAttr(Vec<DmgToken>);
impl ProgramAttr {
  fn parser() -> impl Parser<DmgToken, ProgramAttr, Error = Simple<DmgToken>> {
    just(Punctuation('#')).ignore_then(just(Punctuation('!'))).ignore_then(
      filter(|t: &DmgToken| *t != Punctuation(']'))
        .repeated()
        .collect::<Vec<_>>()
        .delimited_by(Punctuation('['), Punctuation(']'))
        .map(ProgramAttr),
    )
  }
}

What is wrong: The delimited_by takes a parser for what occurs immediately before and immediately after the parser you call the method on. So it has a : Parser<I, O> trait bound. Except that Punctuation('[') is a token, not a parser for a token. What I should have written is just(Punctuation('[')).

What Rustc Tells You:

D:\dev\dmgrs>cargo build
   Compiling dmgrs v0.1.0 (D:\dev\dmgrs)
error[E0277]: the trait bound `DmgToken: Parser<DmgToken, _>` is not satisfied
   --> src\parser.rs:19:10
    |
19  |         .delimited_by(Punctuation('['), Punctuation(']'))
    |          ^^^^^^^^^^^^ the trait `Parser<DmgToken, _>` is not implemented for `DmgToken`
    |
    = help: the following other types implement trait `Parser<I, O>`:
              <&'a T as Parser<I, O>>
              <Arc<T> as Parser<I, O>>
              <Box<T> as Parser<I, O>>
              <BoxedParser<'a, I, O, E> as Parser<I, O>>
              <Choice<(A_, B_, C_, D_, E_, F_, G_, H_, I_, J_, K_, L_, M_, N_, O_, P_, Q_, S_, T_, U_, V_, W_, X_, Y_, Z_), E> as Parser<I, O>>
              <Choice<(B_, C_, D_, E_, F_, G_, H_, I_, J_, K_, L_, M_, N_, O_, P_, Q_, S_, T_, U_, V_, W_, X_, Y_, Z_), E> as Parser<I, O>>
              <Choice<(C_, D_, E_, F_, G_, H_, I_, J_, K_, L_, M_, N_, O_, P_, Q_, S_, T_, U_, V_, W_, X_, Y_, Z_), E> as Parser<I, O>>
              <Choice<(D_, E_, F_, G_, H_, I_, J_, K_, L_, M_, N_, O_, P_, Q_, S_, T_, U_, V_, W_, X_, Y_, Z_), E> as Parser<I, O>>
            and 60 others
note: required by a bound in `delimited_by`
   --> C:\Users\Daniel\.cargo\git\checkouts\chumsky-651fb76526ac39e3\a0a67e4\src\lib.rs:871:12
    |
871 |         L: Parser<I, U, Error = Self::Error>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `delimited_by`

The Problem: The part that's "wrong" in the line is the argument, not the method call. The way the error describes things, it makes it sound like the method doesn't exist because the thing i'm calling it on doesn't satisfy some trait bound or something like that. Which, if this were nearly any other language, would sound like a silly thing to worry about, but with rust that's a genuine concern.

How I Think Rustc Should Show The Error:
Instead of focusing on delimited_by as having the error, it should focus on the argument to delimited_by as having the error.

error[E0277]: the trait bound `DmgToken: Parser<DmgToken, _>` is not satisfied
   --> src\parser.rs:19:10
    |
19  |         .delimited_by(Punctuation('['), Punctuation(']'))
    |                       ^^^^^^^^^^^^^^^^ the trait `Parser<DmgToken, _>` is not implemented for `DmgToken`
    |

@Lokathor Lokathor 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 Aug 15, 2022
@compiler-errors
Copy link
Member

Can you minimize this or provide a few more signatures for all the methods being called here?

@compiler-errors
Copy link
Member

compiler-errors commented Aug 15, 2022

oh, lol, it's chumsky. good to have known that -- didn't see the file path in your error output.

so the root cause here is that both arguments in delimited_by are type DmgToken, so right now the compiler doesn't know which one to point to, so it points to the method call instead... but i think i actually have an idea

@Lokathor
Copy link
Contributor Author

Oh, right, my bad. It's the Parser::delimited_by method in this case:

fn delimited_by<U, V, L, R>(
    self,
    start: L,
    end: R
) -> DelimitedBy<Self, L, R, U, V>
where
    Self: Sized,
    L: Parser<I, U, Error = Self::Error>,
    R: Parser<I, V, Error = Self::Error>, 

So the L generic has the trait bound, which isn't being satisfied, and then it's highlighting the method as being the error point rather than the argument to the method as being the problem.

I'm not entirely sure how to make the example more minimal though...

@Lokathor
Copy link
Contributor Author

oh you even already know the name of the lib >_> i hope they're not the source of a lot of error message reports

@compiler-errors
Copy link
Member

oh you even already know the name of the lib

haha no i just saw in the file path of the error you pasted, and i recognized the name

I'm not entirely sure how to make the example more minimal though...

no worries, i think i understand the root cause. let me "minimize it".

@rustbot claim

@compiler-errors
Copy link
Member

Minimized:

trait Bar {}

fn foo<T: Bar>(t: T, s: String) {}

fn bar<T: Bar>(t: T, u: u32) {}

fn main() {
    foo(String::new(), String::new());
 // ^^^ for foo, the error is placed here
    
    // compare to bar
    bar(String::new(), 1u32);
    //  ^^^^^^^^^^^ where the error is pointing out the correct arg
}
error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `String: Bar` is not satisfied
 --> src/main.rs:8:5
  |
8 |     foo(String::new(), String::new());
  |     ^^^ the trait `Bar` is not implemented for `String`
  |
note: required by a bound in `foo`
 --> src/main.rs:3:11
  |
3 | fn foo<T: Bar>(t: T, s: String) {}
  |           ^^^ required by this bound in `foo`

error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `String: Bar` is not satisfied
  --> src/main.rs:11:9
   |
11 |     bar(String::new(), 1u32);
   |     --- ^^^^^^^^^^^^^ the trait `Bar` is not implemented for `String`
   |     |
   |     required by a bound introduced by this call
   |
note: required by a bound in `bar`
  --> src/main.rs:5:11
   |
5  | fn bar<T: Bar>(t: T, u: u32) {}
   |           ^^^ required by this bound in `bar`

@compiler-errors
Copy link
Member

I've now gotten it to point at the arg even if there's a duplicate argument in the signature:

error[E0277]: the trait bound `String: Bar` is not satisfied
 --> /home/gh-compiler-errors/test.rs:6:9
  |
6 |     foo(String::new(), String::new());
  |         ^^^^^^^^^^^^^ the trait `Bar` is not implemented for `String`
  |
note: required by a bound in `foo`
 --> /home/gh-compiler-errors/test.rs:3:11
  |
3 | fn foo<T: Bar>(t: T, s: String) {}
  |           ^^^ required by this bound in `foo`

Now to deal with all the other fall-out of these changes...

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

2 participants