Skip to content

Fix a Panic on Enums/Interfaces that Inherited from Anonymous Types - #802

Open
InsertCreativityHere wants to merge 1 commit into
icerpc:mainfrom
InsertCreativityHere:audit-fix-enum-underlying-type-panic
Open

Fix a Panic on Enums/Interfaces that Inherited from Anonymous Types#802
InsertCreativityHere wants to merge 1 commit into
icerpc:mainfrom
InsertCreativityHere:audit-fix-enum-underlying-type-panic

Conversation

@InsertCreativityHere

Copy link
Copy Markdown
Member

In a Slice file, if you try to use an anonymous type (a sequence, dictionary or result type) as:

  • the underlying type of an enum (enum Foo : Sequence<int8>), or
  • the base of an interface (interface Foo : Sequence<int8>)

It would cause the compiler to crash, instead of correctly reporting an error.
This was due to a bad assumption we were making about these during the parsing phase.

This PR fixes both parts of #798.


This PR doesn't have any notes, since:
A) Nobody in their right mind was ever doing this, and it's clearly insane on the face of it.
B) It was and is still disallowed, this just changes the 'rejection' from a panic to a proper error we can report.

@InsertCreativityHere InsertCreativityHere added this to the 0.4.1 milestone Aug 20, 2026
@InsertCreativityHere InsertCreativityHere added the slicec Related to the 'slicec' crate label Aug 20, 2026
@@ -51,7 +51,10 @@ impl<T: Element + ?Sized> TypeRef<T> {
impl<T: Type + ?Sized> TypeRef<T> {
// This intentionally shadows the trait method of the same name on `Type`.
pub fn type_string(&self) -> String {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a tangential change.
It lets us print a reference before the patching phase has run.
i.e. now we can safely print a reference while the parser is running.

For unpatched references, we print the exact text found in the Slice file.
For patched references, the behavior is unchanged.

.into_iter()
.map(|base| base.downcast::<Interface>().unwrap())
.filter_map(|base| {
let interface_ref = base.downcast::<Interface>();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Now we check the result of downcast::<Interface> instead of assuming it would succeed.
If it is_err() we report and error and discard the base. Otherwise it gets kept like before.

) -> OwnedPtr<Enum> {
let underlying = underlying_type.map(|type_ref| type_ref.downcast::<Primitive>().unwrap());
let underlying = underlying_type.and_then(|type_ref| {
let primitive_ref = type_ref.downcast::<Primitive>();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Same for enums, we check if the downcast succeeded instead of blindly calling unwrap (assuming it will always work).

@InsertCreativityHere
InsertCreativityHere requested review from bernardnormier and externl and a lite review from Copilot August 20, 2026 19:43

Copilot AI 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.

Pull request overview

This PR prevents slicec from panicking when a Slice file uses an anonymous type (Sequence/Dictionary/Result) as an enum underlying type or as an interface base type, and instead emits a proper diagnostic (per #798).

Changes:

  • Update the Slice grammar construction for interfaces/enums to report a diagnostic instead of unwrap()-panicking on invalid patched TypeRefs.
  • Improve TypeRef::type_string() so it can stringify both patched and unpatched references (supporting better diagnostics).
  • Expand/parameterize enum/interface tests to cover anonymous-type cases (and optional anonymous types) that previously crashed.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
slicec/tests/interfaces/inheritance.rs Parameterizes invalid interface-base tests to include primitives and anonymous built-ins.
slicec/tests/enums/mod.rs Adds coverage for anonymous underlying types and splits optional-underlying cases into clearer test groups.
slicec/src/parsers/slice/grammar.rs Replaces unwrap() downcasts with diagnostic-emitting fallbacks for interface bases and enum underlyings.
slicec/src/grammar/elements/type_ref.rs Makes TypeRef::type_string() work for both patched and unpatched refs (avoids panics and improves messages).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread slicec/src/parsers/slice/grammar.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

slicec Related to the 'slicec' crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants