Fix item-type in list to constant-array conversion with count()#3309
Fix item-type in list to constant-array conversion with count()#3309ondrejmirtes merged 11 commits intophpstan:1.11.xfrom
Conversation
1e63d51 to
afe2113
Compare
|
This pull request has been marked as ready for review. |
1133d1a to
7574911
Compare
src/Analyser/TypeSpecifier.php
Outdated
There was a problem hiding this comment.
What about doing intersect with HasOffsetType instead of the for loop?
There was a problem hiding this comment.
I tried using HasOffsetValueType but it still requires the loop
- $valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
+ $hasOffsetTypes = [];
for ($i = 0; $i < $constantType->getValue(); $i++) {
- $offsetType = new ConstantIntegerType($i);
- $valueTypesBuilder->setOffsetValueType($offsetType, $argType->getOffsetValueType($offsetType));
+ $hasOffsetTypes[] = new HasOffsetValueType(new ConstantIntegerType($i), $argType->getOffsetValueType(new ConstantIntegerType(
$i)));
}
- $valueTypes = $this->create($exprNode->getArgs()[0]->value, $valueTypesBuilder->getArray(), $context, false, $scope, $rootExpr);
+ $valueTypes = $this->create($exprNode->getArgs()[0]->value, TypeCombinator::intersect($argType, ...$hasOffsetTypes), $context, false,
$scope, $rootExpr);and it leads to less precise types, I think (at least less readable)
--- Expected
+++ Actual
@@ @@
-'array{ListCount\A, ListCount\A, ListCount\A}'
+'list<ListCount\A>&hasOffsetValue(0, ListCount\A)&hasOffsetValue(1, ListCount\A)&hasOffsetValue(2, ListCount\A)'
There was a problem hiding this comment.
to drop the loop we could maybe use new HasOffsetValueType(IntegerRangeType::fromInterval(0, $constantType->getValue(), $offsetValueType) but this doesn't work because $offsetValueType is different per offset
|
This pull request has been marked as ready for review. |
7574911 to
18d20a8
Compare
|
Conflict :) |
18d20a8 to
95d749e
Compare
|
This pull request has been marked as ready for review. |
| if ( | ||
| $isNormalCount->yes() | ||
| && $type->isList()->yes() | ||
| && $sizeType instanceof ConstantIntegerType |
There was a problem hiding this comment.
Note to future me: Misses int-range support?
|
Thank you! |
before this PR we were loosing precision in this process as item-types were kind of generalized before.
I guess the original implementation was done before
Type->getOffsetValueType()was a thing.