Skip to content

Commit

Permalink
Forget remembered specific type when entering arrow function with sam…
Browse files Browse the repository at this point in the history
…e-named parameter
  • Loading branch information
ondrejmirtes committed Feb 1, 2022
1 parent cd289bd commit af38f03
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Analyser/MutatingScope.php
Expand Up @@ -3677,6 +3677,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
$variableTypes = $this->variableTypes;
$mixed = new MixedType();
$parameterVariables = [];
$parameterVariableExpressions = [];
foreach ($arrowFunction->params as $i => $parameter) {
if ($parameter->type === null) {
$parameterType = $mixed;
Expand Down Expand Up @@ -3706,6 +3707,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu

$variableTypes[$parameter->var->name] = VariableTypeHolder::createYes($parameterType);
$parameterVariables[] = $parameter->var->name;
$parameterVariableExpressions[] = $parameter->var;
}

if ($arrowFunction->static) {
Expand Down Expand Up @@ -3767,7 +3769,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
}
}

return $this->scopeFactory->create(
$scope = $this->scopeFactory->create(
$this->context,
$this->isDeclareStrictTypes(),
$this->constantTypes,
Expand All @@ -3785,6 +3787,12 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
$this->afterExtractCall,
$this->parentScope,
);

foreach ($parameterVariableExpressions as $expr) {
$scope = $scope->invalidateExpression($expr);
}

return $scope;
}

public function isParameterValueNullable(Node\Param $parameter): bool
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -684,6 +684,7 @@ public function dataFileAsserts(): iterable
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6500.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-6473.php');
}

/**
Expand Down
Expand Up @@ -113,4 +113,10 @@ public function testTreatPhpDocTypesAsCertainRegression(bool $treatPhpDocTypesAs
$this->analyse([__DIR__ . '/../DeadCode/data/bug-without-issue-1.php'], []);
}

public function testBug6473(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/bug-6473.php'], []);
}

}
48 changes: 48 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/bug-6473.php
@@ -0,0 +1,48 @@
<?php

namespace Bug6473;

use function PHPStan\Testing\assertType;

class Point {
public bool $visited = false;

/**
* @return Point[]
*/
public function getNeighbours(): array {
return [ new Point ];
}

public function doFoo()
{
$seen = [];

foreach([new Point, new Point] as $p ) {

$p->visited = true;
assertType('true', $p->visited);
$seen = [
... $seen,
... array_filter( $p->getNeighbours(), static fn (Point $p) => !$p->visited )
];
assertType('true', $p->visited);
}
}

public function doFoo2()
{
$seen = [];

foreach([new Point, new Point] as $p ) {

$p->visited = true;
assertType('true', $p->visited);
$seen = [
... $seen,
... array_filter( $p->getNeighbours(), static fn (Point $p2) => !$p2->visited )
];
assertType('true', $p->visited);
}
}
}

0 comments on commit af38f03

Please sign in to comment.