Skip to content

Commit

Permalink
Forbid array<mixed, ...>
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Feb 21, 2020
1 parent af2ea17 commit 9bdca3c
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,19 @@ public static function getFunctionReturnType(
]);
}

$key_type = $key_type
&& (!isset($call_args[1])
|| ($second_arg_type && ((string) $second_arg_type === 'true')))
? $key_type
: Type::getArrayKey();

if ($key_type->isMixed()) {
$key_type = Type::getArrayKey();
}

return new Type\Union([
new Type\Atomic\TArray([
$key_type
&& (!isset($call_args[1])
|| ($second_arg_type && ((string) $second_arg_type === 'true')))
? $key_type
: Type::getArrayKey(),
$key_type,
$value_type,
]),
]);
Expand Down
8 changes: 7 additions & 1 deletion src/Psalm/Internal/Type/AssertionReconciler.php
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,9 @@ private static function reconcileArray(
$did_remove_type = true;
} elseif ($type instanceof Atomic\TIterable) {
$clone_type = clone $type;
if ($clone_type->type_params[0]->isMixed()) {
$clone_type->type_params[0] = Type::getArrayKey();
}
$array_types[] = new TArray($clone_type->type_params);

$did_remove_type = true;
Expand Down Expand Up @@ -2708,7 +2711,10 @@ private static function handleLiteralEquality(
|| $scalar_type === 'callable-string'
|| $scalar_type === 'trait-string'
) {
if ($existing_var_type->hasMixed() || $existing_var_type->hasScalar()) {
if ($existing_var_type->hasMixed()
|| $existing_var_type->hasScalar()
|| $existing_var_type->hasArrayKey()
) {
if ($is_loose_equality) {
return $existing_var_type;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Internal/Type/NegatedAssertionReconciler.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,8 @@ public static function reconcile(
$existing_var_type->removeType('iterable');
$existing_var_type->addType(new TArray(
[
$iterable->type_params[0],
$iterable->type_params[1],
$iterable->type_params[0]->isMixed() ? Type::getArrayKey() : clone $iterable->type_params[0],
clone $iterable->type_params[1],
]
));
} elseif (strtolower($assertion) === 'int'
Expand Down
6 changes: 5 additions & 1 deletion src/Psalm/Type/Atomic/GenericTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,12 @@ public function replaceTemplateTypesWithStandins(
*/
public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase)
{
foreach ($this->type_params as $type_param) {
foreach ($this->type_params as $offset => $type_param) {
$type_param->replaceTemplateTypesWithArgTypes($template_types, $codebase);

if ($this instanceof Atomic\TArray && $offset === 0 && $type_param->isMixed()) {
$this->type_params[0] = \Psalm\Type::getArrayKey();
}
}

if ($this instanceof TGenericObject) {
Expand Down
2 changes: 1 addition & 1 deletion tests/FunctionCallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ function generator(): Generator {
$a = iterator_to_array(generator());',
'assertions' => [
'$a' => 'array<mixed, stdClass>',
'$a' => 'array<array-key, stdClass>',
],
],
'iteratorToArrayWithGetIterator' => [
Expand Down
4 changes: 2 additions & 2 deletions tests/Template/ClassTemplateCovarianceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,12 @@ function getReference()
class A {
private $arr;
/** @psalm-param array<mixed, T> $arr */
/** @psalm-param array<T> $arr */
public function __construct(array $arr) {
$this->arr = $arr;
}
/** @psalm-return array<mixed, T> */
/** @psalm-return array<T> */
public function foo(): array {
return $this->arr;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/Template/FunctionTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,14 @@ function byRef(array &$arr) : void {}
/**
* @template TValue
*
* @param array<mixed, TValue> $arr
* @param array<TValue> $arr
*/
function byRef(array &$arr) : void {}
$b = ["a" => 5, "c" => 6];
byRef($b);',
'assertions' => [
'$b' => 'array<mixed, int>',
'$b' => 'array<array-key, int>',
],
],
'mixedArrayPop' => [
Expand Down

0 comments on commit 9bdca3c

Please sign in to comment.