Skip to content

Commit

Permalink
Fix defining variables in match condition
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 21, 2023
1 parent f6e65bd commit d6c2752
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -3099,6 +3099,9 @@ public function enterMatch(Expr\Match_ $expr): self
if ($expr->cond instanceof Variable) {
return $this;
}
if ($expr->cond instanceof AlwaysRememberedExpr) {
return $this;
}

$type = $this->getType($expr->cond);
$nativeType = $this->getNativeType($expr->cond);
Expand Down
6 changes: 6 additions & 0 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
use PHPStan\Node\ClosureReturnStatementsNode;
use PHPStan\Node\DoWhileLoopConditionNode;
use PHPStan\Node\ExecutionEndNode;
use PHPStan\Node\Expr\AlwaysRememberedExpr;
use PHPStan\Node\Expr\GetIterableKeyTypeExpr;
use PHPStan\Node\Expr\GetIterableValueTypeExpr;
use PHPStan\Node\Expr\GetOffsetValueTypeExpr;
Expand Down Expand Up @@ -2772,6 +2773,11 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
}

$nodeCallback(new MatchExpressionNode($expr->cond, $armNodes, $expr, $matchScope), $scope);
} elseif ($expr instanceof AlwaysRememberedExpr) {
$result = $this->processExprNode($expr->getExpr(), $scope, $nodeCallback, $context);
$hasYield = $result->hasYield();
$throwPoints = $result->getThrowPoints();
$scope = $result->getScope();
} elseif ($expr instanceof Expr\Throw_) {
$hasYield = false;
$result = $this->processExprNode($expr->expr, $scope, $nodeCallback, ExpressionContext::createDeep());
Expand Down
9 changes: 9 additions & 0 deletions tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -954,4 +954,13 @@ public function testBug393(): void
$this->analyse([__DIR__ . '/data/bug-393.php'], []);
}

public function testBug9474(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = true;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;
$this->analyse([__DIR__ . '/data/bug-9474.php'], []);
}

}
22 changes: 22 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-9474.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Bug9474;

class GlazedTerracotta{
public function getColor() : int{ return 1; }
}

class HelloWorld
{
public function sayHello(): void
{
var_dump((function(GlazedTerracotta $block) : int{
$i = match($color = $block->getColor()){
1 => 1,
default => throw new \Exception("Unhandled dye colour " . $color)
};
echo $color;
return $i;
})(new GlazedTerracotta));
}
}

0 comments on commit d6c2752

Please sign in to comment.