Skip to content

Commit

Permalink
Fix regression in for loop
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Dec 16, 2022
1 parent 2a61ebc commit a8975b1
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
11 changes: 4 additions & 7 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,6 @@ private function processStmtNode(
$bodyScope = $this->enterForeach($bodyScope, $stmt);
$bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function (): void {
}, $context->enterDeep())->filterOutLoopExitPoints();
$alwaysTerminating = $bodyScopeResult->isAlwaysTerminating();
$bodyScope = $bodyScopeResult->getScope();
foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) {
$bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope());
Expand All @@ -848,7 +847,7 @@ private function processStmtNode(
$bodyScope = $prevScope->generalizeWith($bodyScope);
}
$count++;
} while (!$alwaysTerminating && $count < self::LOOP_SCOPE_ITERATIONS);
} while ($count < self::LOOP_SCOPE_ITERATIONS);
}

$bodyScope = $bodyScope->mergeWith($this->polluteScopeWithAlwaysIterableForeach ? $scope->filterByTruthyValue($arrayComparisonExpr) : $scope);
Expand Down Expand Up @@ -904,7 +903,6 @@ private function processStmtNode(
}, ExpressionContext::createDeep())->getTruthyScope();
$bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function (): void {
}, $context->enterDeep())->filterOutLoopExitPoints();
$alwaysTerminating = $bodyScopeResult->isAlwaysTerminating();
$bodyScope = $bodyScopeResult->getScope();
foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) {
$bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope());
Expand All @@ -917,7 +915,7 @@ private function processStmtNode(
$bodyScope = $prevScope->generalizeWith($bodyScope);
}
$count++;
} while (!$alwaysTerminating && $count < self::LOOP_SCOPE_ITERATIONS);
} while ($count < self::LOOP_SCOPE_ITERATIONS);
}

$bodyScope = $bodyScope->mergeWith($scope);
Expand Down Expand Up @@ -999,7 +997,7 @@ private function processStmtNode(
$bodyScope = $prevScope->generalizeWith($bodyScope);
}
$count++;
} while (!$alwaysTerminating && $count < self::LOOP_SCOPE_ITERATIONS);
} while ($count < self::LOOP_SCOPE_ITERATIONS);

$bodyScope = $bodyScope->mergeWith($scope);
}
Expand Down Expand Up @@ -1082,7 +1080,6 @@ private function processStmtNode(
}
$bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function (): void {
}, $context->enterDeep())->filterOutLoopExitPoints();
$alwaysTerminating = $bodyScopeResult->isAlwaysTerminating();
$bodyScope = $bodyScopeResult->getScope();
foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) {
$bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope());
Expand All @@ -1103,7 +1100,7 @@ private function processStmtNode(
$bodyScope = $prevScope->generalizeWith($bodyScope);
}
$count++;
} while (!$alwaysTerminating && $count < self::LOOP_SCOPE_ITERATIONS);
} while ($count < self::LOOP_SCOPE_ITERATIONS);
}

$bodyScope = $bodyScope->mergeWith($initScope);
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-82.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4565.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-3789.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-8520.php');
}

/**
Expand Down
15 changes: 15 additions & 0 deletions tests/PHPStan/Analyser/data/bug-8520.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Bug8520;

use function PHPStan\Testing\assertType;

for ($i = 0; $i < 7; $i++) {
assertType('int<0, 6>', $i);
$tryMax = true;
while ($tryMax) {
$tryMax = false;
}
}

assertType('int<7, max>', $i);

0 comments on commit a8975b1

Please sign in to comment.