mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Type negation in generic context (#5879)
* Type negation in generic context * Fix cs
This commit is contained in:
parent
1a2e761918
commit
e5e397a6c5
@ -73,7 +73,7 @@ class ElseAnalyzer
|
||||
$changed_var_ids,
|
||||
[],
|
||||
$statements_analyzer,
|
||||
[],
|
||||
$statements_analyzer->getTemplateTypeMap() ?: [],
|
||||
$else_context->inside_loop,
|
||||
$else
|
||||
? new CodeLocation($statements_analyzer->getSource(), $else, $outer_context->include_location)
|
||||
|
@ -13,7 +13,6 @@ use Psalm\Issue\RedundantPropertyInitializationCheck;
|
||||
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
|
||||
use Psalm\IssueBuffer;
|
||||
use Psalm\Type;
|
||||
use Psalm\Type\Atomic;
|
||||
use Psalm\Type\Atomic\TArray;
|
||||
use Psalm\Type\Atomic\TFalse;
|
||||
use Psalm\Type\Atomic\TNamedObject;
|
||||
@ -25,6 +24,7 @@ use function strtolower;
|
||||
use function substr;
|
||||
use function explode;
|
||||
use function get_class;
|
||||
use function array_values;
|
||||
|
||||
class NegatedAssertionReconciler extends Reconciler
|
||||
{
|
||||
@ -238,7 +238,13 @@ class NegatedAssertionReconciler extends Reconciler
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_type_part = Atomic::create($assertion, null, $template_type_map);
|
||||
$assertion_type = Type::parseString($assertion, null, $template_type_map);
|
||||
|
||||
if (!$assertion_type->isSingle()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_type_part = array_values($assertion_type->getAtomicTypes())[0];
|
||||
|
||||
if (!$new_type_part instanceof TNamedObject) {
|
||||
continue;
|
||||
|
@ -2589,6 +2589,43 @@ class ConditionalTest extends \Psalm\Tests\TestCase
|
||||
'$c' => 'list<float|int>',
|
||||
],
|
||||
],
|
||||
'negateTypeInGenericContext' => [
|
||||
'<?php
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*/
|
||||
final class Valid {}
|
||||
final class Invalid {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*
|
||||
* @param Valid<T>|Invalid $val
|
||||
* @psalm-assert-if-true Valid<T> $val
|
||||
*/
|
||||
function isValid($val): bool
|
||||
{
|
||||
return $val instanceof Valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param Valid<T>|Invalid $val
|
||||
*/
|
||||
function genericContext($val): void
|
||||
{
|
||||
$takesValid =
|
||||
/** @param Valid<T> $_valid */
|
||||
function ($_valid): void {};
|
||||
|
||||
$takesInvalid =
|
||||
/** @param Invalid $_invalid */
|
||||
function ($_invalid): void {};
|
||||
|
||||
isValid($val) ? $takesValid($val) : $takesInvalid($val);
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user