Skip to content

Commit 9b73ecc

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 9b73ecc

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

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)