Skip to content

Commit 19e6bbe

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 19e6bbe

File tree

4 files changed

+56
-2
lines changed

4 files changed

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

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

tests/PHPStan/Rules/Comparison/data/bug-13048.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<?php // lint >= 8.0
1+
<?php // lint >= 8.1
22

3-
namespace Bug11852;
3+
namespace Bug13048;
44

55
enum IndexBy {
66
case A;

0 commit comments

Comments
 (0)