Skip to content

Commit e25dfea

Browse files
committed
it works, kinda
1 parent 61c91d5 commit e25dfea

File tree

3 files changed

+15
-12
lines changed

3 files changed

+15
-12
lines changed

src/Analyser/NodeScopeResolver.php

+9-11
Original file line numberDiff line numberDiff line change
@@ -5384,12 +5384,12 @@ private function processAssignVar(
53845384
}
53855385

53865386
if ($dimExpr === null) {
5387-
$offsetTypes[] = null;
5388-
$offsetNativeTypes[] = null;
5387+
$offsetTypes[] = [null, TrinaryLogic::createYes()];
5388+
$offsetNativeTypes[] = [null, TrinaryLogic::createYes()];
53895389

53905390
} else {
5391-
$offsetTypes[] = $scope->getType($dimExpr);
5392-
$offsetNativeTypes[] = $scope->getNativeType($dimExpr);
5391+
$offsetTypes[] = [$scope->getType($dimExpr), $scope->getType($dimFetch->var)->hasOffsetValueType($scope->getType($dimExpr))->or($scope->hasExpressionType($dimFetch))];
5392+
$offsetNativeTypes[] = [$scope->getNativeType($dimExpr), $scope->getNativeType($dimFetch->var)->hasOffsetValueType($scope->getNativeType($dimExpr))->or($scope->hasExpressionType($dimFetch))];
53935393

53945394
if ($enterExpressionAssign) {
53955395
$scope->enterExpressionAssign($dimExpr);
@@ -5436,8 +5436,8 @@ private function processAssignVar(
54365436
$nativeValueToWrite = $this->produceArrayDimFetchAssignValueToWrite($offsetNativeTypes, $offsetNativeValueType, $nativeValueToWrite);
54375437
} else {
54385438
$rewritten = false;
5439-
foreach ($offsetTypes as $i => $offsetType) {
5440-
$offsetNativeType = $offsetNativeTypes[$i];
5439+
foreach ($offsetTypes as $i => [$offsetType]) {
5440+
[$offsetNativeType] = $offsetNativeTypes[$i];
54415441
if ($offsetType === null) {
54425442
if ($offsetNativeType !== null) {
54435443
throw new ShouldNotHappenException();
@@ -5752,18 +5752,16 @@ static function (): void {
57525752
}
57535753

57545754
/**
5755-
* @param list<Type|null> $offsetTypes
5755+
* @param list<array{Type|null, TrinaryLogic}> $offsetTypes
57565756
*/
57575757
private function produceArrayDimFetchAssignValueToWrite(array $offsetTypes, Type $offsetValueType, Type $valueToWrite): Type
57585758
{
57595759
$offsetValueTypeStack = [[$offsetValueType, TrinaryLogic::createYes()]];
5760-
foreach (array_slice($offsetTypes, 0, -1) as $offsetType) {
5760+
foreach (array_slice($offsetTypes, 0, -1) as [$offsetType, $has]) {
57615761
if ($offsetType === null) {
5762-
$has = TrinaryLogic::createYes();
57635762
$offsetValueType = new ConstantArrayType([], []);
57645763

57655764
} else {
5766-
$has = $offsetValueType->hasOffsetValueType($offsetType);
57675765
$offsetValueType = $offsetValueType->getOffsetValueType($offsetType);
57685766
if ($offsetValueType instanceof ErrorType) {
57695767
$offsetValueType = new ConstantArrayType([], []);
@@ -5773,7 +5771,7 @@ private function produceArrayDimFetchAssignValueToWrite(array $offsetTypes, Type
57735771
$offsetValueTypeStack[] = [$offsetValueType, $has];
57745772
}
57755773

5776-
foreach (array_reverse($offsetTypes) as $i => $offsetType) {
5774+
foreach (array_reverse($offsetTypes) as $i => [$offsetType]) {
57775775
/** @var Type $offsetValueType */
57785776
[$offsetValueType, $has] = array_pop($offsetValueTypeStack);
57795777
if (

tests/PHPStan/Analyser/data/bug-10922.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function sayHello(array $array): void
1212
foreach ($array as $key => $item) {
1313
$array[$key]['bar'] = '';
1414
}
15-
assertType("array<string, array{foo: string, bar: ''}>", $array);
15+
assertType("array<string, array{foo: string, bar?: ''}>", $array);
1616
}
1717

1818
/** @param array<string, array{foo: string}> $array */

tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,11 @@ public function testBug6356b(): void
502502
26,
503503
"Offset 'age' (int) does not accept type int|string.",
504504
],
505+
[
506+
'Property Bug6356b\HelloWorld2::$nestedDetails (array<array{name: string, age: int}>) does not accept non-empty-array<array{age: \'Eleventy-one\'|\'Five\'|\'Twelve\'|int, name: string}>.',
507+
29,
508+
'Offset \'age\' (int) does not accept type int|string.',
509+
],
505510
]);
506511
}
507512

0 commit comments

Comments
 (0)