Skip to content

Commit 9c1f32e

Browse files
VincentLangletphpstan-bot
authored andcommitted
Fix #10422
1 parent 9c915ec commit 9c1f32e

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

src/Analyser/MutatingScope.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3210,6 +3210,7 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
32103210

32113211
$conditions = [];
32123212
$prevSpecifiedCount = -1;
3213+
$debugFile = getenv('PHPSTAN_DEBUG_FILTER') ?: '';
32133214
while (count($specifiedExpressions) !== $prevSpecifiedCount) {
32143215
$prevSpecifiedCount = count($specifiedExpressions);
32153216
foreach ($scope->conditionalExpressions as $conditionalExprString => $conditionalExpressions) {
@@ -3218,11 +3219,31 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
32183219
}
32193220
foreach ($conditionalExpressions as $conditionalExpression) {
32203221
foreach ($conditionalExpression->getConditionExpressionTypeHolders() as $holderExprString => $conditionalTypeHolder) {
3221-
if (!array_key_exists($holderExprString, $specifiedExpressions) || !$specifiedExpressions[$holderExprString]->equals($conditionalTypeHolder)) {
3222+
if (!array_key_exists($holderExprString, $specifiedExpressions)) {
32223223
continue 2;
32233224
}
3225+
$specifiedHolder = $specifiedExpressions[$holderExprString];
3226+
if (!$specifiedHolder->equals($conditionalTypeHolder)) {
3227+
if (
3228+
!$conditionalExpression->getTypeHolder()->getCertainty()->yes()
3229+
|| !$specifiedHolder->getCertainty()->equals($conditionalTypeHolder->getCertainty())
3230+
|| !$conditionalTypeHolder->getType() instanceof UnionType
3231+
|| !$conditionalTypeHolder->getType()->isSuperTypeOf($specifiedHolder->getType())->yes()
3232+
) {
3233+
if ($debugFile !== '' && str_contains($scope->getFile(), $debugFile)) {
3234+
file_put_contents('/tmp/phpstan-debug.log', sprintf("SKIP: target=%s guard=%s guardType=%s specType=%s targetCert=%s\n", $conditionalExprString, $holderExprString, $conditionalTypeHolder->getType()->describe(\PHPStan\Type\VerbosityLevel::precise()), $specifiedHolder->getType()->describe(\PHPStan\Type\VerbosityLevel::precise()), $conditionalExpression->getTypeHolder()->getCertainty()->describe()), FILE_APPEND);
3235+
}
3236+
continue 2;
3237+
}
3238+
if ($debugFile !== '' && str_contains($scope->getFile(), $debugFile)) {
3239+
file_put_contents('/tmp/phpstan-debug.log', sprintf("RELAXED MATCH: target=%s guard=%s guardType=%s specType=%s targetCert=%s targetType=%s\n", $conditionalExprString, $holderExprString, $conditionalTypeHolder->getType()->describe(\PHPStan\Type\VerbosityLevel::precise()), $specifiedHolder->getType()->describe(\PHPStan\Type\VerbosityLevel::precise()), $conditionalExpression->getTypeHolder()->getCertainty()->describe(), $conditionalExpression->getTypeHolder()->getType()->describe(\PHPStan\Type\VerbosityLevel::precise())), FILE_APPEND);
3240+
}
3241+
}
32243242
}
32253243

3244+
if ($debugFile !== '' && str_contains($scope->getFile(), $debugFile)) {
3245+
file_put_contents('/tmp/phpstan-debug.log', sprintf("MATCHED: target=%s targetType=%s targetCert=%s\n", $conditionalExprString, $conditionalExpression->getTypeHolder()->getType()->describe(\PHPStan\Type\VerbosityLevel::precise()), $conditionalExpression->getTypeHolder()->getCertainty()->describe()), FILE_APPEND);
3246+
}
32263247
$conditions[$conditionalExprString][] = $conditionalExpression;
32273248
$specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder();
32283249
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug10422;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class TestClass {
8+
public function test(): void {}
9+
public function something(): bool { return true; }
10+
}
11+
12+
function (): void {
13+
/** @var ?TestClass $test */
14+
$test = null;
15+
16+
$error = '';
17+
18+
if (!$test) {
19+
$error = 'missing test';
20+
} else if ($test->something()) {
21+
$error = 'another';
22+
}
23+
if ($error) {
24+
die('Done');
25+
}
26+
assertType('Bug10422\TestClass', $test);
27+
$test->test();
28+
};

tests/PHPStan/Analyser/nsrt/bug-5051.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,23 @@ public function testWithBooleans($data): void
6464
}
6565

6666
if ($data === 1) {
67-
assertType('bool', $update);
68-
assertType('bool', $foo);
67+
assertType('false', $update);
68+
assertType('false', $foo);
6969
} else {
7070
assertType('bool', $update);
7171
assertType('bool', $foo);
7272
}
7373

7474
if ($data === 2) {
75-
assertType('bool', $update);
76-
assertType('bool', $foo);
75+
assertType('false', $update);
76+
assertType('false', $foo);
7777
} else {
7878
assertType('bool', $update);
7979
assertType('bool', $foo);
8080
}
8181

8282
if ($data === 3) {
83-
assertType('bool', $update);
83+
assertType('false', $update);
8484
assertType('true', $foo);
8585
} else {
8686
assertType('bool', $update);

0 commit comments

Comments
 (0)