Skip to content

Commit

Permalink
Fix mixed type hole when sending Foo<string> to Foo<mixed> (#8481)
Browse files Browse the repository at this point in the history
* Fix mixed type hole when sending Foo<string> to Foo<mixed>

* Fix ifThisIs test

* Suppress bugs highlighted with fix

* Fix PHPDoc parsing
  • Loading branch information
muglug committed Sep 13, 2022
1 parent afe85fa commit d957ff2
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 12 deletions.
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -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"
},
Expand Down
1 change: 1 addition & 0 deletions psalm.xml.dist
Expand Up @@ -38,6 +38,7 @@
<file name="vendor/felixfbecker/advanced-json-rpc/lib/Dispatcher.php" />
<directory name="vendor/netresearch/jsonmapper" />
<directory name="vendor/phpunit" />
<file name="vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.php" />
</ignoreFiles>
</projectFiles>

Expand Down
2 changes: 2 additions & 0 deletions src/Psalm/Internal/LanguageServer/Client/TextDocument.php
Expand Up @@ -57,6 +57,8 @@ public function publishDiagnostics(string $uri, array $diagnostics): void
* @param TextDocumentIdentifier $textDocument The document to get the content for
*
* @return Promise<TextDocumentItem> The document's current content
*
* @psalm-suppress MixedReturnTypeCoercion due to Psalm bug
*/
public function xcontent(TextDocumentIdentifier $textDocument): Promise
{
Expand Down
8 changes: 1 addition & 7 deletions src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions tests/IfThisIsTest.php
Expand Up @@ -219,7 +219,7 @@ public function compact(): ArrayList
'ifThisIsResolveTemplateParams' => [
'code' => '<?php
/**
* @template T
* @template-covariant T
*/
final class Option
{
Expand All @@ -228,8 +228,8 @@ public function unwrap() { throw new RuntimeException("???"); }
}
/**
* @template L
* @template R
* @template-covariant L
* @template-covariant R
*/
final class Either
{
Expand Down
5 changes: 3 additions & 2 deletions tests/Template/ClassTemplateExtendsTest.php
Expand Up @@ -987,15 +987,16 @@ public function __construct(SplObjectStorage $handlers)
}
}
/** @var SplObjectStorage<\stdClass, string> */
/** @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' => [
Expand Down
17 changes: 17 additions & 0 deletions tests/Template/ClassTemplateTest.php
Expand Up @@ -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' => '<?php
/** @template T */
class MyCollection {
/** @param array<T> $members */
public function __construct(public array $members) {}
}
/**
* @param MyCollection<string> $c
* @return MyCollection<mixed>
*/
function getMixedCollection(MyCollection $c): MyCollection {
return $c;
}',
'error_message' => 'InvalidReturnStatement',
],
];
}
}

0 comments on commit d957ff2

Please sign in to comment.