Skip to content

Commit f407ac6

Browse files
committed
Filter right side of null coalesce assign with === null
1 parent adbc35a commit f407ac6

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

src/Analyser/NodeScopeResolver.php

+22-1
Original file line numberDiff line numberDiff line change
@@ -1932,7 +1932,28 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
19321932
$expr,
19331933
$nodeCallback,
19341934
$context,
1935-
fn (MutatingScope $scope): ExpressionResult => $this->processExprNode($expr->expr, $scope, $nodeCallback, $context->enterDeep()),
1935+
function (MutatingScope $scope) use ($expr, $nodeCallback, $context): ExpressionResult {
1936+
$originalScope = $scope;
1937+
if ($expr instanceof Expr\AssignOp\Coalesce) {
1938+
$scope = $scope->filterByFalseyValue(
1939+
new BinaryOp\NotIdentical($expr->var, new ConstFetch(new Name('null'))),
1940+
);
1941+
}
1942+
1943+
$result = $this->processExprNode($expr->expr, $scope, $nodeCallback, $context->enterDeep());
1944+
if ($expr instanceof Expr\AssignOp\Coalesce) {
1945+
return new ExpressionResult(
1946+
$result->getScope()->mergeWith(
1947+
$this->processExprNode($expr->expr, $originalScope, static function (): void {
1948+
}, $context->enterDeep())->getScope(),
1949+
),
1950+
$result->hasYield(),
1951+
$result->getThrowPoints(),
1952+
);
1953+
}
1954+
1955+
return $result;
1956+
},
19361957
$expr instanceof Expr\AssignOp\Coalesce,
19371958
);
19381959
$scope = $result->getScope();

tests/PHPStan/Rules/Classes/InstantiationRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -456,4 +456,9 @@ public function testBug7574(): void
456456
$this->analyse([__DIR__ . '/data/bug-7574.php'], []);
457457
}
458458

459+
public function testBug9946(): void
460+
{
461+
$this->analyse([__DIR__ . '/data/bug-9946.php'], []);
462+
}
463+
459464
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Bug9946;
4+
5+
class Foo
6+
{
7+
8+
function test(?\DateTimeImmutable $a, ?string $b): string
9+
{
10+
if (!$a && !$b) {
11+
throw new \LogicException('Either a or b MUST be set');
12+
}
13+
if (!$a) {
14+
$c = new \DateTimeImmutable($b);
15+
}
16+
$a ??= new \DateTimeImmutable($b);
17+
18+
return $a->format('c');
19+
}
20+
21+
}

0 commit comments

Comments
 (0)