Skip to content

Commit

Permalink
Support the $foo ?? false pattern when making sure variable exists
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Mar 26, 2021
1 parent ed1736c commit c4cc668
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/Analyser/TypeSpecifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,16 @@ public function specifyTypesInCondition(
}

return $types;
} elseif (
$expr instanceof Expr\BinaryOp\Coalesce
&& $context->true()
&& ((new ConstantBooleanType(false))->isSuperTypeOf($scope->getType($expr->right))->yes())
) {
return $this->create(
$expr->left,
new NullType(),
TypeSpecifierContext::createFalse()
);
} elseif (
$expr instanceof Expr\Empty_ && $context->truthy()
&& (new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($scope->getType($expr->expr))->yes()
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5755,6 +5755,11 @@ public function dataTernarySpecifiedTypes(): array
return $this->gatherAssertTypes(__DIR__ . '/data/ternary-specified-types.php');
}

public function dataBug560(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-560.php');
}

/**
* @dataProvider dataArrayFunctions
* @param string $description
Expand Down Expand Up @@ -11389,6 +11394,7 @@ private function gatherAssertTypes(string $file): array
* @dataProvider dataBug2977
* @dataProvider dataBug3190
* @dataProvider dataTernarySpecifiedTypes
* @dataProvider dataBug560
* @param string $assertType
* @param string $file
* @param mixed ...$args
Expand Down
22 changes: 22 additions & 0 deletions tests/PHPStan/Analyser/data/bug-560.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Bug560;

use PHPStan\TrinaryLogic;
use function PHPStan\Analyser\assertType;
use function PHPStan\Analyser\assertVariableCertainty;

assertVariableCertainty(TrinaryLogic::createMaybe(), $city);
assertType('mixed', $city);

if ($city ?? false) {
assertVariableCertainty(TrinaryLogic::createYes(), $city);
assertType('mixed~null', $city);
}

function (?string $s): void {
if ($s ?? false) {
assertVariableCertainty(TrinaryLogic::createYes(), $s);
assertType('string' ,$s);
}
};

0 comments on commit c4cc668

Please sign in to comment.