Skip to content

Commit bf09af9

Browse files
committed
Add TemplateNullType
This fixes issues like #13048. Currently, T of (A|null) subtracted by A is T of mixed
1 parent 76045f5 commit bf09af9

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

phpstan-baseline.neon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,12 @@ parameters:
12391239
count: 3
12401240
path: src/Type/Generic/TemplateIterableType.php
12411241

1242+
-
1243+
message: '#^Doing instanceof PHPStan\\Type\\IntersectionType is error\-prone and deprecated\.$#'
1244+
identifier: phpstanApi.instanceofType
1245+
count: 3
1246+
path: src/Type/Generic/TemplateNullType.php
1247+
12421248
-
12431249
message: '#^Doing instanceof PHPStan\\Type\\IntersectionType is error\-prone and deprecated\.$#'
12441250
identifier: phpstanApi.instanceofType
@@ -1335,6 +1341,12 @@ parameters:
13351341
count: 1
13361342
path: src/Type/Generic/TemplateTypeFactory.php
13371343

1344+
-
1345+
message: '#^Doing instanceof PHPStan\\Type\\NullType is error\-prone and deprecated\. Use Type\:\:isNull\(\) instead\.$#'
1346+
identifier: phpstanApi.instanceofType
1347+
count: 1
1348+
path: src/Type/Generic/TemplateTypeFactory.php
1349+
13381350
-
13391351
message: '#^Doing instanceof PHPStan\\Type\\ObjectShapeType is error\-prone and deprecated\. Use Type\:\:isObject\(\) and Type\:\:hasProperty\(\) instead\.$#'
13401352
identifier: phpstanApi.instanceofType

src/Type/Generic/TemplateNullType.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPStan\Type\Generic;
6+
7+
use PHPStan\Type\NullType;
8+
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
9+
use PHPStan\Type\Type;
10+
11+
final class TemplateNullType extends NullType implements TemplateType
12+
{
13+
/** @use TemplateTypeTrait<NullType> */
14+
use TemplateTypeTrait;
15+
use UndecidedComparisonCompoundTypeTrait;
16+
17+
18+
/**
19+
* @param non-empty-string $name
20+
*/
21+
public function __construct(
22+
TemplateTypeScope $scope,
23+
TemplateTypeStrategy $templateTypeStrategy,
24+
TemplateTypeVariance $templateTypeVariance,
25+
string $name,
26+
NullType $bound,
27+
?Type $default,
28+
)
29+
{
30+
parent::__construct();
31+
$this->scope = $scope;
32+
$this->strategy = $templateTypeStrategy;
33+
$this->variance = $templateTypeVariance;
34+
$this->name = $name;
35+
$this->bound = $bound;
36+
$this->default = $default;
37+
}
38+
}

src/Type/Generic/TemplateTypeFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPStan\Type\IterableType;
1616
use PHPStan\Type\KeyOfType;
1717
use PHPStan\Type\MixedType;
18+
use PHPStan\Type\NullType;
1819
use PHPStan\Type\ObjectShapeType;
1920
use PHPStan\Type\ObjectType;
2021
use PHPStan\Type\ObjectWithoutClassType;
@@ -112,6 +113,10 @@ public static function create(TemplateTypeScope $scope, string $name, ?Type $bou
112113
return new TemplateIterableType($scope, $strategy, $variance, $name, $bound, $default);
113114
}
114115

116+
if ($bound instanceof NullType && ($boundClass === NullType::class || $bound instanceof TemplateType)) {
117+
return new TemplateNullType($scope, $strategy, $variance, $name, $bound, $default);
118+
}
119+
115120
return new TemplateMixedType($scope, $strategy, $variance, $name, new MixedType(true), $default);
116121
}
117122

0 commit comments

Comments
 (0)