1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Merge pull request #6774 from orklah/reconcileFalsyOrEmpty

fix local variable defined too early
This commit is contained in:
orklah 2021-10-28 21:47:17 +02:00 committed by GitHub
commit 9823e87b80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 4 deletions

View File

@ -2221,7 +2221,6 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler
bool $recursive_check
) : Union {
$old_var_type_string = $existing_var_type->getId();
$existing_var_atomic_types = $existing_var_type->getAtomicTypes();
$did_remove_type = $existing_var_type->possibly_undefined
|| $existing_var_type->possibly_undefined_from_try;
@ -2358,7 +2357,7 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler
$existing_var_type->addType(new TEmptyNumeric());
}
foreach ($existing_var_atomic_types as $type_key => $existing_var_atomic_type) {
foreach ($existing_var_type->getAtomicTypes() as $type_key => $existing_var_atomic_type) {
if ($existing_var_atomic_type instanceof TTemplateParam) {
if (!$existing_var_atomic_type->as->isMixed()) {
$template_did_fail = 0;

View File

@ -573,7 +573,7 @@ class SimpleNegatedAssertionReconciler extends Reconciler
bool $recursive_check
) : Type\Union {
$old_var_type_string = $existing_var_type->getId();
$existing_var_atomic_types = $existing_var_type->getAtomicTypes();
//empty is used a lot to check for array offset existence, so we have to silent errors a lot
$is_empty_assertion = $assertion === 'empty';
@ -723,7 +723,7 @@ class SimpleNegatedAssertionReconciler extends Reconciler
}
}
foreach ($existing_var_atomic_types as $type_key => $existing_var_atomic_type) {
foreach ($existing_var_type->getAtomicTypes() as $type_key => $existing_var_atomic_type) {
if ($existing_var_atomic_type instanceof TTemplateParam) {
if (!$is_equality && !$existing_var_atomic_type->as->isMixed()) {
$template_did_fail = 0;

View File

@ -2749,6 +2749,64 @@ class ConditionalTest extends \Psalm\Tests\TestCase
echo "false";
}',
],
'nullIsFalsyEvenInTemplate' => [
'<?php
abstract class Animal {
public function foo(): void {}
}
class Dog extends Animal {}
class Cat extends Animal {}
/**
* @template T
*/
interface RepositoryInterface
{
/**
* @return ?T
*/
public function find(int $id);
}
/**
* @template T
* @implements RepositoryInterface<T>
*/
class AbstarctRepository implements RepositoryInterface
{
public function find(int $id) {
return null;
}
}
/**
* @template T as Animal
* @extends AbstarctRepository<T>
*/
class AnimalRepository extends AbstarctRepository {}
/**
* @extends AnimalRepository<Cat>
*/
class CatRepository extends AnimalRepository {}
/**
* @extends AnimalRepository<Dog>
*/
class DogRepository extends AnimalRepository {}
function doSomething(AnimalRepository $repository) : void {
$foo = $repository->find(1);
if (!$foo) {
return;
}
$foo->foo();
}',
],
];
}