diff --git a/composer.json b/composer.json index 3b9b3ef4c3b..a09b2ce81c3 100644 --- a/composer.json +++ b/composer.json @@ -52,6 +52,7 @@ "phpunit/phpunit": "^9.5", "psalm/plugin-phpunit": "^0.16", "slevomat/coding-standard": "^7.0", + "phpstan/phpdoc-parser": "1.6.4", "squizlabs/php_codesniffer": "^3.6", "symfony/process": "^4.3 || ^5.0 || ^6.0" }, diff --git a/psalm.xml.dist b/psalm.xml.dist index bdb53be6ec9..04e314c7038 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -38,6 +38,7 @@ + diff --git a/src/Psalm/Internal/LanguageServer/Client/TextDocument.php b/src/Psalm/Internal/LanguageServer/Client/TextDocument.php index 380b5e0d18e..c2b7f8cc704 100644 --- a/src/Psalm/Internal/LanguageServer/Client/TextDocument.php +++ b/src/Psalm/Internal/LanguageServer/Client/TextDocument.php @@ -57,6 +57,8 @@ public function publishDiagnostics(string $uri, array $diagnostics): void * @param TextDocumentIdentifier $textDocument The document to get the content for * * @return Promise The document's current content + * + * @psalm-suppress MixedReturnTypeCoercion due to Psalm bug */ public function xcontent(TextDocumentIdentifier $textDocument): Promise { diff --git a/src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php b/src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php index e99d00433a4..6d40f771857 100644 --- a/src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php @@ -167,13 +167,7 @@ public static function isContainedBy( ) { // do nothing } else { - if ($container_param->hasMixed() || $container_param->isArrayKey()) { - if ($atomic_comparison_result) { - $atomic_comparison_result->type_coerced_from_mixed = true; - } - } else { - $all_types_contain = false; - } + $all_types_contain = false; if ($atomic_comparison_result) { $atomic_comparison_result->type_coerced = false; diff --git a/tests/IfThisIsTest.php b/tests/IfThisIsTest.php index 38e2821f7ee..248fe495583 100644 --- a/tests/IfThisIsTest.php +++ b/tests/IfThisIsTest.php @@ -219,7 +219,7 @@ public function compact(): ArrayList 'ifThisIsResolveTemplateParams' => [ 'code' => ' */ + /** @var SplObjectStorage<\stdClass, mixed> */ $storage = new SplObjectStorage(); new SomeService($storage); $c = new \stdClass(); $storage[$c] = "hello"; + /** @psalm-suppress MixedAssignment */ $b = $storage->offsetGet($c);', 'assertions' => [ - '$b' => 'string', + '$b' => 'mixed', ], ], 'extendsArrayIterator' => [ diff --git a/tests/Template/ClassTemplateTest.php b/tests/Template/ClassTemplateTest.php index 91c733e18a4..6dc1a02a118 100644 --- a/tests/Template/ClassTemplateTest.php +++ b/tests/Template/ClassTemplateTest.php @@ -4600,6 +4600,23 @@ final class Two {} final class Three {}', 'error_message' => 'InvalidReturnStatement - src' . DIRECTORY_SEPARATOR . 'somefile.php:12:40 - The inferred type \'T:A as One|Two\' ', ], + 'preventMixedNestedCoercion' => [ + 'code' => ' $members */ + public function __construct(public array $members) {} + } + + /** + * @param MyCollection $c + * @return MyCollection + */ + function getMixedCollection(MyCollection $c): MyCollection { + return $c; + }', + 'error_message' => 'InvalidReturnStatement', + ], ]; } }