Skip to content

Conversation

@mbouaziz
Copy link
Contributor

@mbouaziz mbouaziz commented Feb 6, 2026

Summary

  • Fix issue Segfault/incorrect results for overlapping patterns with underscore-prefixed variables #988: Segfault/incorrect results for overlapping patterns with underscore-prefixed variables
  • Names starting with _ no longer bind in patterns (they act as wildcards)
  • Attempting to use a _-prefixed variable value produces a clear error message
  • Underscore-prefixed struct fields are still allowed - use explicit binding syntax (_field => var) if you need the value

Test plan

Fixes #988

🤖 Generated with Claude Code

@mbouaziz mbouaziz requested review from beauby and bennostein February 6, 2026 17:23
mbouaziz and others added 5 commits February 12, 2026 17:00
Underscore-prefixed variables in overlapping patterns cause
segfaults and incorrect results due to a binding collision in
match lowering.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The ? operator desugars to a match expression that binds the inner value
to a temporary variable. This variable was named `__x` which starts with
underscore. Rename to `!x` to follow the compiler temp variable convention
and avoid triggering the underscore-prefixed variable restriction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When pattern matching on fields with underscore prefix (e.g., _value_name),
use explicit binding syntax `_value_name => value_name` to bind the value
to a non-underscore variable name. This allows the value to be used while
avoiding the underscore-prefixed variable restriction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Don't bind underscore-prefixed variables (_x, _y, etc.) in pattern
matching. They are still allowed in patterns but act as wildcards,
so reading their value triggers the existing "You cannot use a variable
that starts with _" error.

This fixes issue #988 where overlapping patterns with _x-style variables
caused binding collisions in the lowering phase, resulting in segfaults
or incorrect results.

Changes:
- check_locals_pattern: Skip binding for is_wildcard_name variables
- bind_pattern_name: Use startsWith("_") for duplicate checking
- Enable the repro test from tests/todo/ in tests/syntax/invalid/

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Defense in depth: when lowering match expressions, treat any binding
whose name starts with _ as an underscore binding (not just exact "_").
This prevents creating bindings for _x-style variables during match
lowering, complementing the fix in skipNaming.sk.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mbouaziz mbouaziz force-pushed the fix-988-underscore-pattern-vars branch from 2b82561 to b2f07e3 Compare February 12, 2026 16:00
SkipAst.Pat_type(
SkipAst.Tid_object(SkipAst.Tclass((range, "Success"))),
Some(Positional(Array[(range, SkipAst.Pat_var((range, "__x")))])),
Some(Positional(Array[(range, SkipAst.Pat_var((range, "!x")))])),
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this now using "!x" as an identifier? surprising that we allow that! Or is this conversion pass already downstream of where that gets checked?

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.

Segfault/incorrect results for overlapping patterns with underscore-prefixed variables

2 participants