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

Avoid Invalid code suggested when encountering unsatisfied trait bounds in derive macro code #104895

Merged
merged 1 commit into from
Dec 1, 2022

Conversation

chenyukang
Copy link
Member

Fixes #104884

@rustbot
Copy link
Collaborator

rustbot commented Nov 25, 2022

r? @petrochenkov

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

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 25, 2022
@chenyukang
Copy link
Member Author

I verified the change fixed this issue with serde, but I'm struggling to construct a minimal case without serde.

Appreciate if anyone could help me on this.

@petrochenkov
Copy link
Contributor

r? rust-lang/diagnostics
Skipping suggestions for macro code is relevant for pretty much all reported diagnostics.
There's probably some centralized way to do this.

@rustbot rustbot assigned TaKO8Ki and unassigned petrochenkov Nov 26, 2022
@petrochenkov
Copy link
Contributor

I'm struggling to construct a minimal case without serde.

See src/test/ui/proc-macro for examples of using proc macros in the test suite.

@TaKO8Ki
Copy link
Member

TaKO8Ki commented Nov 28, 2022

Thank you for your contribution. I found a mcve.

Given the following code as a MCVE:

src/test/ui/proc-macro/add-trait-impl.rs

// aux-build:add-trait-impl.rs

use std::collections::BinaryHeap;

#[macro_use]
extern crate add_trait_impl;

#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct PriorityQueueEntry<T> {
    value: T,
}

#[derive(PartialOrd, AddImpl)]
struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);

fn main() {}

src/test/ui/proc-macro/auxiliary/add-trait-impl.rs

// force-host
// no-prefer-dynamic

#![crate_type = "proc-macro"]

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro_derive(AddImpl)]

pub fn derive(input: TokenStream) -> TokenStream {
    "use std::cmp::Ordering;

    impl<T> Ord for PriorityQueue<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.0.cmp(&self.height)
        }
    }
    "
    .parse()
    .unwrap()
}

Current output is:

error[E0277]: can't compare `PriorityQueue<T>` with `PriorityQueue<T>`
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:10
   |
LL | #[derive(PartialOrd, AddImpl)]
   |          ^^^^^^^^^^ no implementation for `PriorityQueue<T> == PriorityQueue<T>`
   |
   = help: the trait `PartialEq` is not implemented for `PriorityQueue<T>`
note: required by a bound in `PartialOrd`
  --> /Users/maeda.takayuki/GitHub/rust/rust/library/core/src/cmp.rs:1083:43
   |
LL | pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
   |                                           ^^^^^^^^^^^^^^ required by this bound in `PartialOrd`
   = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `PriorityQueue<T>: Eq` is not satisfied
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:22
   |
LL | #[derive(PartialOrd, AddImpl)]
   |                      ^^^^^^^ the trait `Eq` is not implemented for `PriorityQueue<T>`
   |
note: required by a bound in `Ord`
  --> /Users/maeda.takayuki/GitHub/rust/rust/library/core/src/cmp.rs:765:16
   |
LL | pub trait Ord: Eq + PartialOrd<Self> {
   |                ^^ required by this bound in `Ord`
   = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: can't compare `T` with `T`
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:22
   |
LL | #[derive(PartialOrd, AddImpl)]
   |                      ^^^^^^^ no implementation for `T < T` and `T > T`
   |
note: required for `PriorityQueue<T>` to implement `PartialOrd`
  --> /Users/maeda.takayuki/GitHub/rust/rust/src/test/ui/proc-macro/add-trait-impl.rs:13:10
   |
LL | #[derive(PartialOrd, AddImpl)]
   |          ^^^^^^^^^^
note: required by a bound in `Ord`
  --> /Users/maeda.takayuki/GitHub/rust/rust/library/core/src/cmp.rs:765:21
   |
LL | pub trait Ord: Eq + PartialOrd<Self> {
   |                     ^^^^^^^^^^^^^^^^ required by this bound in `Ord`
   = note: this error originates in the derive macro `AddImpl` which comes from the expansion of the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
   |
LL | #[derive(PartialOrd, AddImpl: std::cmp::PartialOrd)]
   |                             ++++++++++++++++++++++

error: aborting due to 3 previous errors

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

The suggestion is a little bit different from what the issue says, but it might help you.

@chenyukang
Copy link
Member Author

Thanks very much! @TaKO8Ki
This code could be MCVE for the issue, seems serde does something different,
but the wrong suggestion comes with the same codepath, and this PR fixes it.
I will add it as unit testcase.

@TaKO8Ki TaKO8Ki 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 Nov 28, 2022
@chenyukang chenyukang force-pushed the yukang/fix-104884-serde branch from dc1e083 to 7d2346e Compare November 28, 2022 12:23
…unsatisfied trait bounds in derive macro code
@TaKO8Ki
Copy link
Member

TaKO8Ki commented Nov 30, 2022

After reviewing your code, I thought that rustc should suggest like the following in this case. What do you think about? That is because skipping suggestions for macro code is just a quick fix.

Given the following code:

use std::collections::BinaryHeap;

#[derive(PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
struct PriorityQueueEntry<T> {
    value: T,
}

#[derive(serde::Serialize)]
struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);

Rustc should suggest like:

error[E0277]: the trait bound `T: Ord` is not satisfied
   --> src/main.rs:8:10
    |
8   | #[derive(serde::Serialize)]
    |          ^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `T`
9   | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);
    |                         --------------------------------- required by a bound introduced by this call
    |
note: required for `PriorityQueueEntry<T>` to implement `Ord`
   --> src/main.rs:3:37
    |
3   | #[derive(PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
    |                                     ^^^
    = note: required for `BinaryHeap<PriorityQueueEntry<T>>` to implement `Serialize`
note: required by a bound in `serialize_newtype_struct`
   --> /Users/maeda.takayuki/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.148/src/ser/mod.rs:904:12
    |
904 |         T: Serialize;
    |            ^^^^^^^^^ required by this bound in `serialize_newtype_struct`
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
- help: consider further restricting type parameter `T`
-     |
- 8   | #[derive(serde::Serialize, T: std::cmp::Ord)]
-     |                          ++++++++++++++++++
+ help: consider restricting type parameter `T`
+   |
+ 9 | struct PriorityQueue<T: std::cmp::Ord>(BinaryHeap<PriorityQueueEntry<T>>);
+   |                       +++++++++++++++

@chenyukang
Copy link
Member Author

Yes, you're right!
seems the span for suggestion is wrong.
Let me think how to fix it.

@chenyukang
Copy link
Member Author

@TaKO8Ki I'm still learning this part of code,
if you already have a fix please create a new PR, I will close this one😊

@chenyukang
Copy link
Member Author

I guess bounds_span_for_suggestions does not handle well for derive scenario.

@chenyukang chenyukang force-pushed the yukang/fix-104884-serde branch from 7d2346e to 3980945 Compare November 30, 2022 05:51
@TaKO8Ki
Copy link
Member

TaKO8Ki commented Nov 30, 2022

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Nov 30, 2022

📌 Commit 3980945 has been approved by TaKO8Ki

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 30, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Nov 30, 2022
…, r=TaKO8Ki

Avoid Invalid code suggested when encountering unsatisfied trait bounds in derive macro code

Fixes rust-lang#104884
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 1, 2022
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#103065 (rustdoc-json: Document and Test that args can be patterns.)
 - rust-lang#104865 (Don't overwrite local changes when updating submodules)
 - rust-lang#104895 (Avoid Invalid code suggested when encountering unsatisfied trait bounds in derive macro code)
 - rust-lang#105063 (Rustdoc Json Tests: Don't assume that core::fmt::Debug will always have one item.)
 - rust-lang#105064 (rustdoc: add comment to confusing CSS `main { min-width: 0 }`)
 - rust-lang#105074 (Add Nicholas Bishop to `.mailmap`)
 - rust-lang#105081 (Add a regression test for rust-lang#104322)
 - rust-lang#105086 (rustdoc: clean up sidebar link CSS)
 - rust-lang#105091 (add Tshepang Mbambo to .mailmap)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit eabc072 into rust-lang:master Dec 1, 2022
@rustbot rustbot added this to the 1.67.0 milestone Dec 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid code suggested when encountering unsatisfied trait bounds in derive macro code
5 participants