Skip to content

Commit cf401ab

Browse files
github-actions[bot]phpstan-bot
authored andcommitted
Fix phpstan/phpstan#11054: NAN array type narrowing in strict comparison
- Override getFiniteTypes() in ConstantFloatType to return [] for NAN values - This prevents TypeSpecifier from subtracting array{NAN} from mixed in the false branch of === checks, since NAN-containing arrays can still be identical when they share the same zval (e.g., class constants) - New regression test in tests/PHPStan/Rules/Comparison/data/bug-11054.php
1 parent d8f5be7 commit cf401ab

3 files changed

Lines changed: 56 additions & 0 deletions

File tree

src/Type/Constant/ConstantFloatType.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ public function toArrayKey(): Type
9999
return new ConstantIntegerType((int) $this->value);
100100
}
101101

102+
public function getFiniteTypes(): array
103+
{
104+
if (is_nan($this->value)) {
105+
return [];
106+
}
107+
108+
return [$this];
109+
}
110+
102111
public function generalize(GeneralizePrecision $precision): Type
103112
{
104113
return new FloatType();

tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,4 +1161,9 @@ public function testPossiblyImpureTip(): void
11611161
]);
11621162
}
11631163

1164+
public function testBug11054(): void
1165+
{
1166+
$this->analyse([__DIR__ . '/data/bug-11054.php'], []);
1167+
}
1168+
11641169
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug11054;
4+
5+
class XXX {
6+
public const DEF_VALUE = [NAN];
7+
public const NO_VALUE = [NAN];
8+
}
9+
10+
class YYY
11+
{
12+
public const LOSSLESS = [NAN];
13+
14+
/**
15+
* @param string|int|mixed $substituteChar
16+
*/
17+
public static function convertEncoding (
18+
string $str,
19+
string $sourceEncoding,
20+
string $targetEncoding,
21+
$substituteChar = XXX::DEF_VALUE,
22+
$defValue = XXX::NO_VALUE
23+
): string {
24+
if ($substituteChar === XXX::DEF_VALUE) { // no error expected
25+
return mb_convert_encoding($str, $targetEncoding, $sourceEncoding);
26+
}
27+
28+
if ($substituteChar === self::LOSSLESS) { // no error expected
29+
return $str;
30+
}
31+
32+
return $str;
33+
}
34+
}
35+
36+
class SimpleTest {
37+
/** @param mixed $v */
38+
public static function test($v): void
39+
{
40+
if ($v === [NAN]) {} // no error expected
41+
}
42+
}

0 commit comments

Comments
 (0)