Skip to content

Commit bffa064

Browse files
committed
Fix #4366 - possibly-undefined vars in finally block should not error
1 parent 9e3b069 commit bffa064

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ public static function analyze(
128128
foreach ($context->vars_in_scope as $var_id => $type) {
129129
if (!isset($try_context->vars_in_scope[$var_id])) {
130130
$try_context->vars_in_scope[$var_id] = clone $type;
131-
$try_context->vars_in_scope[$var_id]->from_docblock = true;
131+
132+
if (!$stmt->catches) {
133+
$context->vars_in_scope[$var_id]->possibly_undefined = true;
134+
$context->vars_in_scope[$var_id]->possibly_undefined_from_try = true;
135+
}
132136
} else {
133137
$try_context->vars_in_scope[$var_id] = Type::combineUnionTypes(
134138
$try_context->vars_in_scope[$var_id],
@@ -470,11 +474,13 @@ function ($fq_catch_class) use ($codebase): Type\Atomic {
470474
}
471475
}
472476

473-
foreach ($definitely_newly_assigned_var_ids as $var_id => $_) {
474-
if (isset($context->vars_in_scope[$var_id])) {
475-
$new_type = clone $context->vars_in_scope[$var_id];
476-
$new_type->possibly_undefined_from_try = false;
477-
$context->vars_in_scope[$var_id] = $new_type;
477+
if ($stmt->catches) {
478+
foreach ($definitely_newly_assigned_var_ids as $var_id => $_) {
479+
if (isset($context->vars_in_scope[$var_id])) {
480+
$new_type = clone $context->vars_in_scope[$var_id];
481+
$new_type->possibly_undefined_from_try = false;
482+
$context->vars_in_scope[$var_id] = $new_type;
483+
}
478484
}
479485
}
480486

tests/TryCatchTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,29 @@ public function handle(string $arg): string
391391
}
392392
}'
393393
],
394+
'finallyArgMaybeUndefined' => [
395+
'<?php
396+
class TestMe {
397+
private function startTransaction(): void {
398+
}
399+
400+
private function endTransaction(bool $commit): void {
401+
echo $commit ? "Committing" : "Rolling back";
402+
}
403+
404+
public function doWork(): void {
405+
$this->startTransaction();
406+
try {
407+
$this->workThatMayOrMayNotThrow();
408+
$success = true;
409+
} finally {
410+
$this->endTransaction($success ?? false);
411+
}
412+
}
413+
414+
private function workThatMayOrMayNotThrow(): void {}
415+
}'
416+
]
394417
];
395418
}
396419

0 commit comments

Comments
 (0)