Skip to content

Commit e20136d

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 e20136d

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
@@ -1251,6 +1251,12 @@ parameters:
12511251
count: 2
12521252
path: src/Type/Generic/TemplateMixedType.php
12531253

1254+
-
1255+
message: '#^Doing instanceof PHPStan\\Type\\IntersectionType is error\-prone and deprecated\.$#'
1256+
identifier: phpstanApi.instanceofType
1257+
count: 3
1258+
path: src/Type/Generic/TemplateNullType.php
1259+
12541260
-
12551261
message: '#^Doing instanceof PHPStan\\Type\\IntersectionType is error\-prone and deprecated\.$#'
12561262
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)