Skip to content

fix(rust): handle enums whose first or only tag is a default tag - #183

Merged
hchataing merged 1 commit into
google:mainfrom
renz011tzar:fix-enum-default-tag
Aug 15, 2026
Merged

fix(rust): handle enums whose first or only tag is a default tag#183
hchataing merged 1 commit into
google:mainfrom
renz011tzar:fix-enum-default-tag

Conversation

@renz011tzar

Copy link
Copy Markdown
Contributor

Fixes #182.

Two related panics in the Rust backend for enums that declare a default (= ..) tag.

1. enum_is_complete — empty ranges

enum_is_complete filter-maps the tags down to Tag::Value / Tag::Range, then calls ranges.first().unwrap(). An enum whose only tag is a default tag produces an empty vector, so the unwrap panics (mod.rs:997). An enum with no value or range tags cannot cover the backing integer range, so it is not complete — guarded with !ranges.is_empty().

2. default_value — first tag is a default tag

default_value matched on &tags[0], with ast::Tag::Other(_) => todo!() (mod.rs:1075). That is reached whenever the first declared tag is a default tag, even when the enum also declares value tags:

enum Foo : 8 {
  RESERVED = ..,
  A = 0,
}

Per the discussion on #182, this now selects the first tag that is not a default tag, and falls back to the default tag when it is the only tag declared:

enum OpenWithDefaultTagFirst : 8 {   ->  default() == OpenWithDefaultTagFirst::A
  UNKNOWN = ..,
  A = 0,
}

enum OpenWithOnlyDefaultTag : 8 {    ->  default() == OpenWithOnlyDefaultTag::Unknown(Private(0x0))
  UNKNOWN = ..,
}

Testing

  • Both cases added to the existing enum_declaration snapshot test; snapshots regenerated with UPDATE_SNAPSHOTS=1.
  • The new cases fail on the current main (panicked at mod.rs:1075:31) and pass with this change.
  • cargo test -p pdl-compiler: 171 passed, 0 failed.
  • Generated output for both enums compiles against pdl-runtime.

One note: the final match arm is unreachable for any parsed input, since the parser rejects an enum with no tags — I used expect rather than leaving a todo!(), but happy to restructure it if you would prefer the arm be total.


Found and checked while evaluating Rust verification tooling — midas-lex for the specification step, and a small Verus model of both obligations (the empty-ranges index, and that tag selection always yields a value) to confirm the patched forms are total.

Two related panics in the Rust backend for enums declaring a default
(`= ..`) tag:

- enum_is_complete called ranges.first().unwrap() on a vector that is
  empty when the enum declares no value or range tag. An enum with no
  value or range tags cannot cover the backing integer range, so it is
  not complete; guard with !ranges.is_empty().

- default_value matched on &tags[0] with Tag::Other(_) => todo!(), which
  is reached whenever the first declared tag is a default tag, even when
  value tags follow. Select the first tag that is not a default tag, and
  fall back to the default tag when it is the only tag declared.

Adds both cases to the enum_declaration snapshot test.

Fixes google#182
@hchataing

Copy link
Copy Markdown
Collaborator

Looks good! Thank you for the patch :)

@hchataing
hchataing merged commit e5cc806 into google:main Aug 15, 2026
12 checks passed
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.

pdlc: rust backend panics on an enum whose only tag is a default (= ..)

2 participants