From 7172e5fc42154dbc73e78068bf12dbe3e27f9af5 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sun, 15 Aug 2021 11:48:54 +0200 Subject: [PATCH] Fix casting non-empty-string array key type --- src/Type/ArrayType.php | 2 +- .../Analyser/NodeScopeResolverTest.php | 6 ++++- tests/PHPStan/Analyser/data/bug-5219.php | 2 +- .../Analyser/data/non-empty-string.php | 6 ++--- .../Arrays/AppendedArrayKeyTypeRuleTest.php | 5 ++++ .../PHPStan/Rules/Arrays/data/bug-5372_2.php | 23 +++++++++++++++++++ 6 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 tests/PHPStan/Rules/Arrays/data/bug-5372_2.php diff --git a/src/Type/ArrayType.php b/src/Type/ArrayType.php index 1696294001..48ffdd6e15 100644 --- a/src/Type/ArrayType.php +++ b/src/Type/ArrayType.php @@ -317,7 +317,7 @@ public static function castToArrayKeyType(Type $offsetType): Type return new IntegerType(); } - if ($offsetType instanceof StringType) { + if ($offsetType instanceof StringType || $offsetType->isNonEmptyString()->yes()) { return $offsetType; } diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index 41fab64c49..a63b4f8c95 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -447,7 +447,11 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4970.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5322.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/splfixedarray-iterator-types.php'); - yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5372.php'); + + if (PHP_VERSION_ID >= 70400 || self::$useStaticReflectionProvider) { + yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5372.php'); + } + yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-5372_2.php'); } /** diff --git a/tests/PHPStan/Analyser/data/bug-5219.php b/tests/PHPStan/Analyser/data/bug-5219.php index c79e9f59a2..ab75d306a5 100644 --- a/tests/PHPStan/Analyser/data/bug-5219.php +++ b/tests/PHPStan/Analyser/data/bug-5219.php @@ -12,7 +12,7 @@ protected function foo(string $message): void $header = sprintf('%s-%s', '', implode('-', ['x'])); assertType('non-empty-string', $header); - assertType('array&nonEmpty', [$header => $message]); + assertType('array&nonEmpty', [$header => $message]); } protected function bar(string $message): void diff --git a/tests/PHPStan/Analyser/data/non-empty-string.php b/tests/PHPStan/Analyser/data/non-empty-string.php index 457229c9ba..a951ca8af0 100644 --- a/tests/PHPStan/Analyser/data/non-empty-string.php +++ b/tests/PHPStan/Analyser/data/non-empty-string.php @@ -282,7 +282,7 @@ public function doFoo(array $a, string $s): void $a[$s] = 2; // there might be non-empty-string that becomes a number instead - assertType('array&nonEmpty', $a); + assertType('array&nonEmpty', $a); } /** @@ -309,12 +309,12 @@ public function doFoo(string $s, string $nonEmpty, int $i) assertType('non-empty-string', addslashes($nonEmpty)); assertType('string', addcslashes($s)); assertType('non-empty-string', addcslashes($nonEmpty)); - + assertType('string', escapeshellarg($s)); assertType('non-empty-string', escapeshellarg($nonEmpty)); assertType('string', escapeshellcmd($s)); assertType('non-empty-string', escapeshellcmd($nonEmpty)); - + assertType('string', strtoupper($s)); assertType('non-empty-string', strtoupper($nonEmpty)); assertType('string', strtolower($s)); diff --git a/tests/PHPStan/Rules/Arrays/AppendedArrayKeyTypeRuleTest.php b/tests/PHPStan/Rules/Arrays/AppendedArrayKeyTypeRuleTest.php index 8804531ec5..6bdc105a48 100644 --- a/tests/PHPStan/Rules/Arrays/AppendedArrayKeyTypeRuleTest.php +++ b/tests/PHPStan/Rules/Arrays/AppendedArrayKeyTypeRuleTest.php @@ -56,4 +56,9 @@ public function testRule(): void ]); } + public function testBug5372Two(): void + { + $this->analyse([__DIR__ . '/data/bug-5372_2.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Arrays/data/bug-5372_2.php b/tests/PHPStan/Rules/Arrays/data/bug-5372_2.php new file mode 100644 index 0000000000..5e6caebd42 --- /dev/null +++ b/tests/PHPStan/Rules/Arrays/data/bug-5372_2.php @@ -0,0 +1,23 @@ + */ + private $map = []; + + /** + * @param array $values + */ + public function __construct(array $values) + { + assertType('array', $values); + foreach ($values as $v) { + assertType('non-empty-string', $v); + $this->map[$v] = 'whatever'; + } + } +}