Skip to content

Commit 28776ff

Browse files
committed
Fix the difference between ?T and T|null
1 parent d26496e commit 28776ff

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

src/PhpDoc/TypeNodeResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ private function resolveThisTypeNode(ThisTypeNode $typeNode, NameScope $nameScop
384384

385385
private function resolveNullableTypeNode(NullableTypeNode $typeNode, NameScope $nameScope): Type
386386
{
387-
return TypeCombinator::addNull($this->resolve($typeNode->type, $nameScope));
387+
return TypeCombinator::union($this->resolve($typeNode->type, $nameScope), new NullType());
388388
}
389389

390390
private function resolveUnionTypeNode(UnionTypeNode $typeNode, NameScope $nameScope): Type

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,10 @@ public function dataFileAsserts(): iterable
786786
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6591.php');
787787
}
788788

789+
if (PHP_VERSION_ID >= 80000) {
790+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6790.php');
791+
}
792+
789793
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6584.php');
790794
}
791795

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php declare(strict_types = 1); // lint >= 8.0
2+
3+
namespace Bug6790;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @template T
9+
*/
10+
class Repository
11+
{
12+
/**
13+
* @param array<T> $items
14+
*/
15+
public function __construct(private array $items) {}
16+
17+
/**
18+
* @return ?T
19+
*/
20+
public function find(string $id)
21+
{
22+
return $this->items[$id] ?? null;
23+
}
24+
}
25+
26+
/**
27+
* @template T
28+
*/
29+
class Repository2
30+
{
31+
/**
32+
* @param array<T> $items
33+
*/
34+
public function __construct(private array $items) {}
35+
36+
/**
37+
* @return T|null
38+
*/
39+
public function find(string $id)
40+
{
41+
return $this->items[$id] ?? null;
42+
}
43+
}
44+
45+
class Foo
46+
{
47+
48+
/**
49+
* @param Repository<string> $r
50+
* @return void
51+
*/
52+
public function doFoo(Repository $r): void
53+
{
54+
assertType('string|null', $r->find('foo'));
55+
}
56+
57+
/**
58+
* @param Repository2<string> $r
59+
* @return void
60+
*/
61+
public function doFoo2(Repository2 $r): void
62+
{
63+
assertType('string|null', $r->find('foo'));
64+
}
65+
66+
}

0 commit comments

Comments
 (0)