Skip to content

Commit 251d1f7

Browse files
committed
Scope - fix specifyExpressionType+removeTypeFromExpression for native types
1 parent e5eca6b commit 251d1f7

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/Analyser/MutatingScope.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2680,10 +2680,15 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
26802680

26812681
public function removeTypeFromExpression(Expr $expr, Type $type): self
26822682
{
2683-
return $this->specifyExpressionType(
2683+
$scope = $this->specifyExpressionType(
26842684
$expr,
26852685
TypeCombinator::remove($this->getType($expr), $type)
26862686
);
2687+
if ($expr instanceof Variable && is_string($expr->name)) {
2688+
$scope->nativeExpressionTypes[sprintf('$%s', $expr->name)] = TypeCombinator::remove($this->getNativeType($expr), $type);
2689+
}
2690+
2691+
return $scope;
26872692
}
26882693

26892694
/**
@@ -2742,10 +2747,11 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
27422747
$expr = $typeSpecification['expr'];
27432748
$type = $typeSpecification['type'];
27442749
if ($typeSpecification['sure']) {
2745-
if (!$specifiedTypes->shouldOverwrite()) {
2746-
$type = TypeCombinator::intersect($type, $this->getType($expr));
2750+
$scope = $scope->specifyExpressionType($expr, $specifiedTypes->shouldOverwrite() ? $type : TypeCombinator::intersect($type, $this->getType($expr)));
2751+
2752+
if ($expr instanceof Variable && is_string($expr->name)) {
2753+
$scope->nativeExpressionTypes[sprintf('$%s', $expr->name)] = $specifiedTypes->shouldOverwrite() ? $type : TypeCombinator::intersect($type, $this->getNativeType($expr));
27472754
}
2748-
$scope = $scope->specifyExpressionType($expr, $type);
27492755
} else {
27502756
$scope = $scope->removeTypeFromExpression($expr, $type);
27512757
}

tests/PHPStan/Analyser/data/native-types.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,40 @@ public function doForeachArrayDestructuring(array $array)
138138
}
139139
}
140140

141+
/**
142+
* @param \DateTimeImmutable $date
143+
*/
144+
public function doIfElse(\DateTimeInterface $date): void
145+
{
146+
if ($date instanceof \DateTimeInterface) {
147+
assertType(\DateTimeImmutable::class, $date);
148+
assertNativeType(\DateTimeInterface::class, $date);
149+
} else {
150+
assertType('*NEVER*', $date);
151+
assertNativeType('*NEVER*', $date);
152+
}
153+
154+
assertType(\DateTimeImmutable::class, $date);
155+
assertNativeType(\DateTimeInterface::class, $date);
156+
157+
if ($date instanceof \DateTimeImmutable) {
158+
assertType(\DateTimeImmutable::class, $date);
159+
assertNativeType(\DateTimeImmutable::class, $date);
160+
} else {
161+
assertType('*NEVER*', $date);
162+
assertNativeType('DateTimeInterface~DateTimeImmutable', $date);
163+
}
164+
165+
assertType(\DateTimeImmutable::class, $date);
166+
167+
// in reality it works but here the analyser is ran with treatPhpDocTypesAsCertain=true
168+
// assertNativeType(\DateTimeInterface::class, $date);
169+
170+
if ($date instanceof \DateTime) {
171+
172+
}
173+
}
174+
141175
}
142176

143177
/**

0 commit comments

Comments
 (0)