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',
+ ],
];
}
}