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

Add better error message when == operator is badly used #41559

Merged
merged 1 commit into from
May 23, 2017

Conversation

GuillaumeGomez
Copy link
Member

@GuillaumeGomez GuillaumeGomez commented Apr 26, 2017

Part of #40660.

With the following code:

fn foo<T: PartialEq>(a: &T, b: T) {
    a == b;
}

fn main() {
    foo(&1, 1);
}

It prints:

error[E0277]: the trait bound `&T: std::cmp::PartialEq<T>` is not satisfied
 --> test.rs:2:5
  |
2 |     a == b;
  |     ^^^^^^ can't compare `&T` with `T`
  |
  = help: the trait `std::cmp::PartialEq<T>` is not implemented for `&T`
  = help: consider adding a `where &T: std::cmp::PartialEq<T>` bound

error: aborting due to previous error

@rust-highfive
Copy link
Collaborator

r? @pnkfelix

(rust_highfive has picked a reviewer for you, use r? to override)

@estebank
Copy link
Contributor

@GuillaumeGomez you need to update the output of src/test/ui/mismatched_types/binops.stderr.

@GuillaumeGomez
Copy link
Member Author

Ah thanks!

@GuillaumeGomez
Copy link
Member Author

The output looks way nicer this way. :D (Updated.)

@alexcrichton alexcrichton added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 27, 2017
@@ -559,6 +559,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trait_ref.to_predicate(),
post_message);

let trait_display = format!("{}", trait_ref);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just let trait_display = trait_ref.to_string();

@GuillaumeGomez
Copy link
Member Author

Updated.

@kennytm
Copy link
Member

kennytm commented May 1, 2017

I thought a better error message should suggest a == &b or *a == b, not adding a where clause? 😳

@GuillaumeGomez
Copy link
Member Author

Well, I didn't add the where clause, it was already there.

@kennytm
Copy link
Member

kennytm commented May 1, 2017

@GuillaumeGomez Ah I see.

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some of @arielb1's comments in #40565 apply to this review too. I'm all for more explicit diagnostic output, but I came around to thinking that using #[rustc_on_unimplemented] for this is enough (at least for now).

@@ -559,6 +559,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trait_ref.to_predicate(),
post_message);

let trait_display = trait_ref.to_string();
if trait_display.starts_with("std::cmp::PartialEq") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work with no_std (as pointed out before to me).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good point!

|
= help: the trait `std::cmp::PartialEq<std::string::String>` is not implemented for `{integer}`
= note: can't compare `{integer}` with `std::string::String`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The label and a note have the same text.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They don't?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

screen shot 2017-05-02 at 11 18 24 pm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, didn't look more below. :-/

|
= help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
= note: can't compare `{integer}` with `std::result::Result<{integer}, _>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

@GuillaumeGomez
Copy link
Member Author

Updated.

@Mark-Simulacrum
Copy link
Member

Label and note seem to have the same text still? @GuillaumeGomez Was that intentional?

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 7, 2017
@GuillaumeGomez
Copy link
Member Author

No, I need to fix this.

@GuillaumeGomez
Copy link
Member Author

Updated.

@carols10cents carols10cents added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 8, 2017
@bors
Copy link
Contributor

bors commented May 8, 2017

☔ The latest upstream changes (presumably #41745) made this pull request unmergeable. Please resolve the merge conflicts.

@arielb1
Copy link
Contributor

arielb1 commented May 9, 2017

@GuillaumeGomez

Any particular reason this isn't a rustc_on_unimplemented note? I think we should make rustc_on_unimplemented be the label (instead of the redundant "the trait X is not implemented for Y").

@GuillaumeGomez
Copy link
Member Author

@arielb1: I thought about it. So as you prefer.

@alexcrichton
Copy link
Member

I think @pnkfelix is on PTO right now, @estebank would you be willing to review?

@estebank
Copy link
Contributor

@alexcrichton the difference in output at the moment is swapping the note and the label, but I have the same hangup as @arielb1 as I would rather avoid checking paths by string. That being said, @GuillaumeGomez I'd be down with setting rustc_on_unimplemented text as label always and the existing label as a note or, as I half jokingly proposed, expanding rustc_on_unimplemented to have a way to set wether the text should be rendered as a note or a label.

@GuillaumeGomez
Copy link
Member Author

Ok so we definitely agree on this:

If rustc_on_unimplemented is available, it'll be the label.

@GuillaumeGomez
Copy link
Member Author

Ok, updated. Let's see what the CI says.

trait_ref.self_ty()));
} else {
err.span_label(span,
&*format!("{}the trait `{}` is not implemented for `{}`",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is &* necessary here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'm surprised about it but it seems that it fails otherwise because of the From<&str> not matching and auto-dereferencing a String.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be able to use the format!() directly since #41745

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's since my last rebase that I can't, so not sure...

@estebank
Copy link
Contributor

@GuillaumeGomez the failing files are:

  • compile-fail/E0277-2.rs
  • compile-fail/E0277.rs
  • compile-fail/const-unsized.rs
  • compile-fail/impl-trait/auto-trait-leak.rs
  • compile-fail/on-unimplemented/multiple-impls.rs
  • compile-fail/on-unimplemented/on-impl.rs
  • compile-fail/on-unimplemented/on-trait.rs
  • compile-fail/on-unimplemented/slice-index.rs
  • compile-fail/trait-suggest-where-clause.rs

@GuillaumeGomez
Copy link
Member Author

@estebank: Ah great, thanks for the list! :)

@GuillaumeGomez
Copy link
Member Author

Updated.

|
= note: no implementation for `{integer} + std::option::Option<{integer}>`
= help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not prevent the merge of this PR, but reading this file I feel the full output of this error should be:

error[E0277]: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
  --> $DIR/binops.rs:12:5
   |
12 |     1 + Some(1);
   |     ^^^^^^^^^^^ no implementation for `{integer} + std::option::Option<{integer}>`

instead of

error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{integer}>>` is not satisfied
  --> $DIR/binops.rs:12:5
   |
12 |     1 + Some(1);
   |     ^^^^^^^^^^^ no implementation for `{integer} + std::option::Option<{integer}>`
   |
   = help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`

Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate having both in case the user isn't well aware of the Add and equivalent traits.

@carols10cents
Copy link
Member

What's the current state of this PR please @GuillaumeGomez @estebank? I'm having trouble following :)

@estebank
Copy link
Contributor

@carols10cents thanks for the ping

@GuillaumeGomez can you post the visual diff of one of the modified cfail tests, like this one against the current nightly? I want to make sure that we're not removing information. If the new output looks fine for that, I'll r+.

@GuillaumeGomez
Copy link
Member Author

Sure. Here it is:

> ./build/x86_64-apple-darwin/stage1/bin/rustc src/test/compile-fail/on-unimplemented/slice-index.rs
error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied
  --> src/test/compile-fail/on-unimplemented/slice-index.rs:21:5
   |
21 |     x[1i32]; //~ ERROR E0277
   |     ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
   |
   = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
   = note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[i32]`

error[E0277]: the trait bound `std::ops::RangeTo<i32>: std::slice::SliceIndex<[i32]>` is not satisfied
  --> src/test/compile-fail/on-unimplemented/slice-index.rs:24:5
   |
24 |     x[..1i32]; //~ ERROR E0277
   |     ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
   |
   = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
   = note: required because of the requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>` for `[i32]`

error: aborting due to 2 previous errors

And the old one:

> rustc --version
> rustc 1.19.0-nightly (14f30da61 2017-05-21)
imperio@/Users/imperio/rust/rust > rustc src/test/compile-fail/on-unimplemented/slice-index.rs
error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied
  --> src/test/compile-fail/on-unimplemented/slice-index.rs:21:5
   |
21 |     x[1i32]; //~ ERROR E0277
   |     ^^^^^^^ the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
   |
   = note: slice indices are of type `usize` or ranges of `usize`
   = note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[i32]`

error[E0277]: the trait bound `std::ops::RangeTo<i32>: std::slice::SliceIndex<[i32]>` is not satisfied
  --> src/test/compile-fail/on-unimplemented/slice-index.rs:24:5
   |
24 |     x[..1i32]; //~ ERROR E0277
   |     ^^^^^^^^^ the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
   |
   = note: slice indices are of type `usize` or ranges of `usize`
   = note: required because of the requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>` for `[i32]`

error: aborting due to 2 previous errors

@estebank
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented May 23, 2017

📌 Commit 747287a has been approved by estebank

@bors
Copy link
Contributor

bors commented May 23, 2017

⌛ Testing commit 747287a with merge 2e91391...

bors added a commit that referenced this pull request May 23, 2017
Add better error message when == operator is badly used

Part of #40660.

With the following code:

```rust
fn foo<T: PartialEq>(a: &T, b: T) {
    a == b;
}

fn main() {
    foo(&1, 1);
}
```

It prints:

```
error[E0277]: the trait bound `&T: std::cmp::PartialEq<T>` is not satisfied
 --> test.rs:2:5
  |
2 |     a == b;
  |     ^^^^^^ can't compare `&T` with `T`
  |
  = help: the trait `std::cmp::PartialEq<T>` is not implemented for `&T`
  = help: consider adding a `where &T: std::cmp::PartialEq<T>` bound

error: aborting due to previous error
```
@bors
Copy link
Contributor

bors commented May 23, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: estebank
Pushing 2e91391 to master...

@bors bors merged commit 747287a into rust-lang:master May 23, 2017
@GuillaumeGomez GuillaumeGomez deleted the partial-eq-msg branch May 23, 2017 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.