Skip to content

Commit 9d91353

Browse files
committed
Don't remember non-nullable properties as nullable
1 parent b3d3386 commit 9d91353

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5625,12 +5625,15 @@ static function (): void {
56255625
$assignedExprType = $scope->getType($assignedExpr);
56265626
$nodeCallback(new PropertyAssignNode($var, $assignedExpr, $isAssignOp), $scope);
56275627
if ($propertyReflection->canChangeTypeAfterAssignment()) {
5628-
if ($propertyReflection->hasNativeType() && $scope->isDeclareStrictTypes()) {
5629-
$propertyNativeType = $propertyReflection->getNativeType();
5628+
$assignedNativeType = $scope->getNativeType($assignedExpr);
5629+
$propertyNativeType = $propertyReflection->getNativeType();
56305630

5631-
$scope = $scope->assignExpression($var, TypeCombinator::intersect($assignedExprType->toCoercedArgumentType(true), $propertyNativeType), TypeCombinator::intersect($scope->getNativeType($assignedExpr)->toCoercedArgumentType(true), $propertyNativeType));
5631+
if ($propertyReflection->hasNativeType() && $scope->isDeclareStrictTypes()) {
5632+
$scope = $scope->assignExpression($var, TypeCombinator::intersect($assignedExprType->toCoercedArgumentType(true), $propertyNativeType), TypeCombinator::intersect($assignedNativeType->toCoercedArgumentType(true), $propertyNativeType));
5633+
} elseif ($propertyNativeType->isNull()->no()) {
5634+
$scope = $scope->assignExpression($var, TypeCombinator::removeNull($assignedExprType), TypeCombinator::removeNull($assignedNativeType));
56325635
} else {
5633-
$scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr));
5636+
$scope = $scope->assignExpression($var, $assignedExprType, $assignedNativeType);
56345637
}
56355638
}
56365639
$declaringClass = $propertyReflection->getDeclaringClass();
@@ -5696,12 +5699,15 @@ static function (): void {
56965699
$assignedExprType = $scope->getType($assignedExpr);
56975700
$nodeCallback(new PropertyAssignNode($var, $assignedExpr, $isAssignOp), $scope);
56985701
if ($propertyReflection !== null && $propertyReflection->canChangeTypeAfterAssignment()) {
5699-
if ($propertyReflection->hasNativeType() && $scope->isDeclareStrictTypes()) {
5700-
$propertyNativeType = $propertyReflection->getNativeType();
5702+
$assignedNativeType = $scope->getNativeType($assignedExpr);
5703+
$propertyNativeType = $propertyReflection->getNativeType();
57015704

5702-
$scope = $scope->assignExpression($var, TypeCombinator::intersect($assignedExprType->toCoercedArgumentType(true), $propertyNativeType), TypeCombinator::intersect($scope->getNativeType($assignedExpr)->toCoercedArgumentType(true), $propertyNativeType));
5705+
if ($propertyReflection->hasNativeType() && $scope->isDeclareStrictTypes()) {
5706+
$scope = $scope->assignExpression($var, TypeCombinator::intersect($assignedExprType->toCoercedArgumentType(true), $propertyNativeType), TypeCombinator::intersect($assignedNativeType->toCoercedArgumentType(true), $propertyNativeType));
5707+
} elseif ($propertyNativeType->isNull()->no()) {
5708+
$scope = $scope->assignExpression($var, TypeCombinator::removeNull($assignedExprType), TypeCombinator::removeNull($assignedNativeType));
57035709
} else {
5704-
$scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr));
5710+
$scope = $scope->assignExpression($var, $assignedExprType, $assignedNativeType);
57055711
}
57065712
}
57075713
} else {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace PropertyNullAfterAssignment;
4+
5+
use function PHPStan\Testing\assertNativeType;
6+
use function PHPStan\Testing\assertType;
7+
8+
class HelloWorld {
9+
private readonly int $i;
10+
11+
public function __construct()
12+
{
13+
$this->i = getIntOrNull();
14+
}
15+
16+
public function doFoo(): void {
17+
assertType('int', $this->i);
18+
assertNativeType('int', $this->i);
19+
}
20+
}
21+
22+
function getIntOrNull(): ?int {
23+
if (rand(0, 1) === 0) {
24+
return null;
25+
}
26+
return 1;
27+
}

0 commit comments

Comments
 (0)