Skip to content

Commit c191148

Browse files
committed
More precise types after assignment when strict-types=0
1 parent 6b6c9c4 commit c191148

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5647,6 +5647,12 @@ static function (): void {
56475647
TypeCombinator::intersect($assignedExprType->toCoercedArgumentType(true), $propertyNativeType),
56485648
TypeCombinator::intersect($assignedNativeType->toCoercedArgumentType(true), $propertyNativeType),
56495649
);
5650+
} elseif (TypeCombinator::containsNull($propertyNativeType) && !TypeCombinator::containsNull($assignedNativeType)) {
5651+
$scope = $scope->assignExpression(
5652+
$var,
5653+
TypeCombinator::removeNull($propertyReflection->hasPhpDocType() ? $propertyReflection->getPhpDocType() : $propertyNativeType),
5654+
TypeCombinator::removeNull($propertyNativeType),
5655+
);
56505656
}
56515657
} else {
56525658
$scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr));
@@ -5735,6 +5741,12 @@ static function (): void {
57355741
TypeCombinator::intersect($assignedExprType->toCoercedArgumentType(true), $propertyNativeType),
57365742
TypeCombinator::intersect($assignedNativeType->toCoercedArgumentType(true), $propertyNativeType),
57375743
);
5744+
} elseif (TypeCombinator::containsNull($propertyNativeType) && !TypeCombinator::containsNull($assignedNativeType)) {
5745+
$scope = $scope->assignExpression(
5746+
$var,
5747+
TypeCombinator::removeNull($propertyReflection->hasPhpDocType() ? $propertyReflection->getPhpDocType() : $propertyNativeType),
5748+
TypeCombinator::removeNull($propertyNativeType),
5749+
);
57385750
}
57395751
} else {
57405752
$scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr));

tests/PHPStan/Analyser/nsrt/remember-non-nullable-property-non-strict.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,41 @@ public function doFoo(): void {
8686
function getInt(): int {
8787
return 1;
8888
}
89+
90+
91+
interface ObjectDataMapper
92+
{
93+
/**
94+
* @template OutType of object
95+
*
96+
* @param literal-string&class-string<OutType> $class
97+
* @param mixed $data
98+
*
99+
* @return OutType
100+
*
101+
* @throws DataMappingException
102+
*/
103+
public function map(string $class, $data): object;
104+
}
105+
106+
final class ApiProductController
107+
{
108+
109+
protected ?SearchProductsVM $searchProductsVM = null;
110+
111+
protected static ?SearchProductsVM $searchProductsVMStatic = null;
112+
113+
public function search(ObjectDataMapper $dataMapper): void
114+
{
115+
$this->searchProductsVM = $dataMapper->map(SearchProductsVM::class, $_REQUEST);
116+
assertType('RememberNonNullablePropertyWhenStrictTypesDisabled\SearchProductsVM', $this->searchProductsVM);
117+
}
118+
119+
public function searchStatic(ObjectDataMapper $dataMapper): void
120+
{
121+
self::$searchProductsVMStatic = $dataMapper->map(SearchProductsVM::class, $_REQUEST);
122+
assertType('RememberNonNullablePropertyWhenStrictTypesDisabled\SearchProductsVM', self::$searchProductsVMStatic);
123+
}
124+
}
125+
126+
class SearchProductsVM {}

0 commit comments

Comments
 (0)