Skip to content

Commit 54a204e

Browse files
committed
Throwable catch block also uses implicit throw points even when there are explicit ones
1 parent 088518f commit 54a204e

File tree

4 files changed

+87
-1
lines changed

4 files changed

+87
-1
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ private function processStmtNode(
11701170
$matchingThrowPoints = [];
11711171
$newThrowPoints = [];
11721172
foreach ($throwPoints as $throwPoint) {
1173-
if (!$throwPoint->isExplicit()) {
1173+
if (!$throwPoint->isExplicit() && !$catchType->isSuperTypeOf(new ObjectType(\Throwable::class))->yes()) {
11741174
continue;
11751175
}
11761176
$isSuperType = $catchType->isSuperTypeOf($throwPoint->getType());

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@ public function dataFileAsserts(): iterable
385385
yield from $this->gatherAssertTypes(__DIR__ . '/data/DateTimeDynamicReturnTypes.php');
386386
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4821.php');
387387
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4838.php');
388+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4879.php');
389+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4820.php');
388390
}
389391

390392
/**
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Bug4820;
4+
5+
use PHPStan\TrinaryLogic;
6+
use function PHPStan\Testing\assertType;
7+
use function PHPStan\Testing\assertVariableCertainty;
8+
9+
class Param {
10+
11+
public bool $foo;
12+
}
13+
14+
class HelloWorld
15+
{
16+
public function sayHello(Param $param): void
17+
{
18+
19+
try {
20+
$result = call_user_func([$this, 'mayThrow']);
21+
if ($param->foo) {
22+
$this->mayThrow();
23+
}
24+
25+
} catch (\Throwable $e) {
26+
assertType('bool', $param->foo);
27+
assertVariableCertainty(TrinaryLogic::createMaybe(), $result);
28+
throw $e;
29+
}
30+
}
31+
32+
/**
33+
* @throws \RuntimeException
34+
*/
35+
private function mayThrow(): void
36+
{
37+
throw new \RuntimeException();
38+
}
39+
40+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Bug4879;
4+
5+
use PHPStan\TrinaryLogic;
6+
use function PHPStan\Testing\assertVariableCertainty;
7+
8+
class HelloWorld
9+
{
10+
public function sayHello(bool $bool1): void
11+
{
12+
try {
13+
if ($bool1) {
14+
throw new \Exception();
15+
}
16+
17+
$var = 'foo';
18+
19+
$this->test();
20+
} catch (\Throwable $ex) {
21+
assertVariableCertainty(TrinaryLogic::createMaybe(), $var);
22+
}
23+
}
24+
25+
public function sayHello2(bool $bool1): void
26+
{
27+
try {
28+
if ($bool1) {
29+
throw new \Exception();
30+
}
31+
32+
$var = 'foo';
33+
34+
$this->test();
35+
} catch (\Exception $ex) {
36+
assertVariableCertainty(TrinaryLogic::createNo(), $var);
37+
}
38+
}
39+
40+
public function test(): void
41+
{
42+
return;
43+
}
44+
}

0 commit comments

Comments
 (0)