Skip to content

fix(lower): #6143 — unresolvable object shorthand throws ReferenceError (was silently dropped)#6144

Merged
proggeramlug merged 1 commit into
mainfrom
fix/6142-shorthand-ref.error
Jul 8, 2026
Merged

fix(lower): #6143 — unresolvable object shorthand throws ReferenceError (was silently dropped)#6144
proggeramlug merged 1 commit into
mainfrom
fix/6142-shorthand-ref.error

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #6143. const o = { undeclaredName } must throw ReferenceError: undeclaredName is not defined (a shorthand reads its binding). Perry's object-literal lowering instead did continue, silently dropping the property, in both legacy handlers (non-spread + spread). The closed-shape fast path bails to those on an unresolvable shorthand, so { undeclaredName } produced an empty object.

Fix

Lower the unresolvable shorthand as a normal identifier read (lower_expr(Ident)) — which throws for a truly-undeclared name and reads a sloppy implicit global if one exists.

Validation (vs Node)

Now throw ReferenceError: { a, undeclaredZZZ, b }, { ...{x:1}, undeclaredYYY }, { undeclaredXYZ }.
Unchanged: {a,b}{"a":1,"b":2}, {a, fn: fn()}, spread {...{a}, b}, sloppy implicit global g=5; {g}{"g":5}.

Summary by CodeRabbit

  • Bug Fixes
    • Object literal shorthand properties that can’t be resolved now behave like normal identifier reads instead of being skipped.
    • In cases with spreads, computed keys, methods, accessors, or prototype setters, undeclared shorthand names now surface a runtime ReferenceError rather than disappearing.
    • The same fix applies to computed-key handling after object initialization, making shorthand behavior more consistent and predictable.

…renceError (was silently dropped)

`const o = { undeclaredName }` must throw `ReferenceError: undeclaredName is not
defined` — the shorthand reads the binding. Perry's object-literal lowering
instead did `continue`, silently dropping the property, in both legacy handlers
(non-spread and spread). The closed-shape fast path already bails to these on an
unresolvable shorthand, so `{ undeclaredName }` produced an empty object.

Fix: lower the unresolvable shorthand as a normal identifier read
(`lower_expr(Ident)`), which throws for a truly-undeclared name and reads a
sloppy implicit global when one was assigned.

Validated vs Node: `{ undeclaredZZZ }` and `{ ...{x:1}, undeclaredYYY }` now throw
ReferenceError; resolvable shorthands (`{a,b}`, `{a, fn: fn()}`), spreads
(`{...{a}, b}`), and sloppy implicit globals (`g=5; {g}`) are unchanged.
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cf308837-a2ad-4c62-acdc-c181f9109a01

📥 Commits

Reviewing files that changed from the base of the PR and between 74628ed and 32e44bd.

📒 Files selected for processing (1)
  • crates/perry-hir/src/lower/expr_object.rs

📝 Walkthrough

Walkthrough

In object literal lowering, unresolvable shorthand properties in both the spread/IIFE path and the computed-key post-init path now lower to an identifier read via lower_expr instead of being skipped with continue, enabling ReferenceError for undeclared names.

Changes

Object literal shorthand lowering fix

Layer / File(s) Summary
Lower unresolvable shorthand as identifier read
crates/perry-hir/src/lower/expr_object.rs
Both the spread/IIFE shorthand path and the computed-key post-init shorthand path now lower unresolvable shorthand properties via lower_expr on an Ident expression instead of using continue to drop them, producing a ReferenceError for truly undeclared names.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • PerryTS/perry#5244: Both PRs modify the same object-literal shorthand handling in crates/perry-hir/src/lower/expr_object.rs, changing dropped shorthand properties to be lowered/resolved via lower_expr.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix for unresolvable object shorthand lowering.
Description check ✅ Passed The description includes a summary, fix details, and validation, and is mostly aligned with the required template.
Linked Issues check ✅ Passed The change matches #6143 by lowering unresolvable shorthands as identifier reads in both legacy object-literal paths.
Out of Scope Changes check ✅ Passed The summary shows only the targeted object-literal lowering fix with no unrelated scope added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/6142-shorthand-ref.error

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug proggeramlug merged commit 7159c2a into main Jul 8, 2026
23 of 24 checks passed
@proggeramlug proggeramlug deleted the fix/6142-shorthand-ref.error branch July 8, 2026 19:50
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.

Unresolvable shorthand in object literal silently dropped instead of throwing ReferenceError

1 participant