Skip to content

Commit 894acfe

Browse files
VincentLangletphpstan-bot
authored andcommitted
Fix settype() not handled properly for non-constant type strings
- When settype()'s second argument is a non-constant string, broaden the variable type to all possible settype outcomes (bool|int|float|string|array|object|null) - Previously, non-constant type strings caused the extension to return empty SpecifiedTypes, leaving the variable type unchanged - New regression test in tests/PHPStan/Analyser/nsrt/bug-3250.php
1 parent 7b8a821 commit 894acfe

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

src/Type/Php/SetTypeFunctionTypeSpecifyingExtension.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@
1010
use PHPStan\Analyser\TypeSpecifierContext;
1111
use PHPStan\DependencyInjection\AutowiredService;
1212
use PHPStan\Reflection\FunctionReflection;
13+
use PHPStan\Type\ArrayType;
14+
use PHPStan\Type\BooleanType;
1315
use PHPStan\Type\ErrorType;
16+
use PHPStan\Type\FloatType;
1417
use PHPStan\Type\FunctionTypeSpecifyingExtension;
18+
use PHPStan\Type\IntegerType;
19+
use PHPStan\Type\MixedType;
1520
use PHPStan\Type\NullType;
1621
use PHPStan\Type\ObjectType;
22+
use PHPStan\Type\StringType;
1723
use PHPStan\Type\TypeCombinator;
1824
use stdClass;
1925
use function count;
@@ -41,7 +47,20 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
4147

4248
$constantStrings = $castType->getConstantStrings();
4349
if (count($constantStrings) < 1) {
44-
return new SpecifiedTypes();
50+
return $this->typeSpecifier->create(
51+
$value,
52+
TypeCombinator::union(
53+
new BooleanType(),
54+
new IntegerType(),
55+
new FloatType(),
56+
new StringType(),
57+
new ArrayType(new MixedType(), new MixedType()),
58+
new ObjectType(stdClass::class),
59+
new NullType(),
60+
),
61+
TypeSpecifierContext::createTruthy(),
62+
$scope,
63+
)->setAlwaysOverwriteTypes();
4564
}
4665

4766
$types = [];
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug3250;
4+
5+
use stdClass;
6+
use function PHPStan\Testing\assertType;
7+
8+
function castTo(string $value, string $castTo): void
9+
{
10+
$newValue = $value;
11+
settype($newValue, $castTo);
12+
13+
assertType('array|bool|float|int|stdClass|string|null', $newValue);
14+
}
15+
16+
function castToInt(string $value): void
17+
{
18+
$newValue = $value;
19+
settype($newValue, 'int');
20+
21+
assertType('int', $newValue);
22+
}
23+
24+
/**
25+
* @param 'int'|'float' $castTo
26+
*/
27+
function castToIntOrFloat(string $value, string $castTo): void
28+
{
29+
$newValue = $value;
30+
settype($newValue, $castTo);
31+
32+
assertType('float|int', $newValue);
33+
}

0 commit comments

Comments
 (0)