Skip to content

Commit

Permalink
Merge branch refs/heads/1.10.x into 1.11.x
Browse files Browse the repository at this point in the history
  • Loading branch information
phpstan-bot committed Nov 2, 2023
2 parents dbeb001 + 01a0de2 commit b58f2c8
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 16 deletions.
29 changes: 19 additions & 10 deletions src/Analyser/TypeSpecifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,9 @@
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeTraverser;
use PHPStan\Type\UnionType;
use function array_filter;
use function array_key_exists;
use function array_map;
use function array_merge;
use function array_reduce;
use function array_reverse;
use function count;
use function in_array;
Expand Down Expand Up @@ -681,14 +679,25 @@ public function specifyTypesInCondition(
throw new ShouldNotHappenException();
}

return array_reduce(
array_filter(
$expr->vars,
static fn (Expr $var) => $scope->issetCheck($var, static fn () => true),
),
fn (SpecifiedTypes $types, Expr $var) => $types->unionWith($this->specifyTypesInCondition($scope, $var, $context, $rootExpr)),
new SpecifiedTypes(),
);
$specifiedTypes = new SpecifiedTypes();
foreach ($expr->vars as $var) {
$isset = $scope->issetCheck($var, static fn () => true);

if ($isset !== true) {
continue;
}

$specifiedTypes = $specifiedTypes->unionWith($this->create(
$var,
new NullType(),
$context->negate(),
false,
$scope,
$rootExpr,
));
}

return $specifiedTypes;
}

$vars = [];
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/trigger-error-php7.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/falsy-isset.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7915.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9714.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9105.php');
Expand Down
8 changes: 4 additions & 4 deletions tests/PHPStan/Analyser/TypeSpecifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,8 @@ public function dataCondition(): iterable
'$barOrNull' => '~null',
],
[
'$stringOrNull' => self::SURE_NOT_TRUTHY,
'$barOrNull' => self::SURE_NOT_TRUTHY,
'$stringOrNull' => 'null',
'$barOrNull' => 'null',
],
],
[
Expand All @@ -606,7 +606,7 @@ public function dataCondition(): iterable
[
new Expr\Empty_(new Variable('array')),
[
'$array' => 'array{}',
'$array' => 'array{}|null',
],
[
'$array' => '~0|0.0|\'\'|\'0\'|array{}|false|null',
Expand All @@ -618,7 +618,7 @@ public function dataCondition(): iterable
'$array' => '~0|0.0|\'\'|\'0\'|array{}|false|null',
],
[
'$array' => 'array{}',
'$array' => 'array{}|null',
],
],
[
Expand Down
4 changes: 2 additions & 2 deletions tests/PHPStan/Analyser/data/bug-9753.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ function (): void {
$items[] = $entry;
}
}
assertType('list<1|2|3|4|5>|null', $items);
assertType('non-empty-list<1|2|3|4|5>|null', $items);
}

assertType('list<1|2|3|4|5>|null', $items);
assertType('non-empty-list<1|2|3|4|5>|null', $items);
};
44 changes: 44 additions & 0 deletions tests/PHPStan/Analyser/data/falsy-isset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace FalsyIsset;

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

function mixedIsset(mixed $m): void
{
if (isset($m)) {
assertType("mixed~null", $m);
} else {
assertType("null", $m);
}
}

function stdclassIsset(?\stdClass $m): void
{
if (isset($m)) {
assertType("stdClass", $m);
} else {
assertType("null", $m);
}
}

function nullableVariable(?string $a): void
{
if (isset($a)) {
assertType("string", $a);
} else {
assertType("null", $a);
}
}

function nullableUnionVariable(null|string|int $a): void
{
if (isset($a)) {
assertType("int|string", $a);
} else {
assertType("null", $a);
}
}

10 changes: 10 additions & 0 deletions tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1450,4 +1450,14 @@ public function testBug9803(): void
$this->analyse([__DIR__ . '/data/bug-9803.php'], []);
}

public function testBug8659(): void
{
$this->analyse([__DIR__ . '/data/bug-8659.php'], []);
}

public function testBug9580(): void
{
$this->analyse([__DIR__ . '/data/bug-9580.php'], []);
}

}
30 changes: 30 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-8659.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Bug8659;

function acceptsString(string $input): string
{
return $input;
}

function foo1(?string $bar, ?string $baz): string
{
assert($bar !== null || $baz !== null);

// In this case, baz cannot be null (because $bar is and assert above makes sure that at least one value is not-null. Yet phpstan fails.
return $bar ?? acceptsString($baz);
}


function foo2(?string $bar, ?string $baz): string
{
assert($bar !== null || $baz !== null);

// In this case, PHPStan can resolve that $baz must be string and is OK.
return $bar ?? $baz;
}

function doBar() {
echo foo1(null, 'a');
echo foo2(null, 'a');
}
22 changes: 22 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-9580.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Bug9580;


function test(): int|string|float|null
{
return $_GET['value'];
}

function onlyNull(null $value): void
{

}

function doFoo() {
$value = test();
if (isset($value)) {
exit;
}
onlyNull($value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -568,4 +568,10 @@ public function testWritingReadonlyProperty(): void
]);
}

public function testBug8190(): void
{
$this->checkExplicitMixed = true;
$this->analyse([__DIR__ . '/data/bug-8190.php'], []);
}

}
57 changes: 57 additions & 0 deletions tests/PHPStan/Rules/Properties/data/bug-8190.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php // lint >= 7.4

namespace Bug8190;

/**
* @phpstan-type OwnerBackup array{name: string, isTest?: bool}
*/
class ClassA
{
/** @var OwnerBackup */
public array $ownerBackup;

/**
* @param OwnerBackup|null $ownerBackup
*/
public function __construct(?array $ownerBackup)
{
$this->ownerBackup = $ownerBackup ?? [
'name' => 'Deleted',
];
}


/**
* @param OwnerBackup|null $ownerBackup
*/
public function setOwnerBackup(?array $ownerBackup): void
{
$this->ownerBackup = $ownerBackup ?: [
'name' => 'Deleted',
];
}

/**
* @param OwnerBackup|null $ownerBackup
*/
public function setOwnerBackupWorksForSomeReason(?array $ownerBackup): void
{
$this->ownerBackup = $ownerBackup !== null ? $ownerBackup : [
'name' => 'Deleted',
];
}

/**
* @param OwnerBackup|null $ownerBackup
*/
public function setOwnerBackupAlsoWorksForSomeReason(?array $ownerBackup): void
{
if ($ownerBackup) {
$this->ownerBackup = $ownerBackup;
} else {
$this->ownerBackup = [
'name' => 'Deleted',
];
}
}
}

0 comments on commit b58f2c8

Please sign in to comment.