Skip to content

bugfix(semantic): Reject phantom types used as values.#10169

Merged
orizi merged 1 commit into
mainfrom
orizi/06-28-bugfix_semantic_reject_phantom_types_used_as_values
Jun 28, 2026
Merged

bugfix(semantic): Reject phantom types used as values.#10169
orizi merged 1 commit into
mainfrom
orizi/06-28-bugfix_semantic_reject_phantom_types_used_as_values

Conversation

@orizi

@orizi orizi commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Phantom types (types marked #[phantom], or types that transitively contain a phantom type through struct members, enum variants, tuple elements, or fixed-size array elements) now produce a diagnostic error when they appear in a function signature or are used as values. Previously, only direct instantiation of a phantom type was caught; wrapping a phantom type in a generic container like Option<Ph> would silently compile. The diagnostic message was also updated from "Can not create instances of phantom types." to "Phantom types cannot be instantiated.".

The is_phantom check on TypeLongId was extended to recurse into struct members and enum variants (in addition to the existing tuple/array recursion), and the check is now memoized via a Salsa-tracked query with a cycle-breaking fallback of false. Function signature validation now explicitly checks each parameter type and the return type for phantom-ness and emits CannotCreateInstancesOfPhantomTypes accordingly.

On the Sierra generation side, the special-casing that represented user-defined phantom structs/enums as never was removed. Extern phantom types (e.g. circuit gates) still retain their dedicated Phantom Sierra long id. User-defined phantom types that appear only after generic substitution (i.e. where the generic parameter itself is not phantom) fall through to their regular Sierra representation, since the front-end diagnostic only fires when the concrete phantom type is visible at the use site.


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?

Using a phantom type inside a generic container (e.g. Option<Ph>) in a function signature or as a runtime value was previously accepted by the compiler and silently lowered to a never-typed Sierra representation. This was incorrect: phantom types have no runtime representation and must not appear as values. The compiler should reject such code with a clear diagnostic rather than silently producing potentially unsound Sierra output.


What was the behavior or documentation before?

Option<Ph> (where Ph is a #[phantom] type) was accepted in function signatures and as values. The Sierra generator would represent the phantom struct/enum as never and specialize containers around it accordingly. The diagnostic for direct phantom instantiation used the message "Can not create instances of phantom types.".


What is the behavior or documentation after?

Any type that is, or transitively contains, a phantom type is now rejected in function signatures (both parameters and return types) and when used as a value. The diagnostic message is "Phantom types cannot be instantiated.". Extern phantom types used by libfuncs (e.g. circuit gates) are unaffected. Phantom types that appear only after generic substitution (where the generic parameter is not itself phantom) continue to compile via their regular Sierra representation.


Related issue or discussion (if any)


Additional context

The is_phantom query is now Salsa-tracked with a cycle result of false to handle self-referential types without infinite recursion.

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

orizi commented Jun 28, 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 28, 2026 10:43
@cursor

cursor Bot commented Jun 28, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches core type checking, inference rewrite diagnostics, and Sierra type lowering; behavior change may reject previously accepted code and alter circuit type strings, though extern circuit phantoms are preserved.

Overview
Phantom types (including those nested in generics, structs, tuples, snapshots, or implicits) are now rejected when they appear in function signatures or as expression values, not only on direct struct/enum construction. The diagnostic is renamed to InstancesOfPhantomTypes with message "Phantom types cannot be instantiated." (still E2019).

is_phantom now treats a type as phantom if it transitively contains one via struct members, enum variant payloads, tuples, fixed-size arrays, or @T snapshots; the check is Salsa-memoized with cycle edges contributing false.

Sierra generation drops mapping user-defined phantom structs/enums to never and the old contains_extern_phantom walk; only extern phantom types keep the dedicated Phantom long id. Cases that only become phantom after generic substitution may still lower with a regular representation.

Expectation updates cover new semantic tests, sierra generator cases (signature/value errors vs post-substitution compile), circuit profiling/contract JSON (Circuit<(...)>Circuit<Tuple<...>>), and related fixtures.

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

Comment thread crates/cairo-lang-semantic/src/types.rs

@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: ab368f90d8

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/cairo-lang-semantic/src/items/functions.rs
Comment thread crates/cairo-lang-semantic/src/types.rs Outdated
@orizi orizi force-pushed the orizi/06-28-bugfix_semantic_reject_phantom_types_used_as_values branch from ab368f9 to 10b248b Compare June 28, 2026 11:03
Comment thread crates/cairo-lang-semantic/src/expr/compute.rs

@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: 0 of 15 files reviewed, 3 unresolved discussions (waiting on eytan-starkware and TomerStarkware).

Comment thread crates/cairo-lang-semantic/src/items/functions.rs

@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 resolved 2 discussions.
Reviewable status: 0 of 15 files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).

@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 3 files and all commit messages, and made 1 comment.
Reviewable status: 3 of 15 files reviewed, 2 unresolved discussions (waiting on orizi and TomerStarkware).


crates/cairo-lang-semantic/src/types.rs line 167 at r2 (raw file):

    /// Returns whether the type is, or transitively contains, a phantom type.
    ///
    /// A type is phantom if it carries the `#[phantom]` attribute (or a phantom attribute declared

Documenting what a phantom is twice will be a source of divergance

@orizi orizi force-pushed the orizi/06-28-bugfix_semantic_reject_phantom_types_used_as_values branch from 10b248b to 30696f9 Compare June 28, 2026 11:31
Comment thread crates/cairo-lang-semantic/src/expr/compute.rs
Phantom types have no runtime representation, but a `#[phantom]` type -
or a type that transitively contains one, e.g. `Option<Ph>` - could still
appear as a value: a function parameter or return type, a constructed
value, or any expression. Reaching sierra generation it caused an ICE -
the type was lowered to `never`, whose shape did not match the phantom's
declared variants/members, so the emitted `match`/`struct_deconstruct`
mismatched the libfunc signature.

- `TypeId::is_phantom` now reports whether a type is, or transitively
  contains, a phantom type (through struct members, enum variants, tuple
  and fixed-size-array elements, or a snapshot), guarded against
  self-referential types.
- Function parameter and return types, and every expression, are now
  checked; a phantom one is reported as `CannotCreateInstancesOfPhantomTypes`
  ("Phantom types cannot be instantiated.").
- The sierra-generator `never` workaround is removed; phantom types now
  use their regular representation. This is correct for the only case the
  front end cannot see - a phantom that becomes concrete only after generic
  substitution - which now compiles instead of panicking.
@orizi orizi force-pushed the orizi/06-28-bugfix_semantic_reject_phantom_types_used_as_values branch from 30696f9 to 0e631f3 Compare June 28, 2026 11:35

@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: 2 of 15 files reviewed, 2 unresolved discussions (waiting on eytan-starkware and TomerStarkware).


crates/cairo-lang-semantic/src/types.rs line 167 at r2 (raw file):

Previously, eytan-starkware wrote…

Documenting what a phantom is twice will be a source of divergance

Done.

@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 resolved 1 discussion.
Reviewable status: 1 of 15 files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0e631f3. Configure here.

Comment thread crates/cairo-lang-semantic/src/types.rs

@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: 1 of 15 files reviewed, 2 unresolved discussions (waiting on eytan-starkware and TomerStarkware).

Comment thread crates/cairo-lang-semantic/src/types.rs

@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 14 files and all commit messages, made 1 comment, and resolved 1 discussion.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on orizi and TomerStarkware).

Comment thread crates/cairo-lang-semantic/src/types.rs

@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: all files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).

Comment thread crates/cairo-lang-semantic/src/types.rs

@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 made 1 comment and resolved 1 discussion.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on TomerStarkware).

@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: :shipit: complete! all files reviewed, all discussions resolved (waiting on TomerStarkware).

Comment thread crates/cairo-lang-semantic/src/types.rs
@orizi orizi enabled auto-merge June 28, 2026 12:55
@orizi orizi added this pull request to the merge queue Jun 28, 2026
Merged via the queue into main with commit 0fb9292 Jun 28, 2026
55 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.

3 participants