Skip to content

Commit b3547b6

Browse files
ondrejmirtesclaude
andcommitted
Do not preserve conditional holders for unresolved expressions
An ErrorType consequent (e.g. an access to an undefined property) is a subtype of everything, so it looked "already satisfied" and its holder was preserved across the merge. Applying it tracked the expression and hid the underlying error - a false negative on undefined-property access. Skip holders whose consequent or other-branch state is an ErrorType, and use early exit in the preservation loop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGhnJQpUWRRpg6H5LuWJkA
1 parent ad96bf8 commit b3547b6

1 file changed

Lines changed: 17 additions & 5 deletions

File tree

‎src/Analyser/MutatingScope.php‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4559,12 +4559,24 @@ private function preserveVacuousConditionalExpressions(
45594559

45604560
$otherTargetHolder = $otherExpressionTypes[$exprString];
45614561
$otherTargetCertainty = $otherTargetHolder->getCertainty();
4562-
if (
4563-
($otherTargetCertainty->yes() || $otherTargetCertainty->equals($typeHolder->getCertainty()))
4564-
&& $typeHolder->getType()->isSuperTypeOf($otherTargetHolder->getType())->yes()
4565-
) {
4566-
$currentConditionalExpressions[$exprString][$key] = $holder;
4562+
if (!$otherTargetCertainty->yes() && !$otherTargetCertainty->equals($typeHolder->getCertainty())) {
4563+
continue;
4564+
}
4565+
4566+
// An unresolved expression (e.g. an access to an undefined property) is held
4567+
// as ErrorType. ErrorType is a subtype of everything, so a consequent or an
4568+
// other-branch state of ErrorType would look "already satisfied" and preserve
4569+
// a holder that tracks the expression and hides the underlying error. Such a
4570+
// holder carries no real type relationship, so skip it.
4571+
if ($typeHolder->getType() instanceof ErrorType || $otherTargetHolder->getType() instanceof ErrorType) {
4572+
continue;
45674573
}
4574+
4575+
if (!$typeHolder->getType()->isSuperTypeOf($otherTargetHolder->getType())->yes()) {
4576+
continue;
4577+
}
4578+
4579+
$currentConditionalExpressions[$exprString][$key] = $holder;
45684580
}
45694581
}
45704582

0 commit comments

Comments
 (0)