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

fix(semantic): canonicalize felt252 inside NonZero when matching const patterns - #10058

Merged
orizi merged 1 commit into
mainfrom
orizi/06-08-fix_semantic_canonicalize_felt252_inside_nonzero_when_matching_const_patterns
Jun 8, 2026
Merged

orizi merged 1 commit into
mainfrom
orizi/06-08-fix_semantic_canonicalize_felt252_inside_nonzero_when_matching_const_patterns

Conversation

@orizi

@orizi orizi commented Jun 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes constant evaluation of NonZero values in match patterns. Previously, when a NonZero-wrapped value appeared as the scrutinee in a match expression during constant evaluation, the pattern matching logic did not unwrap the NonZero layer before comparing against literal patterns, causing the match to fail. The fix propagates the NonZero-unwrapping behavior (already present in NumericArg::try_new) into the literal pattern matching branch, and consolidates the numeric_arg_value free function into NumericArg::try_new so that the type is correctly carried through after unwrapping.

A new test case (VALID_MATCH_NONZERO_FELT_CROSS_FORM) is added to verify that matching a NonZero<felt252> constant against its field-equivalent hex literal evaluates correctly.


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?

Matching a NonZero-wrapped constant value against a literal pattern in a const context would silently fail because the pattern matching code called numeric_arg_value (which discarded the type after unwrapping NonZero) rather than NumericArg::try_new (which preserves the unwrapped type). This meant cross-form equality checks using match on NonZero values were broken at compile-time constant evaluation.


What was the behavior or documentation before?

A const expression using match on a NonZero<felt252> value against a literal pattern would not evaluate correctly, even when the values were semantically equal.


What is the behavior or documentation after?

NonZero-wrapped values are correctly unwrapped during literal pattern matching in constant evaluation, and the unwrapped type is preserved. The numeric_arg_value helper is removed in favor of the unified NumericArg::try_new.


Related issue or discussion (if any)

N/A


Additional context

The line number shifts in the test snapshot reflect the insertion of the new VALID_MATCH_NONZERO_FELT_CROSS_FORM constant (6 lines added before the error-producing constants).

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

orizi commented Jun 8, 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 8, 2026 06:50
@cursor

cursor Bot commented Jun 8, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Narrow change to const pattern matching and numeric arg extraction; behavior aligns with existing const equality paths.

Overview
Fixes compile-time match on NonZero constants when the scrutinee and a literal pattern use different but field-equivalent felt252 forms (e.g. -1 vs hex).

Literal pattern matching in constant evaluation now goes through NumericArg::try_new, which unwraps NonZero and keeps the inner numeric type for eq_in_type (same felt252 canonicalization as ==). The old numeric_arg_value helper is removed and its logic lives in NumericArg::try_new.

Adds VALID_MATCH_NONZERO_FELT_CROSS_FORM in the constant test snapshot; unrelated diagnostic line numbers shift slightly.

Reviewed by Cursor Bugbot for commit e8ccd86. 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.

:lgtm:

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


crates/cairo-lang-semantic/src/items/constant.rs line 1266 at r1 (raw file):

    ty: TypeId<'db>,
}
impl<'db> NumericArg<'db> {

Add doc

@orizi
orizi force-pushed the orizi/06-08-fix_semantic_canonicalize_felt252_inside_nonzero_when_matching_const_patterns branch from c460eb2 to 6a8270a Compare June 8, 2026 07:39

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


crates/cairo-lang-semantic/src/items/constant.rs line 1266 at r1 (raw file):

Previously, eytan-starkware wrote…

Add doc

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.

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


crates/cairo-lang-semantic/src/items/constant.rs line 1272 at r2 (raw file):

        match arg.long(db) {
            ConstValue::Int(v, ty) => Some(Self { v: v.clone(), ty: *ty }),
            ConstValue::Struct(v, ty) => {

We should check struct type to verify u256

…t patterns

  `destructure_pattern`'s literal arm passed the matched value's OUTER type to
  `eq_in_type`, so for a `NonZero<felt252>` const the felt252 canonicalization
  (gated on `ty == felt252`) was skipped: `match nz_felt { PRIME-1 => .. }`
  compared the raw `-1` vs `PRIME-1` and took the wildcard arm, disagreeing with
  `==` (which recurses through NonZero). Route the literal arm through
  `NumericArg::try_new`, which already unwraps NonZero and carries the inner
  numeric type — the same machinery the const arithmetic path uses.
@orizi
orizi force-pushed the orizi/06-08-fix_semantic_canonicalize_felt252_inside_nonzero_when_matching_const_patterns branch from 6a8270a to e8ccd86 Compare June 8, 2026 08:47

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


crates/cairo-lang-semantic/src/items/constant.rs line 1272 at r2 (raw file):

Previously, eytan-starkware wrote…

We should check struct type to verify u256

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, made 1 comment, and 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 8, 2026
Merged via the queue into main with commit 815e6dd Jun 8, 2026
54 checks passed
@orizi
orizi deleted the orizi/06-08-fix_semantic_canonicalize_felt252_inside_nonzero_when_matching_const_patterns branch June 8, 2026 09:59
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