Skip to content

Commit fcd7604

Browse files
committed
remember list offset-values with constant union keys
1 parent c5a61d6 commit fcd7604

File tree

4 files changed

+28
-14
lines changed

4 files changed

+28
-14
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ parameters:
3333
-
3434
message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantStringType is error\-prone and deprecated\. Use Type\:\:getConstantStrings\(\) instead\.$#'
3535
identifier: phpstanApi.instanceofType
36-
count: 3
36+
count: 2
3737
path: src/Analyser/MutatingScope.php
3838

3939
-
@@ -48,12 +48,6 @@ parameters:
4848
count: 2
4949
path: src/Analyser/NodeScopeResolver.php
5050

51-
-
52-
message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantStringType is error\-prone and deprecated\. Use Type\:\:getConstantStrings\(\) instead\.$#'
53-
identifier: phpstanApi.instanceofType
54-
count: 1
55-
path: src/Analyser/NodeScopeResolver.php
56-
5751
-
5852
message: '#^Parameter \#2 \$node of method PHPStan\\BetterReflection\\SourceLocator\\Ast\\Strategy\\NodeToReflection\:\:__invoke\(\) expects PhpParser\\Node\\Expr\\ArrowFunction\|PhpParser\\Node\\Expr\\Closure\|PhpParser\\Node\\Expr\\FuncCall\|PhpParser\\Node\\Stmt\\Class_\|PhpParser\\Node\\Stmt\\Const_\|PhpParser\\Node\\Stmt\\Enum_\|PhpParser\\Node\\Stmt\\Function_\|PhpParser\\Node\\Stmt\\Interface_\|PhpParser\\Node\\Stmt\\Trait_, PhpParser\\Node\\Stmt\\ClassLike given\.$#'
5953
identifier: argument.type

src/Analyser/MutatingScope.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4236,12 +4236,14 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType,
42364236
if (!$exprVarType instanceof MixedType && !$exprVarType->isArray()->no()) {
42374237
$hasOffsets = [];
42384238
$containsInteger = false;
4239-
foreach($dimTypes as $dimType) {
4239+
foreach ($dimTypes as $dimType) {
42404240
$hasOffsets[] = new HasOffsetValueType($dimType, $type);
42414241

4242-
if ($dimType instanceof ConstantIntegerType) {
4243-
$containsInteger = true;
4242+
if (!($dimType instanceof ConstantIntegerType)) {
4243+
continue;
42444244
}
4245+
4246+
$containsInteger = true;
42454247
}
42464248

42474249
$types = [

src/Analyser/NodeScopeResolver.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@
171171
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
172172
use PHPStan\Type\Constant\ConstantBooleanType;
173173
use PHPStan\Type\Constant\ConstantIntegerType;
174-
use PHPStan\Type\Constant\ConstantStringType;
175174
use PHPStan\Type\ErrorType;
176175
use PHPStan\Type\FileTypeMapper;
177176
use PHPStan\Type\GeneralizePrecision;
@@ -6053,15 +6052,19 @@ private function produceArrayDimFetchAssignValueToWrite(array $dimFetchStack, ar
60536052
&& $scope->hasExpressionType($arrayDimFetch)->yes()
60546053
) {
60556054
$hasOffsetType = null;
6056-
if ($offsetType instanceof ConstantStringType || $offsetType instanceof ConstantIntegerType) {
6057-
$hasOffsetType = new HasOffsetValueType($offsetType, $valueToWrite);
6055+
$offsetConstantArrayKeys = $offsetType->getConstantArrayKeys();
6056+
if ($offsetConstantArrayKeys !== []) {
6057+
$hasOffsetType = [];
6058+
foreach ($offsetConstantArrayKeys as $constantArrayKey) {
6059+
$hasOffsetType[] = new HasOffsetValueType($constantArrayKey, $valueToWrite);
6060+
}
60586061
}
60596062
$valueToWrite = $offsetValueType->setExistingOffsetValueType($offsetType, $valueToWrite);
60606063

60616064
if ($hasOffsetType !== null) {
60626065
$valueToWrite = TypeCombinator::intersect(
60636066
$valueToWrite,
6064-
$hasOffsetType,
6067+
...$hasOffsetType,
60656068
);
60666069
} elseif ($valueToWrite->isArray()->yes()) {
60676070
$valueToWrite = TypeCombinator::intersect(

tests/PHPStan/Rules/Methods/data/bug-12927.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,19 @@ public function sayFooBar(array $list): void
6060
}
6161
assertType('array<string, string>', $list[$k]);
6262
}
63+
64+
/**
65+
* @param list<array<string, string>> $list
66+
* @param 'ab'|'cd' $constUnion
67+
*/
68+
public function sayUnionFoo2(array $list, $constUnion): void
69+
{
70+
foreach($list as $k => $v) {
71+
$list[$k][$constUnion] = 'world';
72+
assertType("non-empty-list<non-empty-array<string, string>&hasOffsetValue('ab', 'world')&hasOffsetValue('cd', 'world')>", $list);
73+
assertType("non-empty-array<string, string>&hasOffsetValue('ab', 'world')&hasOffsetValue('cd', 'world')", $list[$k]);
74+
}
75+
assertType("list<non-empty-array<string, string>&hasOffsetValue('ab', 'world')&hasOffsetValue('cd', 'world')>", $list);
76+
}
77+
6378
}

0 commit comments

Comments
 (0)