Skip to content

Commit caa4f39

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 caa4f39

File tree

5 files changed

+55
-2
lines changed

5 files changed

+55
-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/TemplateMixedType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types = 1);
1+
<?php declare(strict_types=1);
22

33
namespace PHPStan\Type\Generic;
44

src/Type/Generic/TemplateNullType.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
/** @use TemplateTypeTrait<NullType> */
12+
use TemplateTypeTrait;
13+
use UndecidedComparisonCompoundTypeTrait;
14+
15+
/**
16+
* @param non-empty-string $name
17+
*/
18+
public function __construct(
19+
TemplateTypeScope $scope,
20+
TemplateTypeStrategy $templateTypeStrategy,
21+
TemplateTypeVariance $templateTypeVariance,
22+
string $name,
23+
NullType $bound,
24+
?Type $default,
25+
)
26+
{
27+
parent::__construct();
28+
$this->scope = $scope;
29+
$this->strategy = $templateTypeStrategy;
30+
$this->variance = $templateTypeVariance;
31+
$this->name = $name;
32+
$this->bound = $bound;
33+
$this->default = $default;
34+
}
35+
36+
}

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php // lint >= 8.0
22

3-
namespace Bug11852;
3+
namespace Bug13048;
44

55
enum IndexBy {
66
case A;

0 commit comments

Comments
 (0)