Skip to content

[derive] Allow clippy::empty_enums on generated field tokens - #3600

Open
githubrobbi wants to merge 1 commit into
google:mainfrom
githubrobbi:derive-allow-empty-enums
Open

[derive] Allow clippy::empty_enums on generated field tokens#3600
githubrobbi wants to merge 1 commit into
google:mainfrom
githubrobbi:derive-allow-empty-enums

Conversation

@githubrobbi

Copy link
Copy Markdown

Fixes #3414.

What breaks

Since rust-lang/rust#155499 stabilized never_type (nightly-2026-08-25 onward), clippy::empty_enums — which is guarded on cx.tcx.features().never_type() — fires on every uninhabited enum, #![feature(never_type)] or not. The derives emit one enum ẕ<field> {} per struct/union field as a type-level field token (derive_has_field_struct_union in derive/try_from_bytes.rs), and derive output carries call-site spans, so the diagnostic lands on the user's #[derive(FromBytes)] line:

error: enum with no variants
  --> src/ntfs/boot_sector.rs:15:30
   |
15 | #[derive(Debug, Clone, Copy, FromBytes, Immutable, KnownLayout)]
   |                              ^^^^^^^^^
   = note: `-D clippy::empty-enums` implied by `-D clippy::nursery`
   = note: this error originates in the derive macro `FromBytes`

A downstream crate that denies clippy::nursery (or pedantic on older clippy, where the lint lived) cannot pass clippy on current nightlies without an #[allow] around every derive site. Clippy's external-macro suppression does not help because the span is the call site.

Fix

Add clippy::empty_enums to the #[allow(...)] list of the generated const _: () = { … } block in util.rs, next to the existing clippy::missing_inline_in_public_items. The exemption is scoped to macro output only; user code keeps the lint.

Verification

Downstream workspace with clippy::nursery = deny (14 FromBytes derive sites): cargo +nightly-2026-08-29 clippy --workspace --all-targets --all-features -- -D warnings goes from 14 errors to clean with this change applied via [patch.crates-io].

The derives emit one uninhabited `enum ẕ<field> {}` per field as a
type-level field token (`derive_has_field_struct_union`). Since
`never_type` stabilized in rust-lang/rust#155499, `clippy::empty_enums`
(guarded on that feature) fires on every empty enum, and because derive
output carries call-site spans the diagnostic lands on the user's
`#[derive(FromBytes)]` line — a downstream crate denying `clippy::nursery`
cannot compile on nightly >= 2026-08-25 without an allow around every
derive site.

Add the lint to the `#[allow(...)]` list of the generated `const _` block,
next to the existing `clippy::missing_inline_in_public_items`, so the
exemption is scoped to macro output only.

Fixes google#3414
@google-cla

google-cla Bot commented Aug 29, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.85%. Comparing base (eb56b4a) to head (f56ef68).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3600   +/-   ##
=======================================
  Coverage   91.85%   91.85%           
=======================================
  Files          20       20           
  Lines        6093     6093           
=======================================
  Hits         5597     5597           
  Misses        496      496           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f56ef68da8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// (rust-lang/rust#155499), `clippy::empty_enums` fires on every
// empty enum, and because derive output carries call-site spans
// the lint lands on the user's `#[derive(...)]` line. See #3414.
clippy::empty_enums,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Allow the new lint name to be unknown on older Clippy

When a downstream crate runs Clippy 1.92 or earlier with -D warnings, this generated attribute is itself a hard error because those releases register the singular clippy::empty_enum and report clippy::empty_enums as an unknown lint. Since const_block wraps every derive expansion, this makes otherwise valid Zerocopy derives fail across older supported toolchains; include unknown_lints in the generated allow list so the unavailable plural spelling is ignored there.

AGENTS.md reference: zerocopy/AGENTS.md:L13-L17

Useful? React with 👍 / 👎.

// (rust-lang/rust#155499), `clippy::empty_enums` fires on every
// empty enum, and because derive output carries call-site spans
// the lint lands on the user's `#[derive(...)]` line. See #3414.
clippy::empty_enums,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Regenerate the derive expansion snapshots

Adding this token changes every expansion produced by const_block, but all 33 checked-in files under zerocopy-derive/src/output_tests/expected still omit it. The output-test harness performs exact pretty-printed token comparison, so cargo test -p zerocopy-derive --lib output_tests::test_known_layout_struct already fails on this added attribute, and the other snapshot-based expansion tests will fail similarly; regenerate and commit the expected expansion files.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

#![feature(never_type)] triggers clippy::empty_enums

2 participants