File tree Expand file tree Collapse file tree 4 files changed +64
-1
lines changed Expand file tree Collapse file tree 4 files changed +64
-1
lines changed Original file line number Diff line number Diff line change @@ -3677,6 +3677,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
36773677$ variableTypes = $ this ->variableTypes ;
36783678$ mixed = new MixedType ();
36793679$ parameterVariables = [];
3680+ $ parameterVariableExpressions = [];
36803681foreach ($ arrowFunction ->params as $ i => $ parameter ) {
36813682if ($ parameter ->type === null ) {
36823683$ parameterType = $ mixed ;
@@ -3706,6 +3707,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
37063707
37073708$ variableTypes [$ parameter ->var ->name ] = VariableTypeHolder::createYes ($ parameterType );
37083709$ parameterVariables [] = $ parameter ->var ->name ;
3710+ $ parameterVariableExpressions [] = $ parameter ->var ;
37093711}
37103712
37113713if ($ arrowFunction ->static ) {
@@ -3767,7 +3769,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
37673769}
37683770}
37693771
3770- return $ this ->scopeFactory ->create (
3772+ $ scope = $ this ->scopeFactory ->create (
37713773$ this ->context ,
37723774$ this ->isDeclareStrictTypes (),
37733775$ this ->constantTypes ,
@@ -3785,6 +3787,12 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
37853787$ this ->afterExtractCall ,
37863788$ this ->parentScope ,
37873789);
3790+
3791+ foreach ($ parameterVariableExpressions as $ expr ) {
3792+ $ scope = $ scope ->invalidateExpression ($ expr );
3793+ }
3794+
3795+ return $ scope ;
37883796}
37893797
37903798public function isParameterValueNullable (Node \Param $ parameter ): bool
Original file line number Diff line number Diff line change @@ -684,6 +684,7 @@ public function dataFileAsserts(): iterable
684684}
685685
686686yield from $ this ->gatherAssertTypes (__DIR__ . '/data/bug-6500.php ' );
687+ yield from $ this ->gatherAssertTypes (__DIR__ . '/../Rules/Comparison/data/bug-6473.php ' );
687688}
688689
689690/**
Original file line number Diff line number Diff line change @@ -113,4 +113,10 @@ public function testTreatPhpDocTypesAsCertainRegression(bool $treatPhpDocTypesAs
113113$ this ->analyse ([__DIR__ . '/../DeadCode/data/bug-without-issue-1.php ' ], []);
114114}
115115
116+ public function testBug6473 (): void
117+ {
118+ $ this ->treatPhpDocTypesAsCertain = true ;
119+ $ this ->analyse ([__DIR__ . '/data/bug-6473.php ' ], []);
120+ }
121+
116122}
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace Bug6473 ;
4+
5+ use function PHPStan \Testing \assertType ;
6+
7+ class Point {
8+ public bool $ visited = false ;
9+
10+ /**
11+ * @return Point[]
12+ */
13+ public function getNeighbours (): array {
14+ return [ new Point ];
15+ }
16+
17+ public function doFoo ()
18+ {
19+ $ seen = [];
20+
21+ foreach ([new Point , new Point ] as $ p ) {
22+
23+ $ p ->visited = true ;
24+ assertType ('true ' , $ p ->visited );
25+ $ seen = [
26+ ... $ seen ,
27+ ... array_filter ( $ p ->getNeighbours (), static fn (Point $ p ) => !$ p ->visited )
28+ ];
29+ assertType ('true ' , $ p ->visited );
30+ }
31+ }
32+
33+ public function doFoo2 ()
34+ {
35+ $ seen = [];
36+
37+ foreach ([new Point , new Point ] as $ p ) {
38+
39+ $ p ->visited = true ;
40+ assertType ('true ' , $ p ->visited );
41+ $ seen = [
42+ ... $ seen ,
43+ ... array_filter ( $ p ->getNeighbours (), static fn (Point $ p2 ) => !$ p2 ->visited )
44+ ];
45+ assertType ('true ' , $ p ->visited );
46+ }
47+ }
48+ }
You can’t perform that action at this time.
0 commit comments