fix(parser): join multi-element subscripts with $; in chained hash deref#556
Closed
fix(parser): join multi-element subscripts with $; in chained hash deref#556
Conversation
Previously, chained hash access like $h{a}{-word => 'ou'} (implicit
arrow deref) evaluated the multi-element subscript in scalar context,
keeping only the last element ('ou'). The initial (non-deref) level
already joined keys with $; (SUBSEP) to form 'a$;b'-style keys, so the
two paths disagreed:
$h{-word => 'ou'} -> FETCH("-word\x1cou") OK
$h{a}{-word => 'ou'} -> FETCH("ou") BUG
Fix: in handleArrowHashDeref, when the HashLiteralNode subscript has
more than one element, emit it as a list and join with $; just like
the top-level case does.
Found while investigating `jcpan -t Regexp::Common`. Regexp::Common's
FETCH-chaining tied hash relies on this semantic (e.g.
$RE{list}{conj}{-word => 'ou'}). With the fix:
- Failed test files: 22/73 -> 11/73
- Completed tests: 116146 -> 140752 (previously aborted tests
such as t/test_list.t, t/URI/http.t, t/number/decimal.t,
t/zip/us.t now run to completion)
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Owner
Author
|
Superseded by #555 — that PR now includes this commit. |
Merged
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a bug where chained hash dereference with multi-element subscripts kept only the last element instead of joining with
$;(SUBSEP).Under the hood,
$h{a}{b}goes throughhandleArrowHashDeref(implicit arrow deref). That path evaluated the subscript list in scalar context, which drops all but the last element. The non-deref top-level path already joined multi-element subscripts with$;, so the two disagreed.Fix: in
handleArrowHashDeref, when theHashLiteralNodehas more than one element, emit it as a list andjoin($;, ...), matching the top-level case.Discovery
Found while investigating
jcpan -t Regexp::Common. Its tied hash chains FETCH calls, and patterns like$RE{list}{conj}{-word => 'ou'}rely on-wordreaching FETCH.Test plan
make(full unit test suite) passesRegexp::Commontest suite improves from 22/73 failed test files to 11/73; completed subtests jump from 116,146 to 140,752 as previously-aborted files (t/test_list.t,t/URI/http.t,t/number/decimal.t,t/zip/us.t, etc.) now run to completiont/test_list.tin Regexp::Common: 50/50 pass (was aborting at test 33)Repro
Before: last FETCH reported
len=2. After:len=8, matching real Perl.Generated with Devin