Skip to content

where clause for tuple structs recommended at wrong place causing syntax errors #91520

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
coderedart opened this issue Dec 4, 2021 · 3 comments · Fixed by #138782
Closed
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@coderedart
Copy link

coderedart commented Dec 4, 2021

Me Newbie. I had this issue while trying to create a new type to abstract over a HashMap, went to rust discord where i got the fix. then, as i got the suggestion as a quickfix from vscode, i thought it was a Rust analyzer bug, rust-lang/rust-analyzer#10923 . but this is a rust bug it seems.

Reproduce error:

  1. add derive_more and halfbrown as dependencies. //hashbrown will probably work too
  2. create a tuple struct with halfbrown::HashMap as its only field. UOMap<K,V>(halfbrown::HashMap<K,V>)
  3. derive IntoIterator using derive_more with the #[derive(IntoIterator)] and vscode gives this error.
    into

cargo check output:

error[E0277]: the trait bound `halfbrown::HashMap<K, V>: IntoIterator` is not satisfied
   --> src/main.rs:7:10
    |
7   | #[derive(IntoIterator)]
    |          ^^^^^^^^^^^^ the trait `IntoIterator` is not implemented for `halfbrown::HashMap<K, V>`
    |
note: required by a bound in `IntoIterator`
   --> /home/red/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:204:1
    |
204 | / pub trait IntoIterator {
205 | |     /// The type of the elements being iterated over.
206 | |     #[stable(feature = "rust1", since = "1.0.0")]
207 | |     type Item;
...   |
234 | |     fn into_iter(self) -> Self::IntoIter;
235 | | }
    | |_^ required by this bound in `IntoIterator`
    = note: this error originates in the derive macro `IntoIterator` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
    |
8   | pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: IntoIterator(HashMap<K, V>);
    |                                        ++++++++++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `halfbrown::HashMap<K, V>: IntoIterator` is not satisfied
 --> src/main.rs:7:10
  |
7 | #[derive(IntoIterator)]
  |          ^^^^^^^^^^^^ the trait `IntoIterator` is not implemented for `halfbrown::HashMap<K, V>`
  |
  = note: this error originates in the derive macro `IntoIterator` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
8 | pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: IntoIterator(HashMap<K, V>);
  |                                        ++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.
  1. the suggestion 8 | pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: IntoIterator(HashMap<K, V>); with where clause between the struct name and the parenthesis which declare the fields, is wrong and introduces a whole new class of errors
    after
    cargo output:
error: proc-macro derive panicked
 --> src/main.rs:7:10
  |
7 | #[derive(IntoIterator)]
  |          ^^^^^^^^^^^^
  |
  = help: message: derive(IntoIterator) only works when forwarding to a single field. Try putting #[into_iterator] or #[into_iterator(ignore)] on the fields in the struct

error[E0658]: parenthetical notation is only stable when used with `Fn`-family traits
 --> src/main.rs:8:72
  |
8 | pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: std::iter::IntoIterator(HashMap<K, V>);
  |                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information

error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
   --> src/main.rs:8:83
    |
8   | pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: std::iter::IntoIterator(HashMap<K, V>);
    |                                                                                   ^^^^^^^^^^^^--------------- help: remove these parenthetical generics
    |                                                                                   |
    |                                                                                   expected 0 generic arguments
    |
note: trait defined here, with 0 generic parameters
   --> /home/red/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:204:11
    |
204 | pub trait IntoIterator {
    |           ^^^^^^^^^^^^

error[E0220]: associated type `Output` not found for `IntoIterator`
 --> src/main.rs:8:83
  |
8 | pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: std::iter::IntoIterator(HashMap<K, V>);
  |                                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `Output` not found

Some errors have detailed explanations: E0107, E0220, E0658.
For more information about an error, try `rustc --explain E0107`.

The Fix:
changing
pub struct UOMap<K: std::hash::Hash,V> where halfbrown::HashMap<K, V>: std::iter::IntoIterator(HashMap<K, V>);
to
pub struct UOMap<K: std::hash::Hash,V>(HashMap<K, V>) where halfbrown::HashMap<K, V>: std::iter::IntoIterator;
basically, insert the where clause AFTER the closing parenthesis.
from what i was told on the discord, where clause needs to come just before the first {, but idk how it will be dealt with in regards to tuple struct.

rustc version: rustc 1.57.0 (f1edd04 2021-11-29)

@coderedart coderedart 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 Dec 4, 2021
@FabianWolff
Copy link
Contributor

struct Inner<T>(T);
impl Clone for Inner<()> {
    fn clone(&self) -> Self { todo!() }
}

#[derive(Clone)]
struct Outer<T>(Inner<T>);

leads to a nonsensical suggestion on stable:

help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
    |
6   | #[derive(Clone where Inner<T>: Clone)]
    |                +++++++++++++++++++++

Seems to be fixed on nightly though.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 16, 2023
Do not provide suggestions when the spans come from expanded code that doesn't point at user code

Hide invalid proc-macro suggestions and track spans
coming from proc-macros pointing at attribute.

Effectively, unless the proc-macro keeps user spans,
suggestions will not be produced for the code they
produce.

r? `@ghost`

Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557.

Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 17, 2023
Do not provide suggestions when the spans come from expanded code that doesn't point at user code

Hide invalid proc-macro suggestions and track spans
coming from proc-macros pointing at attribute.

Effectively, unless the proc-macro keeps user spans,
suggestions will not be produced for the code they
produce.

r? ``@ghost``

Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557.

Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
@estebank estebank added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. labels Mar 9, 2025
@estebank
Copy link
Contributor

estebank commented Mar 9, 2025

Current output:

error[E0277]: the trait bound `Inner<T>: Clone` is not satisfied
 --> src/lib.rs:7:17
  |
6 | #[derive(Clone)]
  |          ----- in this derive macro expansion
7 | struct Outer<T>(Inner<T>);
  |                 ^^^^^^^^ the trait `Clone` is not implemented for `Inner<T>`
  |
  = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Inner<T>` with `#[derive(Clone)]`
  |
1 + #[derive(Clone)]
2 | struct Inner<T>(T);
  |
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
  |
7 | struct Outer<T>(Inner<T>) where Inner<T>: Clone;
  |                           +++++++++++++++++++++

Can be closed by adding a test.

@karolzwolak
Copy link
Contributor

@rustbot claim

bors added a commit to rust-lang-ci/rust that referenced this issue Mar 22, 2025
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#138609 (Add stack overflow handler for cygwin)
 - rust-lang#138639 (Clean UI tests 2 of n)
 - rust-lang#138773 (catch_unwind intrinsic: document return value)
 - rust-lang#138782 (test(ui): add tuple-struct-where-clause-suggestion ui test for rust-lang#91520)
 - rust-lang#138794 (expand: Do not report `cfg_attr` traces on macros as unused attributes)
 - rust-lang#138801 (triagebot: add autolabel rules for D-* and L-*)
 - rust-lang#138804 (Allow inlining for `Atomic*::from_ptr`)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors closed this as completed in f463e47 Mar 22, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Mar 22, 2025
Rollup merge of rust-lang#138782 - karolzwolak:where-test-91520, r=compiler-errors

test(ui): add tuple-struct-where-clause-suggestion ui test for rust-lang#91520

Fixes rust-lang#91520

I tried to also make it a .fixed test, but I failed to accomplish that.
That's because of the 'consider annotating `Inner<T>` with `#[derive(Clone)]`' suggestion does not compile (conflicting Clone implementations), and I can't isolate them with `rustfix-only-machine-applicable` as both suggestions are not marked as `MachineApplicable`.
Instead I just test that the where clause suggestion is applied to the correct line.
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this issue Apr 2, 2025
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#138609 (Add stack overflow handler for cygwin)
 - rust-lang#138639 (Clean UI tests 2 of n)
 - rust-lang#138773 (catch_unwind intrinsic: document return value)
 - rust-lang#138782 (test(ui): add tuple-struct-where-clause-suggestion ui test for rust-lang#91520)
 - rust-lang#138794 (expand: Do not report `cfg_attr` traces on macros as unused attributes)
 - rust-lang#138801 (triagebot: add autolabel rules for D-* and L-*)
 - rust-lang#138804 (Allow inlining for `Atomic*::from_ptr`)

r? `@ghost`
`@rustbot` modify labels: rollup
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. 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.

4 participants