feature(cairo): Support Span<T> destructuring via fixed-size array pa…#9823
feature(cairo): Support Span<T> destructuring via fixed-size array pa…#9823ilyalesokhin-starkware wants to merge 1 commit intomainfrom
Conversation
dbd4689 to
210b40d
Compare
This stack of pull requests is managed by Graphite. Learn more about stacking. |
210b40d to
4f1006f
Compare
8741730 to
dad17c0
Compare
4f1006f to
2621846
Compare
2621846 to
27b5dd6
Compare
27b5dd6 to
e748528
Compare
ilyalesokhin-starkware
left a comment
There was a problem hiding this comment.
@ilyalesokhin-starkware resolved 1 discussion.
Reviewable status: 0 of 11 files reviewed, 1 unresolved discussion (waiting on orizi).
orizi
left a comment
There was a problem hiding this comment.
@orizi made 2 comments.
Reviewable status: 0 of 11 files reviewed, 3 unresolved discussions (waiting on ilyalesokhin-starkware).
corelib/src/test/language_features/match_test.cairo line 26 at r3 (raw file):
assert_eq!(b, @20); assert_eq!(c, @30); },
Suggestion:
[a, b, c] => {
assert_eq!((*a, *b, *c), (10, 20, 30));
},crates/cairo-lang-lowering/src/lower/flow_control/test_data/match line 2603 at r3 (raw file):
match s { [a, b] => *a + *b, [a, b] => *a + *b,
add also:
Suggestion:
match s {
[a, b] | [a, b, _] => *a + *b,
9df5995 to
0aa3fa0
Compare
|
Not sure if I should do that like in Code quote: opt_wildcard_idx = Some(idx);
for group in size_groups.values_mut() {
group.filter.add(idx);
group.patterns.push(None);
} |
|
Done. |
0aa3fa0 to
f765fac
Compare
ilyalesokhin-starkware
left a comment
There was a problem hiding this comment.
@ilyalesokhin-starkware made 1 comment and resolved 1 discussion.
Reviewable status: 0 of 11 files reviewed, 3 unresolved discussions (waiting on orizi).
crates/cairo-lang-lowering/src/lower/flow_control/test_data/match line 2603 at r3 (raw file):
Previously, orizi wrote…
add also:
Done.
|
Previously, ilyalesokhin-starkware wrote…
see r5 <-> r6. |
f765fac to
344d7d3
Compare
PR SummaryMedium Risk Overview The lowering pipeline now builds a Updates core semantic Reviewed by Cursor Bugbot for commit 29abfa2. Bugbot is set up for automated code reviews on this repo. Configure here. |
orizi
left a comment
There was a problem hiding this comment.
@orizi reviewed 6 files and all commit messages, made 1 comment, and resolved 2 discussions.
Reviewable status: 6 of 11 files reviewed, 3 unresolved discussions (waiting on ilyalesokhin-starkware).
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 549 at r6 (raw file):
/// single inner pattern and feed into [create_node_for_patterns], which wants it already /// unwrapped, hence the asymmetry. patterns: Vec<PatternOption<'a, 'db>>,
doesn't the index in the filter provide this already?
|
Previously, orizi wrote…
It can also be None, so I would need some index to include that. This is smpler |
344d7d3 to
bf5a7cd
Compare
ilyalesokhin-starkware
left a comment
There was a problem hiding this comment.
@ilyalesokhin-starkware resolved 1 discussion.
Reviewable status: 6 of 11 files reviewed, 2 unresolved discussions (waiting on orizi).
orizi
left a comment
There was a problem hiding this comment.
@orizi reviewed 1 file and made 3 comments.
Reviewable status: 7 of 11 files reviewed, 4 unresolved discussions (waiting on ilyalesokhin-starkware).
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 549 at r6 (raw file):
Previously, ilyalesokhin-starkware wrote…
It can also be None, so I would need some index to include that.
Also, FilteredPatterns doesn't provide a convenient way to access the index.This is smpler
got it - call it inner_patterns maybe like we call it in the VariantInfo struct.
even possibly you can use the exact same struct (and change its name) and share much more code
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 401 at r7 (raw file):
/// Each size is tried in order. On failure, the next size is attempted. If all sizes fail, /// the wildcard/otherwise patterns are used. #[allow(clippy::too_many_arguments)]
is there no good logical grouping for params to remove this?
Code quote:
#[allow(clippy::too_many_arguments)]crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 430 at r7 (raw file):
Some(semantic::Pattern::FixedSizeArray(p)) => Some(p), _ => None, });
Suggestion:
let first_fsa = patterns.iter().flatten().find_map(|p| try_extract_matches!(p, semantic::Pattern::FixedSizeArray));bf5a7cd to
3b35bee
Compare
|
decided to remove it; it shouldn't have happened anyway. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ 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 3b35bee. Configure here.
|
Previously, orizi wrote…
|
3b35bee to
51c99a7
Compare
|
Previously, orizi wrote…
Done. |
51c99a7 to
5fabbb7
Compare
ilyalesokhin-starkware
left a comment
There was a problem hiding this comment.
@ilyalesokhin-starkware resolved 1 discussion.
Reviewable status: 7 of 11 files reviewed, 3 unresolved discussions (waiting on orizi).
orizi
left a comment
There was a problem hiding this comment.
@orizi reviewed 1 file and all commit messages, made 3 comments, and resolved 3 discussions.
Reviewable status: 8 of 11 files reviewed, 3 unresolved discussions (waiting on ilyalesokhin-starkware).
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 396 at r9 (raw file):
/// Each size is tried in order. On failure, the next size is attempted. If all sizes fail, /// the wildcard/otherwise patterns are used. fn try_create_slice_destructure_chain<'db>(
can you separate this function into 2:
- check if you want to try to match using the [] pattern.
- actually return a node id.
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 411 at r9 (raw file):
// the `StructConstruct(Span<T>)` it emits rely on this: `snapshot_array_var` below must be // exactly `@Array<T>`, not a wrapped variant. if wrapping_info.n_outer_snapshots != 0 || wrapping_info.n_boxed_inner_snapshots.is_some() {
can you add a test with:
match arr.span() {
[v0] => {...},
[v1] => {...},
Span { snapshot: inner } =>{...}
}
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 511 at r9 (raw file):
})); Some(chain)
Suggestion:
Some(graph.add_node(FlowControlNode::Deconstruct(Deconstruct {
input: input_var,
outputs: vec![snapshot_array_var],
next: failure_node,
})))|
Previously, orizi wrote…
Do we want to support don't catch everything? |
…tterns
Add support for `let [a, b] = span else { ... }` syntax by introducing
a SliceDestructure flow control node that calls tuple_from_span to
convert Span<T> to [T; N] at runtime.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
5fabbb7 to
29abfa2
Compare
ilyalesokhin-starkware
left a comment
There was a problem hiding this comment.
@ilyalesokhin-starkware made 3 comments.
Reviewable status: 7 of 11 files reviewed, 4 unresolved discussions (waiting on orizi).
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 396 at r9 (raw file):
Previously, orizi wrote…
can you separate this function into 2:
- check if you want to try to match using the [] pattern.
- actually return a node id.
Done.
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 511 at r9 (raw file):
})); Some(chain)
Done.
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 503 at r10 (raw file):
// A catch-all struct pattern makes every subsequent arm unreachable, so we stop // adding to `size_groups`. The match-completeness pass will flag the dead arms. break;
we can break here for now, right?
Code quote:
// A catch-all struct pattern makes every subsequent arm unreachable, so we stop
// adding to `size_groups`. The match-completeness pass will flag the dead arms.
break;
orizi
left a comment
There was a problem hiding this comment.
@orizi reviewed 2 files and all commit messages, made 4 comments, and resolved 2 discussions.
Reviewable status: 9 of 11 files reviewed, 4 unresolved discussions (waiting on ilyalesokhin-starkware).
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 411 at r9 (raw file):
Previously, ilyalesokhin-starkware wrote…
Do we want to support don't catch everything?
this just checks that can open the type of "catch everything" object.
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 503 at r10 (raw file):
Previously, ilyalesokhin-starkware wrote…
we can break here for now, right?
assuming they are still considered merged and supply diagnostics - this make sense.
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 354 at r10 (raw file):
elem_ty, ); }
Suggestion:
if let Some(elem_ty) =
should_create_slice_destructure_chain(params.ctx.db, params.patterns, concrete_struct_id, wrapping_info)
// or change signature to `should_create_slice_destructure_chain(¶ms, concrete_struct_id, wrapping_info)`
{
return create_slice_destructure_chain(
params,
input_var,
concrete_struct_id,
elem_ty,
);
}
let CreateNodeParams { ctx, graph, patterns, build_node_callback, location } = params;crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 443 at r10 (raw file):
let snapshot_member_id = members.iter().next().unwrap().1.id; let snapshot_array_ty = members.iter().next().unwrap().1.ty; let snapshot_array_var = graph.new_var(snapshot_array_ty, location);
Suggestion:
let members = match ctx.db.concrete_struct_members(concrete_struct_id) {
Ok(members) => members.iter().exactly_one(),
Err(diag_added) => return graph.add_node(FlowControlNode::Missing(diag_added)),
};
let (snapshot_member_id, snapshot_array_ty) = match members.iter().exactly_one() {
Ok((_, member)) => (member.id, member.ty),
Err(e) => panic!("Got wrong number of `Span` members: `{e:?}`."),
};
let snapshot_array_var = graph.new_var(snapshot_array_ty, location);|
Previously, orizi wrote…
what do you mean by considered merged? |
orizi
left a comment
There was a problem hiding this comment.
@orizi made 1 comment.
Reviewable status: 9 of 11 files reviewed, 4 unresolved discussions (waiting on ilyalesokhin-starkware).
crates/cairo-lang-lowering/src/lower/flow_control/create_graph/patterns.rs line 503 at r10 (raw file):
Previously, ilyalesokhin-starkware wrote…
what do you mean by considered merged?
just the goto at the end the arm to the continuation of the flow.


…tterns
Add support for
let [a, b] = span else { ... }syntax by introducing a SliceDestructure flow control node that calls tuple_from_span to convert Span to [T; N] at runtime.Note
Medium Risk
Touches semantic type-checking and match/let lowering by adding a new flow-control node and runtime conversion path; bugs here could affect pattern matching correctness and generated code for matches involving
Span<T>and fixed-size array patterns.Overview
Adds support for matching/destructuring
Span<T>with fixed-size array patterns (e.g.let [a, b] = span else { ... }andmatch span { [a,b] => ... }).Lowering now builds a size-dispatch chain for
Span<T>patterns via a newFlowControlNode::SliceDestructure, which calls corelibtuple_from_span(withFixedSizedArrayInfoImpl) and handles success/failure branching. Semantic pattern computation is updated to accept fixed-size array patterns onSpantypes, and diagnostics/tests are extended to cover the new behavior.Reviewed by Cursor Bugbot for commit dbd4689. Bugbot is set up for automated code reviews on this repo. Configure here.