Skip to content

Commit 6807620

Browse files
committed
Skip constant-array guards when creating conditional expressions for subtype-absorbed targets
- In MutatingScope::createConditionalExpressions(), a subtype-absorbed variable is kept as a conditional-expression *target* (since #5876) so it can be re-narrowed when its guard is re-asserted. Pairing such a target with a constant-array guard, however, never re-narrows anything: a constant array represents a unique literal value that is not re-asserted as a condition later. Those conditional expressions were pure cost — the downstream isSuperTypeOf() guard machinery (including the reverse check added in #5848) compared these potentially huge constant arrays on every branch merge during loop convergence. - Skip creating a conditional expression for a subtype-absorbed target when the guard's type is a constant array, avoiding both the holder creation and the expensive guard-selection comparisons. - Recovers the ~15% analysis-time regression on constant-array-heavy loop code (tests/bench/data/bug-10538.php) while preserving the #5876 inference improvement (bug-7948, bug-11281 remain green). - Verified the removed conditional expressions never produced a re-narrowing (a constant-array-guarded absorbed target already inferred the widened type both before and after the change), so behavior is unchanged — all 1671 NodeScopeResolver inference tests pass identically. - Probed broadening the skip to all targets (not just subtype-absorbed ones): it recovers even more time but breaks a legitimate re-narrowing that relies on a constant-array guard, so the skip is scoped to subtype-absorbed targets.
1 parent ef3fe97 commit 6807620

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

‎src/Analyser/MutatingScope.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,7 +3927,17 @@ private function createConditionalExpressions(
39273927
continue;
39283928
}
39293929

3930+
$exprIsGuardExcluded = array_key_exists($exprString, $guardsToExclude);
39303931
foreach ($variableTypeGuards as $guardExprString => $guardHolder) {
3932+
// A subtype-absorbed target (kept only for re-narrowing) paired with a
3933+
// constant-array guard never helps: such a guard represents a unique
3934+
// literal value that is not re-asserted as a condition later, yet the
3935+
// downstream isSuperTypeOf() guard machinery pays to compare these
3936+
// (potentially huge) constant arrays on every branch merge. Skip them.
3937+
if ($exprIsGuardExcluded && $guardHolder->getType()->isConstantArray()->yes()) {
3938+
continue;
3939+
}
3940+
39313941
if (
39323942
array_key_exists($guardExprString, $theirExpressionTypes)
39333943
&& $theirExpressionTypes[$guardExprString]->getCertainty()->yes()

0 commit comments

Comments
 (0)