Skip to content

Commit 56bfa4e

Browse files
committed
Merge branch 2.1.x into 2.2.x
2 parents 451ec8c + 14856da commit 56bfa4e

3 files changed

Lines changed: 102 additions & 0 deletions

File tree

src/Analyser/NodeScopeResolver.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,10 @@ public function processStmtNode(
12401240

12411241
if ($stmt->valueVar instanceof Variable) {
12421242
$this->callNodeCallback($nodeCallback, new VariableAssignNode($stmt->valueVar, new GetIterableValueTypeExpr($stmt->expr)), $originalScope, $storage);
1243+
} elseif ($stmt->valueVar instanceof List_) {
1244+
$virtualAssign = new Assign($stmt->valueVar, new GetIterableValueTypeExpr($stmt->expr));
1245+
$virtualAssign->setAttributes($stmt->valueVar->getAttributes());
1246+
$this->callNodeCallback($nodeCallback, $virtualAssign, $scope, $storage);
12431247
}
12441248

12451249
$originalStorage = $storage;

tests/PHPStan/Rules/Arrays/ArrayDestructuringRuleTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,40 @@ public function testBug14270(): void
6868
$this->analyse([__DIR__ . '/data/bug-14270.php'], []);
6969
}
7070

71+
public function testBug8075(): void
72+
{
73+
$this->analyse([__DIR__ . '/data/bug-8075.php'], [
74+
[
75+
'Offset \'b\' does not exist on array{a: 0}.',
76+
12,
77+
],
78+
[
79+
'Offset \'b\' does not exist on array{a: 0}.',
80+
14,
81+
],
82+
[
83+
'Offset \'b\' does not exist on array{a: 0}.',
84+
17,
85+
],
86+
[
87+
'Offset \'b\' does not exist on array{a: 0}.',
88+
24,
89+
],
90+
[
91+
'Offset \'missing\' does not exist on array{name: string, age: int}.',
92+
36,
93+
],
94+
[
95+
'Offset 2 does not exist on array{string, int}.',
96+
48,
97+
],
98+
[
99+
'Offset \'z\' does not exist on array{x: int, y: int}.',
100+
60,
101+
],
102+
]);
103+
}
104+
71105
#[RequiresPhp('>= 8.0.0')]
72106
public function testRuleWithNullsafeVariant(): void
73107
{
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Bug8075;
4+
5+
class Foo
6+
{
7+
8+
public function doFoo(): void
9+
{
10+
$arr = [['a' => 0]];
11+
12+
['b' => $val] = $arr[0]; // error - works
13+
14+
foreach ($arr as ['b' => $valueB]) { // error - should be reported
15+
}
16+
17+
foreach ($arr as ['b' => $valueB, 'a' => $valueA]) { // error on 'b'
18+
}
19+
20+
foreach ($arr as ['a' => $valueA]) { // no error - 'a' exists
21+
}
22+
23+
foreach ($arr as $item) {
24+
['b' => $valueB] = $item; // error - works
25+
}
26+
}
27+
28+
/**
29+
* @param array<int, array{name: string, age: int}> $people
30+
*/
31+
public function doBar(array $people): void
32+
{
33+
foreach ($people as ['name' => $name, 'age' => $age]) { // no error
34+
}
35+
36+
foreach ($people as ['name' => $name, 'missing' => $missing]) { // error on 'missing'
37+
}
38+
}
39+
40+
/**
41+
* @param list<array{0: string, 1: int}> $tuples
42+
*/
43+
public function doBaz(array $tuples): void
44+
{
45+
foreach ($tuples as [$first, $second]) { // no error
46+
}
47+
48+
foreach ($tuples as [$first, $second, $third]) { // error on offset 2
49+
}
50+
}
51+
52+
/**
53+
* @param list<array{a: array{x: int, y: int}}> $nested
54+
*/
55+
public function doNested(array $nested): void
56+
{
57+
foreach ($nested as ['a' => ['x' => $x, 'y' => $y]]) { // no error
58+
}
59+
60+
foreach ($nested as ['a' => ['x' => $x, 'z' => $z]]) { // error on 'z'
61+
}
62+
}
63+
64+
}

0 commit comments

Comments
 (0)