Skip to content

Commit 2ca2364

Browse files
phpstan-botstaabmclaude
committed
Implement Type->toCoercedPropertyType() to replace inline coercion logic
Move int-to-float property coercion from NodeScopeResolver into the Type system as toCoercedPropertyType(), following the same polymorphic pattern as toCoercedArgumentType(). FloatType returns float|int; all other types return $this. Composite types (UnionType, IntersectionType) delegate to their members. Co-authored-by: Markus Staab <staabm@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 561aa97 commit 2ca2364

37 files changed

+183
-6
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6366,13 +6366,8 @@ private function processAssignVar(
63666366
$declaringClass = $propertyReflection->getDeclaringClass();
63676367
if ($declaringClass->hasNativeProperty($propertyName)) {
63686368
$nativeProperty = $declaringClass->getNativeProperty($propertyName);
6369-
$propertyNativeType = $nativeProperty->getNativeType();
6370-
// Widen property type to accept int for float properties (PHP allows int-to-float coercion without TypeError)
6371-
$propertyNativeTypeForAccepts = !$propertyNativeType->isFloat()->no()
6372-
? TypeCombinator::union($propertyNativeType, new IntegerType())
6373-
: $propertyNativeType;
63746369
if (
6375-
!$propertyNativeTypeForAccepts->isSuperTypeOf($assignedExprType)->yes()
6370+
!$nativeProperty->getNativeType()->toCoercedPropertyType()->isSuperTypeOf($assignedExprType)->yes()
63766371
) {
63776372
$throwPoints[] = InternalThrowPoint::createExplicit($scope, new ObjectType(TypeError::class), $assignedExpr, false);
63786373
}

src/Type/Accessory/AccessoryArrayListType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
484484
return $this;
485485
}
486486

487+
public function toCoercedPropertyType(): Type
488+
{
489+
return $this;
490+
}
491+
487492
public function traverse(callable $cb): Type
488493
{
489494
return $this;

src/Type/Accessory/AccessoryLiteralStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
228228
return $this;
229229
}
230230

231+
public function toCoercedPropertyType(): Type
232+
{
233+
return $this;
234+
}
235+
231236
public function isNull(): TrinaryLogic
232237
{
233238
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryLowercaseStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
225225
return $this;
226226
}
227227

228+
public function toCoercedPropertyType(): Type
229+
{
230+
return $this;
231+
}
232+
228233
public function isNull(): TrinaryLogic
229234
{
230235
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryNonEmptyStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
225225
return $this;
226226
}
227227

228+
public function toCoercedPropertyType(): Type
229+
{
230+
return $this;
231+
}
232+
228233
public function isNull(): TrinaryLogic
229234
{
230235
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryNonFalsyStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
228228
return $this;
229229
}
230230

231+
public function toCoercedPropertyType(): Type
232+
{
233+
return $this;
234+
}
235+
231236
public function isNull(): TrinaryLogic
232237
{
233238
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryNumericStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
233233
return $this;
234234
}
235235

236+
public function toCoercedPropertyType(): Type
237+
{
238+
return $this;
239+
}
240+
236241
public function isNull(): TrinaryLogic
237242
{
238243
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryUppercaseStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
225225
return $this;
226226
}
227227

228+
public function toCoercedPropertyType(): Type
229+
{
230+
return $this;
231+
}
232+
228233
public function isNull(): TrinaryLogic
229234
{
230235
return TrinaryLogic::createNo();

src/Type/Accessory/HasOffsetType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
405405
return $this;
406406
}
407407

408+
public function toCoercedPropertyType(): Type
409+
{
410+
return $this;
411+
}
412+
408413
public function getEnumCases(): array
409414
{
410415
return [];

src/Type/Accessory/HasOffsetValueType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,11 @@ public function toCoercedArgumentType(bool $strictTypes): Type
472472
return $this;
473473
}
474474

475+
public function toCoercedPropertyType(): Type
476+
{
477+
return $this;
478+
}
479+
475480
public function getEnumCases(): array
476481
{
477482
return [];

0 commit comments

Comments
 (0)