Skip to content

fix: reject a compound assignment whose target is an optional - #1003

Merged
kacy merged 1 commit into
mainfrom
fix-compound-assign-optional
Aug 31, 2026
Merged

fix: reject a compound assignment whose target is an optional#1003
kacy merged 1 commit into
mainfrom
fix-compound-assign-optional

Conversation

@kacy

@kacy kacy commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Closes #998.

x += 3 on an Int? holding 5 answered 0, and nothing reported anything.

A compound assignment reads its target, applies an operator and writes it back, so an optional target has to be unwrapped first. The check ran two acceptances before it ever looked at the operator — one that accepts a value an optional target can be built from, one for collection literals. Both answer a plain assignment's question, and taking either skipped the numeric check entirely, leaving the operator to be emitted against the shell's address.

The symptom on the issue was a segfault on a none-valued target. The quieter and worse one is the case above: a held value reads back as zero, silently.

Those two acceptances now apply to = alone, so every compound form reaches the numeric check and reports E217: operator += requires numeric type, got optional.

Unwrapping and rewrapping instead would be a language decision rather than a fix, and not one this change should make on its own.

what was tested

An invalid-corpus case pins the rejection for both a held value and none. A golden covers what must keep working: compound assignment on integers and floats, and plain assignment into an optional — a different question, still allowed.

Regressions 430/430 on both compilers, colocated std tests 114/114, pithgen 150 seeds clean, leak gate flat, invalid corpus 70/70, both bootstrap seed checks, formatting clean, seed regenerated.

`x += 3` on an `Int?` holding 5 answered 0, and nothing reported anything.

A compound assignment reads its target, applies an operator and writes it back,
so an optional target has to be unwrapped first. The check ran two acceptances
before it looked at the operator: one that accepts a value an optional target
can be built from, and one for collection literals. Both are a plain
assignment's question, and taking either skipped the numeric check entirely, so
the operator was emitted against the shell's address.

The reported symptom was a segfault on a none-valued target. The quieter and
worse one is the case above, where a held value reads back as zero.

Those two acceptances now apply to `=` alone, which leaves every compound form
reaching the numeric check and reporting E217 against the optional. Unwrapping
and rewrapping instead would be a language decision rather than a fix, and it
is not one this change should make on its own.

## what was tested

An invalid-corpus case pins the rejection for a held value and for none. A
golden covers what must keep working: compound assignment on integers and
floats, and plain assignment into an optional, which is a different question
and still allowed.

Regressions 430/430 on both compilers, colocated std tests 114/114, pithgen 150
seeds clean, the leak gate flat, the invalid corpus 70/70, both bootstrap seed
checks, formatting clean, seed regenerated.
@kacy
kacy merged commit 453eca6 into main Aug 31, 2026
2 checks passed
@kacy
kacy deleted the fix-compound-assign-optional branch August 31, 2026 13:29
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.

compound assignment on an optional does pointer arithmetic on the shell

1 participant