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 error report suggests uncompilable #[derive(PartialEq.into())] #123132

Open
sgtatham opened this issue Mar 27, 2024 · 2 comments
Open

rustc error report suggests uncompilable #[derive(PartialEq.into())] #123132

sgtatham opened this issue Mar 27, 2024 · 2 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-confusing Diagnostics: Confusing error or lint that should be reworked. 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

@sgtatham
Copy link

Code

pub enum WeirdOption<T> {
    None,
    Some(T),
}

impl<T: PartialEq> PartialEq for WeirdOption<T> {
    fn eq(&self, _other: &Self) -> bool {
        todo!()
    }
}

impl<T: PartialEq<U>, U> PartialEq<WeirdOption<T>> for Option<U> {
    fn eq(&self, _other: &WeirdOption<T>) -> bool {
        todo!()
    }
}

impl<T> From<T> for WeirdOption<T> {
    fn from(_val: T) -> WeirdOption<T> {
        todo!()
    }
}

struct Foo;

#[derive(PartialEq)]
struct Bar {
    foo: Option<Foo>,
}

fn main() {
    println!("Hello, world!");
}

Current output

Compiling rustc-nonsense2 v0.1.0 (/r)
error[E0308]: mismatched types
  --> src/main.rs:28:5
   |
26 | #[derive(PartialEq)]
   |          --------- in this derive macro expansion
27 | struct Bar {
28 |     foo: Option<Foo>,
   |     ^^^^^^^^^^^^^^^^ expected `WeirdOption<_>`, found `Option<Foo>`
   |
   = note: expected enum `WeirdOption<_>`
              found enum `Option<Foo>`
   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: call `Into::into` on this expression to convert `Option<Foo>` into `WeirdOption<_>`
   |
26 | #[derive(PartialEq.into())]
   |                   +++++++

For more information about this error, try `rustc --explain E0308`.
error: could not compile `rustc-nonsense2` (bin "rustc-nonsense2") due to 1 previous error

Desired output

Compiling rustc-nonsense2 v0.1.0 (/r)
error[E0369]: binary operation `==` cannot be applied to type `Option<Foo>`
  --> src/main.rs:28:5
   |
26 | #[derive(PartialEq)]
   |          --------- in this derive macro expansion
27 | struct Bar {
28 |     foo: Option<Foo>,
   |     ^^^^^^^^^^^^^^^^
   |
note: an implementation of `PartialEq` might be missing for `Foo`
  --> src/main.rs:24:1
   |
24 | struct Foo;
   | ^^^^^^^^^^ must implement `PartialEq`
   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Foo` with `#[derive(PartialEq)]`
   |
24 + #[derive(PartialEq)]
25 | struct Foo;
   |

For more information about this error, try `rustc --explain E0369`.
error: could not compile `rustc-nonsense2` (bin "rustc-nonsense2") due to 1 previous error

Rationale and extra context

The compile failure is legitimate: I've tried to derive PartialEq for Bar, but Foo is not PartialEq in turn, and therefore, neither is Option<Foo>.

But the existence of WeirdOption in the compilation, even though nothing refers to it, has caused rustc to get so confused that it suggests I write #[derive(PartialEq.into())], which is not even syntactically legal, and as far as I can see, wouldn't mean anything comprehensible if it were.

If WeirdOption and all its impls are commented out, then I get a much more sensible error message, telling me that Foo needs to implement PartialEq, and suggesting that I try doing this with a derive. That's the text that I've pasted into "Desired output" as a suggestion of better output in this case.

(This is a cut-down test case from application code; WeirdOption was originally rkyv::ArchivedOption, which was a transitive dependency that I hadn't even known was in my compile at all until seeing this error message.)

I looked for existing issues along these lines; the closest I found was #122919, about a similarly spurious ref in a suggestion. But that one is fixed as of 2024-03-22, and this still fails in 2024-03-26, so I don't think they're the same issue.

Other cases

No response

Rust Version

$ rustc --version --verbose
rustc 1.79.0-nightly (47ecded35 2024-03-26)
binary: rustc
commit-hash: 47ecded3525392b77843534bed69b4302f9af8d2
commit-date: 2024-03-26
host: x86_64-unknown-linux-gnu
release: 1.79.0-nightly
LLVM version: 18.1.2

Anything else?

No response

@sgtatham sgtatham 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 Mar 27, 2024
@jieyouxu jieyouxu added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels Mar 27, 2024
@GrigorenkoPV
Copy link
Contributor

This is actually a regression in nightly-2023-08-04 (8131b97...474709a).

Prior to it, the output looked like this:

error[E0308]: mismatched types
  --> src/lib.rs:28:5
   |
26 | #[derive(PartialEq)]
   |          --------- in this derive macro expansion
27 | struct Bar {
28 |     foo: Option<Foo>,
   |     ^^^^^^^^^^^^^^^^ expected `WeirdOption<_>`, found `Option<Foo>`
   |
   = note: expected enum `WeirdOption<_>`
              found enum `Option<Foo>`
   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: try wrapping the expression in `WeirdOption::Some`
   |
28 |     WeirdOption::Some(foo: Option<Foo>),
   |     ++++++++++++++++++                +

My blind guess would be either #107254 or #112043.

@sgtatham
Copy link
Author

Isn't that an equally invalid suggestion? You can't wrap a struct field declaration in WeirdOption::Some!

I also saw the original error, with the suggestion of PartialEq.into(), from 1.75. I reported it against nightly here because I had to check whether it had already been fixed.

@jieyouxu jieyouxu added the D-confusing Diagnostics: Confusing error or lint that should be reworked. label Aug 5, 2024
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 A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-confusing Diagnostics: Confusing error or lint that should be reworked. 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