1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Fix #3907 - allow template as types to be refined via instanceof

This commit is contained in:
Brown 2020-07-29 17:46:45 -04:00
parent 38f74815d6
commit 1c8f9e94b1
2 changed files with 45 additions and 2 deletions

View File

@ -655,8 +655,8 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
Type\Union $existing_type,
Type\Union $new_type,
array $template_type_map,
bool &$has_match,
bool &$any_scalar_type_match_found
bool &$has_match = false,
bool &$any_scalar_type_match_found = false
) : Type\Union {
$matching_atomic_types = [];
@ -765,6 +765,25 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
continue;
}
if ($has_local_match
&& $new_type_part instanceof Type\Atomic\TNamedObject
&& $existing_type_part instanceof Type\Atomic\TTemplateParam
&& $existing_type_part->as->hasObjectType()
) {
$existing_type_part = clone $existing_type_part;
$existing_type_part->as = self::filterTypeWithAnother(
$codebase,
$existing_type_part->as,
new Type\Union([$new_type_part]),
$template_type_map
);
$matching_atomic_types[] = $existing_type_part;
$has_local_match = true;
continue;
}
if (($new_type_part instanceof Type\Atomic\TGenericObject
|| $new_type_part instanceof Type\Atomic\TArray
|| $new_type_part instanceof Type\Atomic\TIterable)

View File

@ -2838,6 +2838,30 @@ class ClassTemplateTest extends TestCase
}
}'
],
'narrowTemplateTypeWithInstanceof' => [
'<?php
class Foo {}
class Bar {}
/** @template FooOrBarOrNull of Foo|Bar|null */
class Resolved
{
/**
* @var FooOrBarOrNull
*/
private $entity = null;
/**
* @psalm-param FooOrBarOrNull $qux
*/
public function __contruct(?object $qux)
{
if ($qux instanceof Foo) {
$this->entity = $qux;
}
}
}'
],
];
}