mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Better type inference and type checking for large union types used in array keys/values
Fixes #8983 This patch adds a basic test showing that, when reaching a union type with 30 elements or more, Psalm used to fail with an error, because the large union type got simplified into a more general type as part of performance optimizations done in `TypeCombiner::combine()`. This means that a type like `array<1|2|3|(etcetera...)|100, mixed>` was internally simplified to `array<int, mixed>`, after reaching 30 elements or more, which in turn led to problems and confusing errors when large union types are in play. Such union types are relatively common in lookup-table-alike value objects. By removing the hardcoded call-time limit of `30` types to be combined, we hereby rely on the default `TypeCombiner::combine()` limit of `500` items, which is more healthy. This may come with some performance implications, but it is worth trying out, for now. Further parameters passed to `TypeCombiner::combine()` that were already matching parameter default values were also omitted from the call-sites.
This commit is contained in:
parent
dbcfe62c52
commit
e6600fea21
@ -97,9 +97,6 @@ class ArrayAnalyzer
|
||||
$item_key_type = TypeCombiner::combine(
|
||||
$array_creation_info->item_key_atomic_types,
|
||||
$codebase,
|
||||
false,
|
||||
true,
|
||||
30,
|
||||
);
|
||||
} else {
|
||||
$item_key_type = null;
|
||||
@ -109,9 +106,6 @@ class ArrayAnalyzer
|
||||
$item_value_type = TypeCombiner::combine(
|
||||
$array_creation_info->item_value_atomic_types,
|
||||
$codebase,
|
||||
false,
|
||||
true,
|
||||
30,
|
||||
);
|
||||
} else {
|
||||
$item_value_type = null;
|
||||
|
@ -548,10 +548,6 @@ class SimpleTypeInferer
|
||||
if ($array_creation_info->item_key_atomic_types) {
|
||||
$item_key_type = TypeCombiner::combine(
|
||||
$array_creation_info->item_key_atomic_types,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
30,
|
||||
);
|
||||
}
|
||||
|
||||
@ -559,10 +555,6 @@ class SimpleTypeInferer
|
||||
if ($array_creation_info->item_value_atomic_types) {
|
||||
$item_value_type = TypeCombiner::combine(
|
||||
$array_creation_info->item_value_atomic_types,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
30,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2523,6 +2523,19 @@ class ArrayFunctionCallTest extends TestCase
|
||||
}
|
||||
',
|
||||
],
|
||||
'functionRequiringArrayWithLargeUnionTypeKeyAllowsInputArrayUsingSameUnionForItsKeys' => [
|
||||
'code' => '<?php
|
||||
/** @psalm-type TLargeUnion = 1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31 */
|
||||
|
||||
/** @return TLargeUnion */
|
||||
function makeKey(): int { throw new Exception("irrelevant"); }
|
||||
|
||||
/** @param array<TLargeUnion, mixed> $_input */
|
||||
function consumeArray(array $_input): void {}
|
||||
|
||||
consumeArray([makeKey() => null]);
|
||||
',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user