Skip to content

Commit a39518e

Browse files
phpstan-botclaude
andcommitted
Remove redundant phpVersion check and add union type tests
The phpVersion->throwsOnStringCast() check is unnecessary because the toString resolution already handles the PHP version gate internally. Also adds regression tests for echo on union types (int|Foo, int|Bar, int|Baz) as requested in review. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 546a487 commit a39518e

File tree

3 files changed

+43
-16
lines changed

3 files changed

+43
-16
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@
110110
use PHPStan\Parser\ImmediatelyInvokedClosureVisitor;
111111
use PHPStan\Parser\LineAttributesVisitor;
112112
use PHPStan\Parser\Parser;
113-
use PHPStan\Php\PhpVersion;
114113
use PHPStan\PhpDoc\PhpDocInheritanceResolver;
115114
use PHPStan\PhpDoc\ResolvedPhpDocBlock;
116115
use PHPStan\PhpDoc\Tag\VarTag;
@@ -863,24 +862,21 @@ public function processStmtNode(
863862
$hasYield = false;
864863
$throwPoints = [];
865864
$isAlwaysTerminating = false;
866-
$phpVersion = $this->container->getByType(PhpVersion::class);
867865
foreach ($stmt->exprs as $echoExpr) {
868866
$result = $this->processExprNode($stmt, $echoExpr, $scope, $storage, $nodeCallback, ExpressionContext::createDeep());
869867
$throwPoints = array_merge($throwPoints, $result->getThrowPoints());
870-
if ($phpVersion->throwsOnStringCast()) {
871-
$exprType = $scope->getType($echoExpr);
872-
$toStringMethod = $scope->getMethodReflection($exprType, '__toString');
873-
if ($toStringMethod !== null) {
874-
$toStringResult = $this->processExprNode(
875-
$stmt,
876-
new Expr\MethodCall($echoExpr, new Identifier('__toString')),
877-
$scope,
878-
new ExpressionResultStorage(),
879-
new NoopNodeCallback(),
880-
ExpressionContext::createDeep(),
881-
);
882-
$throwPoints = array_merge($throwPoints, $toStringResult->getThrowPoints());
883-
}
868+
$exprType = $scope->getType($echoExpr);
869+
$toStringMethod = $scope->getMethodReflection($exprType, '__toString');
870+
if ($toStringMethod !== null) {
871+
$toStringResult = $this->processExprNode(
872+
$stmt,
873+
new Expr\MethodCall($echoExpr, new Identifier('__toString')),
874+
$scope,
875+
new ExpressionResultStorage(),
876+
new NoopNodeCallback(),
877+
ExpressionContext::createDeep(),
878+
);
879+
$throwPoints = array_merge($throwPoints, $toStringResult->getThrowPoints());
884880
}
885881
$scope = $result->getScope();
886882
$hasYield = $hasYield || $result->hasYield();

tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,10 @@ public function testBug5952(): void
759759
'Dead catch - Exception is never thrown in the try block.',
760760
57,
761761
],
762+
[
763+
'Dead catch - Exception is never thrown in the try block.',
764+
84,
765+
],
762766
]);
763767
}
764768

tests/PHPStan/Rules/Exceptions/data/bug-5952.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,30 @@ public function __toString(): string
5757
} catch (\Exception $e) {
5858
echo "Should not be printed";
5959
}
60+
61+
/** @var int|Foo $intOrFoo */
62+
$intOrFoo = doFoo();
63+
64+
try {
65+
echo $intOrFoo;
66+
} catch (\Exception $e) {
67+
echo "Should be printed";
68+
}
69+
70+
/** @var int|Bar $intOrBar */
71+
$intOrBar = doFoo();
72+
73+
try {
74+
echo $intOrBar;
75+
} catch (\Exception $e) {
76+
echo "Should be printed";
77+
}
78+
79+
/** @var int|Baz $intOrBaz */
80+
$intOrBaz = doFoo();
81+
82+
try {
83+
echo $intOrBaz;
84+
} catch (\Exception $e) {
85+
echo "Should not be printed";
86+
}

0 commit comments

Comments
 (0)