1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #736 - only remove offset type when it doesn’t contain const array type

This commit is contained in:
Matthew Brown 2018-05-12 11:17:41 -04:00
parent d078ce7a26
commit 5589aa89be
2 changed files with 46 additions and 2 deletions

View File

@ -158,7 +158,7 @@ class ArrayFetchChecker
$const_array_key_type = $array_type->getGenericKeyType();
}
if ($dim_var_id && !$const_array_key_type->isMixed()) {
if ($dim_var_id && !$const_array_key_type->isMixed() && !$stmt->dim->inferredType->isMixed()) {
$new_offset_type = clone $stmt->dim->inferredType;
$const_array_key_atomic_types = $const_array_key_type->getTypes();
$project_checker = $statements_checker->getFileChecker()->project_checker;
@ -186,7 +186,11 @@ class ArrayFetchChecker
)) {
$new_offset_type->removeType($offset_key);
}
} else {
} elseif (!TypeChecker::isContainedBy(
$project_checker->codebase,
$const_array_key_type,
new Type\Union([$offset_atomic_type])
)) {
$new_offset_type->removeType($offset_key);
}
}

View File

@ -151,6 +151,46 @@ class ConstantTest extends TestCase
}
}',
],
'noExceptionsOnMixedArrayKey' => [
'<?php
function finder(string $id) : ?object {
if (rand(0, 1)) {
return new A();
}
if (rand(0, 1)) {
return new B();
}
return null;
}
class A {}
class B {}
class Foo
{
private const TYPES = [
"type1" => A::class,
"type2" => B::class,
];
public function bar(array $data): void
{
if (!isset(self::TYPES[$data["type"]])) {
throw new \InvalidArgumentException("Unknown type");
}
$class = self::TYPES[$data["type"]];
$ret = finder($data["id"]);
if (!$ret || !$ret instanceof $class) {
throw new \InvalidArgumentException;
}
}
}',
'assertions' => [],
'error_levels' => ['MixedArgument', 'MixedArrayOffset', 'MixedAssignment'],
],
];
}