Skip to content

Commit d069408

Browse files
ruudkondrejmirtes
authored andcommitted
Fixed === and !== type inference with treatPhpDocTypesAsCertain=false
1 parent 2675dcd commit d069408

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

src/Analyser/MutatingScope.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -810,8 +810,13 @@ private function resolveType(Expr $node): Type
810810
}
811811

812812
if ($node instanceof Expr\BinaryOp\Identical) {
813-
$leftType = $this->getType($node->left);
814-
$rightType = $this->getType($node->right);
813+
if ($this->treatPhpDocTypesAsCertain) {
814+
$leftType = $this->getType($node->left);
815+
$rightType = $this->getType($node->right);
816+
} else {
817+
$leftType = $this->getNativeType($node->left);
818+
$rightType = $this->getNativeType($node->right);
819+
}
815820

816821
if (
817822
(
@@ -851,8 +856,13 @@ private function resolveType(Expr $node): Type
851856
}
852857

853858
if ($node instanceof Expr\BinaryOp\NotIdentical) {
854-
$leftType = $this->getType($node->left);
855-
$rightType = $this->getType($node->right);
859+
if ($this->treatPhpDocTypesAsCertain) {
860+
$leftType = $this->getType($node->left);
861+
$rightType = $this->getType($node->right);
862+
} else {
863+
$leftType = $this->getNativeType($node->left);
864+
$rightType = $this->getNativeType($node->right);
865+
}
856866

857867
if (
858868
(

src/Testing/TypeInferenceTestCase.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,9 @@ public function gatherAssertTypes(string $file): array
153153
$actualType = $scope->getType($node->args[1]->value);
154154
$assert = ['type', $file, $expectedType, $actualType, $node->getLine()];
155155
} elseif ($functionName === 'PHPStan\\Testing\\assertNativeType') {
156-
$expectedType = $scope->getNativeType($node->args[0]->value);
157-
$actualType = $scope->getNativeType($node->args[1]->value);
156+
$nativeScope = $scope->doNotTreatPhpDocTypesAsCertain();
157+
$expectedType = $nativeScope->getNativeType($node->args[0]->value);
158+
$actualType = $nativeScope->getNativeType($node->args[1]->value);
158159
$assert = ['type', $file, $expectedType, $actualType, $node->getLine()];
159160
} elseif ($functionName === 'PHPStan\\Testing\\assertVariableCertainty') {
160161
$certainty = $node->args[0]->value;

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ public function dataFileAsserts(): iterable
379379
require_once __DIR__ . '/data/type-aliases.php';
380380

381381
yield from $this->gatherAssertTypes(__DIR__ . '/data/type-aliases.php');
382+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4650.php');
382383
}
383384

384385
/**
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Bug4650;
4+
5+
use function PHPStan\Testing\assertNativeType;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
11+
/**
12+
* @phpstan-param non-empty-array<string|int> $idx
13+
*/
14+
function doFoo(array $idx): void {
15+
assertType('array<int|string>&nonEmpty', $idx);
16+
assertNativeType('array', $idx);
17+
18+
assertType('array()', []);
19+
assertNativeType('array()', []);
20+
21+
assertType('false', $idx === []);
22+
assertNativeType('bool', $idx === []);
23+
assertType('true', $idx !== []);
24+
assertNativeType('bool', $idx !== []);
25+
}
26+
27+
}

0 commit comments

Comments
 (0)