Skip to content

don't suggest non-deriveable traits for unions#154118

Open
malezjaa wants to merge 1 commit intorust-lang:mainfrom
malezjaa:dont-suggest-some-traits-for-unions
Open

don't suggest non-deriveable traits for unions#154118
malezjaa wants to merge 1 commit intorust-lang:mainfrom
malezjaa:dont-suggest-some-traits-for-unions

Conversation

@malezjaa
Copy link
Contributor

@malezjaa malezjaa commented Mar 19, 2026

cc #137587

Before, the compiler suggested adding #[derive(Debug)] (other traits too) for unions,
which is misleading because some traits can't be automatically derived.

Only traits that are still suggested are Copy and Clone.

I noticed the error label changed after removing the suggestion. I hope this isn't a big deal, but let me know if that's an issue.

original example:

union Union {
    member: usize,
}

impl PartialEq<u8> for Union {
    fn eq(&self, rhs: &u8) -> bool {
        unsafe { self.member == (*rhs).into() }
    }
}

fn main() {
    assert_eq!(Union { member: 0 }, 0);
}

before:

error[E0277]: `Union` doesn't implement `Debug`                                                                       
  --> src\main.rs:13:5
   |
13 |     assert_eq!(Union { member: 0 }, 0);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Union`
   |
   = note: add `#[derive(Debug)]` to `Union` or manually `impl Debug for Union`
   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Union` with `#[derive(Debug)]`
   |
 2 + #[derive(Debug)]
 3 | union Union {
   |

after (the message doesn't suggest adding #[derive(Debug)] to unions)

error[E0277]: `Union` doesn't implement `Debug`                                                                       
  --> src\main.rs:13:5
   |
13 |     assert_eq!(Union { member: 0 }, 0);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
   |
help: the trait `Debug` is not implemented for `Union`
  --> src\main.rs:2:1
   |
 2 | union Union {
   | ^^^^^^^^^^^
   = note: manually `impl Debug for Union`

@rustbot
Copy link
Collaborator

rustbot commented Mar 19, 2026

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) 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. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 19, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 19, 2026

r? @dingxiangfei2009

rustbot has assigned @dingxiangfei2009.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler, types
  • compiler, types expanded to 69 candidates
  • Random selection from 14 candidates

@malezjaa malezjaa changed the title don't suggest non-deriveable for unions don't suggest non-deriveable traits for unions Mar 19, 2026
@Kivooeo
Copy link
Member

Kivooeo commented Mar 20, 2026

Can you please add a test to reflect new behaviour

@malezjaa malezjaa force-pushed the dont-suggest-some-traits-for-unions branch from 8fd2da8 to ccaae21 Compare March 20, 2026 08:24
@rustbot rustbot 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 Mar 20, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 20, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@JonathanBrouwer
Copy link
Contributor

cc @mejrs
if you feel like it, could you also take a look?

Don't suggest non-deriveable tests for unions. This also adds enum, struct and union markers to rustc_on_unimplemented
@malezjaa malezjaa force-pushed the dont-suggest-some-traits-for-unions branch from ccaae21 to dd844f3 Compare March 20, 2026 20:03
Copy link
Contributor

@mejrs mejrs left a comment

Choose a reason for hiding this comment

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

The changes to on_unimplemented look good. I have some suggestions.

Please also update this test

#[diagnostic::on_unimplemented(
message = "{from_desugaring}{direct}{cause}{integral}{integer}",
//~^WARN there is no parameter `from_desugaring` on trait `Baz`
//~|WARN there is no parameter `direct` on trait `Baz`
//~|WARN there is no parameter `cause` on trait `Baz`
//~|WARN there is no parameter `integral` on trait `Baz`
//~|WARN there is no parameter `integer` on trait `Baz`
label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
//~^WARN there is no parameter `float` on trait `Baz`
//~|WARN there is no parameter `_Self` on trait `Baz`
//~|WARN there is no parameter `crate_local` on trait `Baz`
//~|WARN there is no parameter `Trait` on trait `Baz`
//~|WARN there is no parameter `ItemContext` on trait `Baz`
//~|WARN there is no parameter `This` on trait `Baz`
)]
trait Baz {}

View changes since this review

@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
##[endgroup]
Executing "/scripts/stage_2_test_set1.sh"
+ /scripts/stage_2_test_set1.sh
+ '[' 1 == 1 ']'
+ echo 'PR_CI_JOB set; skipping tidy'
+ SKIP_TIDY='--skip tidy'
+ ../x.py --stage 2 test --skip tidy --skip compiler --skip src
PR_CI_JOB set; skipping tidy
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.04s
##[endgroup]
---
78 note: required by a bound in `x`
-   --> $DIR/union-no-derive-suggestion.rs:10:8
+   --> $DIR/union-no-derive-suggestion.rs:10:9
80    |
- LL | fn x<T:Clone>() {}
-    |        ^^^^^ required by this bound in `x`
+ LL | fn x<T: Clone>() {}
+    |         ^^^^^ required by this bound in `x`
83 help: consider annotating `U` with `#[derive(Clone)]`
84    |
85 LL + #[derive(Clone)]

93    |         ^ the trait `Copy` is not implemented for `U`
94    |
95 note: required by a bound in `y`
-   --> $DIR/union-no-derive-suggestion.rs:11:8
+   --> $DIR/union-no-derive-suggestion.rs:11:9
97    |
- LL | fn y<T:Copy>() {}
-    |        ^^^^ required by this bound in `y`
+ LL | fn y<T: Copy>() {}
+    |         ^^^^ required by this bound in `y`
100 help: consider annotating `U` with `#[derive(Copy)]`
101    |
102 LL + #[derive(Copy)]

Note: some mismatched output was normalized before being compared
-   --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:10:9
-   --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:11:9
+   --> $DIR/union-no-derive-suggestion.rs:10:9
+ LL | fn x<T: Clone>() {}
+    |         ^^^^^ required by this bound in `x`
+   --> $DIR/union-no-derive-suggestion.rs:11:9
+ LL | fn y<T: Copy>() {}
+    |         ^^^^ required by this bound in `y`


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args union/union-no-derive-suggestion.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/union/union-no-derive-suggestion.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/union/union-no-derive-suggestion" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0277]: `U` doesn't implement `Debug`
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:16:15
   |
LL |     println!("{u:?}"); //~ ERROR `U` doesn't implement `Debug`
   |               ^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
help: the trait `Debug` is not implemented for `U`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:2:1
   |
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   | ^^^^^^^
   = note: manually `impl Debug for U`

error[E0369]: binary operation `==` cannot be applied to type `U`
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:19:15
   |
LL |     let _ = u == U { a: 0 }; //~ ERROR binary operation `==` cannot be applied to type `U`
   |             - ^^ ---------- U
   |             |
   |             U
   |
note: an implementation of `PartialEq` might be missing for `U`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:2:1
   |
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   | ^^^^^^^ must implement `PartialEq`
note: the trait `PartialEq` must be implemented
  --> /rustc/FAKE_PREFIX/library/core/src/cmp.rs:251:0

error[E0369]: binary operation `<` cannot be applied to type `U`
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:22:15
   |
LL |     let _ = u < U { a: 1 }; //~ ERROR binary operation `<` cannot be applied to type `U`
   |             - ^ ---------- U
   |             |
   |             U
   |
note: an implementation of `PartialOrd` might be missing for `U`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:2:1
   |
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   | ^^^^^^^ must implement `PartialOrd`
note: the trait `PartialOrd` must be implemented
  --> /rustc/FAKE_PREFIX/library/core/src/cmp.rs:1367:0

error[E0277]: the trait bound `U: Default` is not satisfied
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:25:16
   |
LL |     let _: U = Default::default(); //~ ERROR the trait bound `U: Default` is not satisfied
   |                ^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
   |
help: the trait `Default` is not implemented for `U`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:2:1
   |
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   | ^^^^^^^

error[E0277]: the trait bound `U: Hash` is not satisfied
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:28:27
   |
LL |     std::hash::Hash::hash(&u, &mut h); //~ ERROR the trait bound `U: Hash` is not satisfied
   |     --------------------- ^^ unsatisfied trait bound
   |     |
   |     required by a bound introduced by this call
   |
help: the trait `Hash` is not implemented for `U`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:2:1
   |
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   | ^^^^^^^

error[E0277]: the trait bound `U: Clone` is not satisfied
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:31:9
   |
LL |     x::<U>(); //~ ERROR the trait bound `U: Clone` is not satisfied
   |         ^ the trait `Clone` is not implemented for `U`
   |
note: required by a bound in `x`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:10:9
   |
LL | fn x<T: Clone>() {}
   |         ^^^^^ required by this bound in `x`
help: consider annotating `U` with `#[derive(Clone)]`
   |
LL + #[derive(Clone)]
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   |

error[E0277]: the trait bound `U: Copy` is not satisfied
##[error]  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:33:9
   |
LL |     y::<U>(); //~ ERROR the trait bound `U: Copy` is not satisfied
   |         ^ the trait `Copy` is not implemented for `U`
   |
note: required by a bound in `y`
  --> /checkout/tests/ui/union/union-no-derive-suggestion.rs:11:9
   |
LL | fn y<T: Copy>() {}
   |         ^^^^ required by this bound in `y`
help: consider annotating `U` with `#[derive(Copy)]`
   |
LL + #[derive(Copy)]
LL | union U { //~ HELP consider annotating `U` with `#[derive(Clone)]`
   |

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0277, E0369.

@malezjaa
Copy link
Contributor Author

I forgot to rebless the test. Will do that in a sec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants