-
Notifications
You must be signed in to change notification settings - Fork 575
Narrow value type instead of unsetting key in ConstantArrayType::tryRemove for HasOffsetValueType
#5776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.2.x
Are you sure you want to change the base?
Narrow value type instead of unsetting key in ConstantArrayType::tryRemove for HasOffsetValueType
#5776
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6185,6 +6185,67 @@ public static function dataRemove(): array | |
| ArrayType::class, | ||
| 'array<0|string, mixed>', | ||
| ], | ||
| // HasOffsetValueType with partial value overlap — narrow value, keep key mandatory | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should/can these tests better be expressed as "nsrt" tests?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In another PR it was already asked, and there was no possible nsrt test since we never remove HasOffsetValueType yet
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I investigated the reviewer's suggestion thoroughly and concluded that no change is warranted — the tests cannot meaningfully be expressed as nsrt tests. Here's the evidence. What I checkedThe reviewer asked whether the 6 To find out, I temporarily instrumented the partial-overlap (
I also diffed several reproducers' output against the pre-fix Why nsrt tests don't fit hereReal-world array-offset value narrowing (the Consequences for the reviewer's suggestion:
The StateNo source or test changes; instrumentation removed; working tree clean. I'll relay this reasoning as the reply to staabm's comment in the follow-up step.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The working tree is clean and there is nothing to change here. AssessmentVincentLanglet's comment isn't a change request — it's a confirmation of the conclusion already reached on this thread:
This directly corroborates the investigation posted earlier on staabm's "should these be nsrt tests?" comment: the VincentLanglet adds the corroborating fact that this same question came up in another PR with the same answer. So both reviewers now independently agree there's no PHP snippet that would route through this code path, which means:
The Action takenNo source or test changes are warranted — the comment confirms the existing approach rather than requesting a change. Working tree is clean (last commit I'll relay this acknowledgement as the reply to VincentLanglet in the follow-up step.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
is this something planned for the future? or how did you find this problem in the first place? :)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The working tree is clean and there's nothing to change — this review comment is a question, not a change request, so there's no code to modify (and therefore nothing new to test). Here's the answer I'll relay to staabm: Good question! To be transparent about provenance: How it was found: This didn't come from a real-world reproducer — it came from issue phpstan/phpstan#14711, which is itself an audit-style observation about the type system rather than a bug report with a failing snippet. The issue notes that Is the path reachable today? Not from normal analysis — which is exactly what VincentLanglet meant by "we never remove Planned for the future? I don't have visibility into a specific roadmap item that will start removing In short: found by inspecting the |
||
| [ | ||
| new ConstantArrayType( | ||
| [new ConstantStringType('a')], | ||
| [new UnionType([new StringType(), new IntegerType()])], | ||
| ), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new IntegerType()), | ||
| ConstantArrayType::class, | ||
| 'array{a: string}', | ||
| ], | ||
| // HasOffsetValueType with partial value overlap — narrow value, keep key optional | ||
| [ | ||
| new ConstantArrayType( | ||
| [new ConstantStringType('a')], | ||
| [new UnionType([new StringType(), new IntegerType()])], | ||
| [0], | ||
| [0], | ||
| ), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new IntegerType()), | ||
| ConstantArrayType::class, | ||
| 'array{a?: string}', | ||
| ], | ||
| // HasOffsetValueType with full value overlap on optional key — remove key entirely | ||
| [ | ||
| new ConstantArrayType( | ||
| [new ConstantStringType('a')], | ||
| [new IntegerType()], | ||
| [0], | ||
| [0], | ||
| ), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new IntegerType()), | ||
| ConstantArrayType::class, | ||
| 'array{}', | ||
| ], | ||
| // HasOffsetValueType with partial value overlap — multi-key array | ||
| [ | ||
| new ConstantArrayType( | ||
| [new ConstantStringType('a'), new ConstantStringType('b')], | ||
| [new UnionType([new StringType(), new IntegerType()]), new StringType()], | ||
| ), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new IntegerType()), | ||
| ConstantArrayType::class, | ||
| 'array{a: string, b: string}', | ||
| ], | ||
| // HasOffsetValueType removing another HasOffsetValueType with same offset | ||
| [ | ||
| new HasOffsetValueType(new ConstantStringType('a'), new UnionType([new StringType(), new IntegerType()])), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new IntegerType()), | ||
| HasOffsetValueType::class, | ||
| 'hasOffsetValue(\'a\', string)', | ||
| ], | ||
| // HasOffsetValueType on IntersectionType — narrow value type through intersection | ||
| [ | ||
| new IntersectionType([ | ||
| new ArrayType(new MixedType(), new MixedType()), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new UnionType([new StringType(), new IntegerType()])), | ||
| ]), | ||
| new HasOffsetValueType(new ConstantStringType('a'), new IntegerType()), | ||
| IntersectionType::class, | ||
| 'non-empty-array&hasOffsetValue(\'a\', string)', | ||
| ], | ||
| ]; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.