Skip to content

Commit 481303f

Browse files
committed
Merge branch '1.5.x' into 1.6.x
2 parents b6c1acb + 6b6f310 commit 481303f

File tree

4 files changed

+64
-3
lines changed

4 files changed

+64
-3
lines changed

src/Analyser/NodeScopeResolver.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,7 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
25612561
$matchScope = $scope;
25622562
$armNodes = [];
25632563
$hasDefaultCond = false;
2564+
$hasAlwaysTrueCond = false;
25642565
foreach ($expr->arms as $arm) {
25652566
if ($arm->conds === null) {
25662567
$hasDefaultCond = true;
@@ -2586,6 +2587,10 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
25862587
$hasYield = $hasYield || $armCondResult->hasYield();
25872588
$throwPoints = array_merge($throwPoints, $armCondResult->getThrowPoints());
25882589
$armCondExpr = new BinaryOp\Identical($expr->cond, $armCond);
2590+
$armCondType = $armCondResult->getScope()->getType($armCondExpr);
2591+
if ($armCondType instanceof ConstantBooleanType && $armCondType->getValue()) {
2592+
$hasAlwaysTrueCond = true;
2593+
}
25892594
$armCondScope = $armCondResult->getScope()->filterByFalseyValue($armCondExpr);
25902595
if ($filteringExpr === null) {
25912596
$filteringExpr = $armCondExpr;
@@ -2611,7 +2616,7 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
26112616
}
26122617

26132618
$remainingType = $matchScope->getType($expr->cond);
2614-
if (!$hasDefaultCond && !$remainingType instanceof NeverType) {
2619+
if (!$hasDefaultCond && !$hasAlwaysTrueCond && !$remainingType instanceof NeverType) {
26152620
$throwPoints[] = ThrowPoint::createExplicit($scope, new ObjectType(UnhandledMatchError::class), $expr, false);
26162621
}
26172622

src/Type/Constant/ConstantArrayType.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -758,8 +758,9 @@ public function describe(VerbosityLevel $level): string
758758
}
759759
}
760760

761-
$items[] = sprintf('%s%s: %s', $keyDescription, $isOptional ? '?' : '', $valueType->describe($level));
762-
$values[] = $valueType->describe($level);
761+
$valueTypeDescription = $valueType->describe($level);
762+
$items[] = sprintf('%s%s: %s', $keyDescription, $isOptional ? '?' : '', $valueTypeDescription);
763+
$values[] = $valueTypeDescription;
763764
}
764765

765766
$append = '';

tests/PHPStan/Rules/Exceptions/ThrowsVoidMethodWithExplicitThrowPointRuleTest.php

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
77
use ThrowsVoidMethod\MyException;
8+
use UnhandledMatchError;
9+
use const PHP_VERSION_ID;
810

911
/**
1012
* @extends RuleTestCase<ThrowsVoidMethodWithExplicitThrowPointRule>
@@ -96,4 +98,14 @@ public function testRule(bool $missingCheckedExceptionInThrows, array $checkedEx
9698
$this->analyse([__DIR__ . '/data/throws-void-method.php'], $errors);
9799
}
98100

101+
public function testBug6910(): void
102+
{
103+
if (PHP_VERSION_ID < 80000) {
104+
$this->markTestSkipped('Test requires PHP 8.0.');
105+
}
106+
$this->missingCheckedExceptionInThrows = false;
107+
$this->checkedExceptionClasses = [UnhandledMatchError::class];
108+
$this->analyse([__DIR__ . '/data/bug-6910.php'], []);
109+
}
110+
99111
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php declare(strict_types = 1); // lint >= 8.0
2+
3+
namespace Bug6910;
4+
5+
class RedFish {}
6+
7+
class BlueFish {}
8+
9+
class Net {
10+
public RedFish|BlueFish $heldFish;
11+
public int $prop;
12+
13+
/**
14+
* @throws void
15+
*/
16+
public function dropFish(): void {
17+
match ($this->heldFish instanceof RedFish) {
18+
true => 'hello',
19+
false => 'world',
20+
};
21+
}
22+
23+
/**
24+
* @throws void
25+
* @param 'hello'|'world' $string
26+
*/
27+
public function issetFish(string $string): void {
28+
match ($string === 'hello') {
29+
true => 'hello',
30+
false => 'world',
31+
};
32+
}
33+
34+
/**
35+
* @throws void
36+
*/
37+
public function anotherFish(bool $bool): void {
38+
match ($bool) {
39+
true => 'hello',
40+
false => 'world',
41+
};
42+
}
43+
}

0 commit comments

Comments
 (0)