Skip to content

Commit 1e8294b

Browse files
committed
Support null templates
1 parent 30f8f1c commit 1e8294b

File tree

8 files changed

+31
-17
lines changed

8 files changed

+31
-17
lines changed

src/Rules/Generics/TemplateTypeCheck.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use PHPStan\Type\IterableType;
2929
use PHPStan\Type\KeyOfType;
3030
use PHPStan\Type\MixedType;
31+
use PHPStan\Type\NullType;
3132
use PHPStan\Type\ObjectShapeType;
3233
use PHPStan\Type\ObjectType;
3334
use PHPStan\Type\ObjectWithoutClassType;
@@ -132,6 +133,7 @@ public function check(
132133
&& $boundTypeClass !== GenericObjectType::class
133134
&& $boundTypeClass !== KeyOfType::class
134135
&& $boundTypeClass !== IterableType::class
136+
&& $boundTypeClass !== NullType::class
135137
&& !$boundType instanceof UnionType
136138
&& !$boundType instanceof IntersectionType
137139
&& !$boundType instanceof TemplateType

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ public function testBug12979(): void
14961496

14971497
public function testBug12095(): void
14981498
{
1499-
$errors = $this->runAnalyse(__DIR__ . '/data/bug-12095.php');
1499+
$errors = $this->runAnalyse(__DIR__ . '/nsrt/bug-12894.php');
15001500
$this->assertNoErrors($errors);
15011501
}
15021502

tests/PHPStan/Analyser/nsrt/bug-12894.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,24 @@
22

33
namespace Bug12894;
44

5+
use Closure;
6+
57
/**
68
* @template TValue of object|null
79
*/
8-
interface Dependency {
10+
interface Dependency
11+
{
12+
913
/**
1014
* @return TValue
1115
*/
1216
public function __invoke(): object|null;
17+
1318
}
1419

15-
interface DependencyResolver {
20+
interface DependencyResolver
21+
{
22+
1623
/**
1724
* @template V of object|null
1825
* @template D of Dependency<V>
@@ -22,12 +29,12 @@ interface DependencyResolver {
2229
* @return V
2330
*/
2431
public function resolve(Dependency $dependency): object|null;
32+
2533
}
2634

27-
/**
28-
* @internal
29-
*/
30-
class Resolver implements DependencyResolver {
35+
class Resolver implements DependencyResolver
36+
{
37+
3138
public function __construct(
3239
/**
3340
* @var Closure(object|null): void
@@ -39,8 +46,11 @@ public function __construct(
3946

4047
public function resolve(Dependency $dependency): object|null {
4148
$resolved = $dependency();
49+
\PHPStan\Testing\assertType('V of object|null (method Bug12894\DependencyResolver::resolve(), argument)', $resolved);
4250
$result = is_object($resolved) ? 1 : 2;
51+
\PHPStan\Testing\assertType('V of object (method Bug12894\DependencyResolver::resolve(), argument)|V of null (method Bug12894\DependencyResolver::resolve(), argument)', $resolved);
4352
($this->run)($resolved);
4453
return $resolved;
4554
}
55+
4656
}

tests/PHPStan/Analyser/nsrt/bug-12989.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
function a(?int $b): ?int
1111
{
1212
if ($b === null) {
13+
\PHPStan\Testing\assertType('null', $b);
1314
return $b;
1415
}
1516
return $b;
1617
}
17-

tests/PHPStan/Analyser/nsrt/template-null-bound.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,20 @@ public function doFoo(?int $p): ?int
1717
return $p;
1818
}
1919

20+
/**
21+
* @template T of null
22+
* @return T
23+
*/
24+
public function nullTemplate(): mixed
25+
{
26+
return null;
27+
}
28+
2029
}
2130

2231
function (Foo $f, ?int $i): void {
2332
assertType('null', $f->doFoo(null));
2433
assertType('1', $f->doFoo(1));
2534
assertType('int|null', $f->doFoo($i));
35+
assertType('null', $f->nullTemplate());
2636
};

tests/PHPStan/Rules/Generics/FunctionTemplateTypeRuleTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ public function testRule(): void
5656
'PHPDoc tag @template T for function FunctionTemplateType\resourceBound() with bound type resource is not supported.',
5757
50,
5858
],
59-
[
60-
'PHPDoc tag @template T for function FunctionTemplateType\nullNotSupported() with bound type null is not supported.',
61-
68,
62-
],
6359
[
6460
'Call-site variance of covariant int in generic type FunctionTemplateType\GenericCovariant<covariant int> in PHPDoc tag @template U is redundant, template type T of class FunctionTemplateType\GenericCovariant has the same variance.',
6561
94,

tests/PHPStan/Rules/Generics/data/function-template.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function nakano()
6565
}
6666

6767
/** @template T of null */
68-
function nullNotSupported()
68+
function nullSupported()
6969
{
7070

7171
}

tests/PHPStan/Rules/PhpDoc/IncompatiblePropertyPhpDocTypeRuleTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,6 @@ public function testGenericCallables(): void
186186
'PHPDoc tag @var template of callable<TypeAlias of mixed>(TypeAlias): TypeAlias cannot have existing type alias TypeAlias as its name.',
187187
26,
188188
],
189-
[
190-
'PHPDoc tag @var template TNull of callable<TNull of null>(TNull): TNull with bound type null is not supported.',
191-
31,
192-
],
193189
[
194190
'PHPDoc tag @var template TInvalid of callable<TInvalid of GenericCallableProperties\Invalid>(TInvalid): TInvalid has invalid bound type GenericCallableProperties\Invalid.',
195191
36,

0 commit comments

Comments
 (0)