Sitelet https://github.com/starkware-libs/cairo/pull/10080
Skip to content

bugfix(plugins): Fix derive(Hash)/derive(Serde) codegen for enums. - #10080

Merged
orizi merged 1 commit into
mainfrom
orizi/06-11-bugfix_plugins_fix_derive_hash__derive_serde_codegen_for_enums
Jun 11, 2026
Merged

orizi merged 1 commit into
mainfrom
orizi/06-11-bugfix_plugins_fix_derive_hash__derive_serde_codegen_for_enums

Conversation

@orizi

@orizi orizi commented Jun 11, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes #[derive(Hash)] for generic enums by ensuring variant values are properly dropped after hashing. Each enum variant's value is now wrapped in a DropWith or InferDrop struct before calling update_state, so the value is consumed through x.value rather than directly. The Hash derive for enums now also requires Drop bounds on generic type parameters, adding DROP_TRAIT to the list of impl generics alongside HASH_TRAIT.

Additionally, the Serde derive for non-generic enums is simplified to use impl_header (consistent with structs), which removes the spurious empty whitespace in the generated impl header.


Type of change

Please check one:

  • Bug fix (fixes incorrect behavior)
  • New feature
  • Performance improvement
  • Documentation change with concrete technical impact
  • Style, wording, formatting, or typo-only change

Why is this change needed?

Deriving Hash on a generic enum previously did not require or use Drop bounds on the generic type parameters. After update_state consumes the variant value, the remaining matched value would not be properly dropped, causing a compilation error for generic enums. The fix wraps each variant value in a DropWith/InferDrop struct so the compiler can infer the correct drop behavior.


What was the behavior or documentation before?

#[derive(Hash)] on a generic enum (e.g., enum GenericEnum<T>) would fail to compile because the derived implementation did not include Drop<T> bounds and did not properly drop the matched variant values.


What is the behavior or documentation after?

#[derive(Hash)] on generic enums now generates correct implementations that include Drop<T> bounds for each generic member and wrap variant values in DropWith/InferDrop before hashing, ensuring values are properly consumed.


Related issue or discussion (if any)

N/A


Additional context

Test cases for GenericEnum<T> and GenericEnumMulti<T> have been added to the derive test data to cover single and multiple generic variant scenarios.

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

orizi commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@orizi
orizi marked this pull request as ready for review June 11, 2026 08:23
@cursor

cursor Bot commented Jun 11, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes macro-generated trait impls for all derived enums (Hash drop semantics and Serde header formatting); behavior should match structs but affects widespread compile-time output.

Overview
Fixes #[derive(Hash)] on enums so variant payloads are consumed and dropped correctly after hashing, matching the struct derive path.

Enum Hash codegen now includes Drop bounds on generic variant types (alongside Hash), and each matched variant wraps its payload in DropWith / InferDrop before calling update_state via x.value. Non-generic enums get the same InferDrop wrapping (e.g. TwoVariantEnum).

#[derive(Serde)] for enums now builds the impl header through impl_header, which removes stray blank lines in generated impl …Serde<> signatures (format-only; serde logic unchanged).

Derive and Starknet contract plugin snapshots add generic enum Hash cases and updated Serde impl headers.

Reviewed by Cursor Bugbot for commit ea647df. Bugbot is set up for automated code reviews on this repo. Configure here.

@eytan-starkware eytan-starkware left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@eytan-starkware reviewed 4 files and all commit messages, and made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on orizi and TomerStarkware).


crates/cairo-lang-plugins/src/test_data/derive line 127 at r1 (raw file):

#[derive(Drop, Hash)]
enum GenericEnumMulti<T> {
    First: T,

Add a test with more then one generic type

  derive(Hash) on a generic enum previously failed to compile: the
  generated impl left the payload `x: T` live across the (panicking)
  discriminant-hash call with no bound on `T` (E3002 "Variable not
  dropped"), so no generic enum could derive Hash at all. Add a per-member
  `Drop<T>` bound (matching the struct branch) and wrap each variant
  payload in `DropWith`, pinning the variant's named Drop impl so enums
  with multiple members of the same generic type stay unambiguous.

  derive(Serde) on a non-generic enum emitted a whitespace-only generics
  header (`<\n    \n>`) via a standalone formatdoc!; switch to
  `impl_header`, matching every other derive.
@orizi
orizi force-pushed the orizi/06-11-bugfix_plugins_fix_derive_hash__derive_serde_codegen_for_enums branch from 4f51588 to ea647df Compare June 11, 2026 10:28

@orizi orizi left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@orizi made 1 comment.
Reviewable status: 3 of 4 files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).


crates/cairo-lang-plugins/src/test_data/derive line 127 at r1 (raw file):

Previously, eytan-starkware wrote…

Add a test with more then one generic type

Done.

@eytan-starkware eytan-starkware left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

:lgtm:

@eytan-starkware reviewed 1 file and all commit messages, and made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on TomerStarkware).

@orizi
orizi enabled auto-merge June 11, 2026 11:22

@eytan-starkware eytan-starkware left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@eytan-starkware resolved 1 discussion.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on TomerStarkware).

@orizi
orizi added this pull request to the merge queue Jun 11, 2026
Merged via the queue into main with commit 5051f92 Jun 11, 2026
54 checks passed
@orizi
orizi deleted the orizi/06-11-bugfix_plugins_fix_derive_hash__derive_serde_codegen_for_enums branch June 11, 2026 13:31
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.

3 participants