bugfix(semantic): Reject phantom types used as values.#10169
Conversation
PR SummaryMedium Risk Overview
Sierra generation drops mapping user-defined phantom structs/enums to Expectation updates cover new semantic tests, sierra generator cases (signature/value errors vs post-substitution compile), circuit profiling/contract JSON ( Reviewed by Cursor Bugbot for commit 0e631f3. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
💡 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".
ab368f9 to
10b248b
Compare
orizi
left a comment
There was a problem hiding this comment.
@orizi made 1 comment.
Reviewable status: 0 of 15 files reviewed, 3 unresolved discussions (waiting on eytan-starkware and TomerStarkware).
orizi
left a comment
There was a problem hiding this comment.
@orizi resolved 2 discussions.
Reviewable status: 0 of 15 files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).
eytan-starkware
left a comment
There was a problem hiding this comment.
@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
10b248b to
30696f9
Compare
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.
30696f9 to
0e631f3
Compare
orizi
left a comment
There was a problem hiding this comment.
@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
left a comment
There was a problem hiding this comment.
@orizi resolved 1 discussion.
Reviewable status: 1 of 15 files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ 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.
orizi
left a comment
There was a problem hiding this comment.
@orizi made 1 comment.
Reviewable status: 1 of 15 files reviewed, 2 unresolved discussions (waiting on eytan-starkware and TomerStarkware).
eytan-starkware
left a comment
There was a problem hiding this comment.
@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).
orizi
left a comment
There was a problem hiding this comment.
@orizi made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on eytan-starkware and TomerStarkware).
eytan-starkware
left a comment
There was a problem hiding this comment.
@eytan-starkware made 1 comment and resolved 1 discussion.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on TomerStarkware).
orizi
left a comment
There was a problem hiding this comment.
@orizi made 1 comment.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on TomerStarkware).


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 likeOption<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_phantomcheck onTypeLongIdwas 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 offalse. Function signature validation now explicitly checks each parameter type and the return type for phantom-ness and emitsCannotCreateInstancesOfPhantomTypesaccordingly.On the Sierra generation side, the special-casing that represented user-defined phantom structs/enums as
neverwas removed. Extern phantom types (e.g. circuit gates) still retain their dedicatedPhantomSierra 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:
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 anever-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>(wherePhis a#[phantom]type) was accepted in function signatures and as values. The Sierra generator would represent the phantom struct/enum asneverand 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_phantomquery is now Salsa-tracked with a cycle result offalseto handle self-referential types without infinite recursion.