mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
parent
532e2d64be
commit
842b2a53df
@ -2125,6 +2125,8 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
) : Type\Union {
|
||||
$matching_atomic_types = [];
|
||||
|
||||
$has_cloned_type = false;
|
||||
|
||||
foreach ($new_type->getTypes() as $new_type_part) {
|
||||
$has_local_match = false;
|
||||
|
||||
@ -2167,6 +2169,42 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
$matching_atomic_types[] = $existing_type_part;
|
||||
}
|
||||
|
||||
if ($new_type_part instanceof Type\Atomic\ObjectLike
|
||||
&& $existing_type_part instanceof Type\Atomic\TList
|
||||
) {
|
||||
$new_type_key = $new_type_part->getGenericKeyType();
|
||||
$new_type_value = $new_type_part->getGenericValueType();
|
||||
|
||||
if (!$new_type_key->hasString()) {
|
||||
$has_param_match = false;
|
||||
|
||||
$new_type_value = self::filterTypeWithAnother(
|
||||
$codebase,
|
||||
$existing_type_part->type_param,
|
||||
$new_type_value,
|
||||
$template_type_map,
|
||||
$has_param_match,
|
||||
$any_scalar_type_match_found
|
||||
);
|
||||
|
||||
$hybrid_type_part = new Type\Atomic\ObjectLike($new_type_part->properties);
|
||||
$hybrid_type_part->previous_key_type = Type::getInt();
|
||||
$hybrid_type_part->previous_value_type = $new_type_value;
|
||||
$hybrid_type_part->is_list = true;
|
||||
|
||||
if (!$has_cloned_type) {
|
||||
$new_type = clone $new_type;
|
||||
}
|
||||
|
||||
$has_local_match = true;
|
||||
|
||||
$new_type->removeType($key);
|
||||
$new_type->addType($hybrid_type_part);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (($new_type_part instanceof Type\Atomic\TGenericObject
|
||||
|| $new_type_part instanceof Type\Atomic\TArray
|
||||
|| $new_type_part instanceof Type\Atomic\TIterable)
|
||||
@ -2232,6 +2270,10 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
}
|
||||
)
|
||||
) {
|
||||
if (!$has_cloned_type) {
|
||||
$new_type = clone $new_type;
|
||||
}
|
||||
|
||||
$new_type->removeType($key);
|
||||
$new_type->addType($existing_type_part);
|
||||
$new_type->from_docblock = $existing_type_part->from_docblock;
|
||||
|
@ -666,6 +666,32 @@ class AssertAnnotationTest extends TestCase
|
||||
if (rand(0, 1) && f($q)) {}
|
||||
if (!f($q)) {}'
|
||||
],
|
||||
'assertDifferentTypeOfArray' => [
|
||||
'<?php
|
||||
/**
|
||||
* @psalm-assert array{0: string, 1: string} $value
|
||||
* @param mixed $value
|
||||
*/
|
||||
function isStringTuple($value): void {
|
||||
if (!is_array($value)
|
||||
|| !isset($value[0])
|
||||
|| !isset($value[1])
|
||||
|| !is_string($value[0])
|
||||
|| !is_string($value[1])
|
||||
) {
|
||||
throw new \Exception("bad");
|
||||
}
|
||||
}
|
||||
|
||||
$s = "";
|
||||
|
||||
$parts = explode(":", $s, 2);
|
||||
|
||||
isStringTuple($parts);
|
||||
|
||||
echo $parts[0];
|
||||
echo $parts[1];'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user