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:
commit
9823e87b80
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user