Skip to content

Commit

Permalink
Do not add null to a template type for a default parameter value null
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Mar 5, 2022
1 parent 2a0dccb commit 7a66cb6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/Reflection/Php/PhpParameterReflection.php
Expand Up @@ -6,6 +6,7 @@
use PHPStan\Reflection\PassedByReference;
use PHPStan\Type\ConstantTypeHelper;
use PHPStan\Type\MixedType;
use PHPStan\Type\NullType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypehintHelper;
Expand Down Expand Up @@ -43,7 +44,11 @@ public function getType(): Type
$phpDocType = $this->phpDocType;
if ($phpDocType !== null) {
try {
if ($this->reflection->isDefaultValueAvailable() && $this->reflection->getDefaultValue() === null) {
if (
$this->reflection->isDefaultValueAvailable()
&& $this->reflection->getDefaultValue() === null
&& (new NullType())->isSuperTypeOf($phpDocType)->no()
) {
$phpDocType = TypeCombinator::addNull($phpDocType);
}
} catch (Throwable) {
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -767,6 +767,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5668.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/generics-empty-array.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5757.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6584.php');
}

/**
Expand Down
44 changes: 44 additions & 0 deletions tests/PHPStan/Analyser/data/bug-6584.php
@@ -0,0 +1,44 @@
<?php

namespace Bug6584;

use function PHPStan\Testing\assertType;

class Foo
{

public function doFoo(int $int, ?int $intOrNull)
{
assertType('int', $this->same($int));
assertType('int', $this->sameWithDefault($int));

assertType('int|null', $this->same($intOrNull));
assertType('int|null', $this->sameWithDefault($intOrNull));

assertType('null', $this->same(null));
assertType('null', $this->sameWithDefault(null));
assertType('null', $this->sameWithDefault());
}


/**
* @template T
* @param T $t
* @return T
*/
function same($t) {
assertType('T (method Bug6584\Foo::same(), argument)', $t);
return $t;
}

/**
* @template T
* @param T $t
* @return T
*/
function sameWithDefault($t = null) {
assertType('T (method Bug6584\Foo::sameWithDefault(), argument)', $t);
return $t;
}

}

0 comments on commit 7a66cb6

Please sign in to comment.