-
Notifications
You must be signed in to change notification settings - Fork 569
Use position-specific getOffsetValueType() instead of getIterableValueType() when intersecting two ConstantArrayTypes
#5468
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
Changes from all commits
6d1350d
cb14884
7af188e
3ba8784
06925a8
1189a06
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 |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| <?php // lint >= 8.0 | ||
|
|
||
| namespace Bug11234; | ||
|
|
||
| use function PHPStan\Testing\assertType; | ||
|
|
||
| class Payload {} | ||
|
|
||
| /** @param array{0|1|2|3, int|Payload|string|null}&array{int, Payload} $x */ | ||
| function testIntersectConstantUnionWithInt(mixed $x): void | ||
| { | ||
| assertType('array{0|1|2|3, Bug11234\Payload}', $x); | ||
| } | ||
|
|
||
| /** @param array{int, Payload}&array{0|1|2|3, int|Payload|string|null} $x */ | ||
| function testIntersectConstantUnionWithIntReverse(mixed $x): void | ||
| { | ||
| assertType('array{0|1|2|3, Bug11234\Payload}', $x); | ||
| } | ||
|
|
||
| /** @param array{0|1|2|3, int|Payload|string|null}&array{0|1|2|3, Payload} $x */ | ||
| function testIntersectBothConstantUnion(mixed $x): void | ||
| { | ||
| assertType('array{0|1|2|3, Bug11234\Payload}', $x); | ||
| } | ||
|
|
||
| /** @param array{int, int|Payload|string|null}&array{int, Payload} $y */ | ||
|
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. I think we should also test with intersection types, like non-empty-string
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. Done. Added three new test cases addressing staabm's review:
There was also a prior remote commit that added a |
||
| function testIntersectPlainInt(mixed $y): void | ||
| { | ||
| assertType('array{int, Bug11234\Payload}', $y); | ||
| } | ||
|
|
||
| /** @param array{0|1, string|int, Payload|null}&array{int, string, Payload} $z */ | ||
| function testIntersectThreePositions(mixed $z): void | ||
| { | ||
| assertType('array{0|1, string, Bug11234\Payload}', $z); | ||
| } | ||
|
|
||
| /** @param array{'a'|'b', int|Payload|string|null}&array{string, Payload} $w */ | ||
| function testIntersectStringConstantUnion(mixed $w): void | ||
| { | ||
| assertType("array{'a'|'b', Bug11234\Payload}", $w); | ||
| } | ||
|
|
||
| /** @param array{0|1, int|string}&array{int, int, extra?: bool} $v */ | ||
| function testIntersectOptionalKey(mixed $v): void | ||
| { | ||
| assertType('array{0|1, int}', $v); | ||
| } | ||
|
|
||
| /** @param array{true|false, int|string}&array{bool, string} $u */ | ||
| function testIntersectBoolConstantUnion(mixed $u): void | ||
| { | ||
| assertType('array{bool, string}', $u); | ||
| } | ||
|
|
||
| /** @param array{int<0, 3>, int|Payload|string|null}&array{int, Payload} $x */ | ||
| function testIntersectIntRangeValue(mixed $x): void | ||
| { | ||
| assertType('array{int<0, 3>, Bug11234\Payload}', $x); | ||
| } | ||
|
|
||
| /** @param array{non-empty-string, int|Payload|string|null}&array{string, Payload} $x */ | ||
| function testIntersectNonEmptyStringValue(mixed $x): void | ||
| { | ||
| assertType('array{non-empty-string, Bug11234\Payload}', $x); | ||
| } | ||
|
|
||
| /** @param array{0|1|2|3, non-empty-string|int|null}&array{int, string} $x */ | ||
| function testIntersectNonEmptyStringInUnion(mixed $x): void | ||
| { | ||
| assertType('array{0|1|2|3, non-empty-string}', $x); | ||
| } | ||
|
|
||
| /** @param array{0|1|2|3, string|null}&array{int, non-empty-string} $x */ | ||
| function testIntersectWithNonEmptyStringOtherSide(mixed $x): void | ||
| { | ||
| assertType('array{0|1|2|3, non-empty-string}', $x); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we test with a int-range as array-key?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I added two test cases to address staabm's review comments:
testIntersectIntRangeValue— Tests withint<0, 3>(integer range) as a value type at position 0, verifying thatarray{int<0, 3>, int|Payload|string|null} & array{int, Payload}correctly yieldsarray{int<0, 3>, Payload}.testIntersectNonEmptyStringValue— Tests withnon-empty-string(an intersection/accessory type) as a value type at position 0, verifying thatarray{non-empty-string, int|Payload|string|null} & array{string, Payload}correctly yieldsarray{non-empty-string, Payload}.All 11859 tests pass (79369 assertions) and
make phpstanreports no errors.