Skip to content

Commit d05b694

Browse files
authored
Merge branch refs/heads/1.10.x into 1.11.x
2 parents 5b9eabc + 59c3eaa commit d05b694

File tree

8 files changed

+98
-12
lines changed

8 files changed

+98
-12
lines changed

phpstan-baseline.neon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,8 +1528,8 @@ parameters:
15281528
path: src/Type/Php/SscanfFunctionDynamicReturnTypeExtension.php
15291529

15301530
-
1531-
message: "#^Casting to string something that's already string\\.$#"
1532-
count: 1
1531+
message: "#^Cannot access offset int\\<0, max\\> on \\(float\\|int\\)\\.$#"
1532+
count: 2
15331533
path: src/Type/Php/StrIncrementDecrementFunctionReturnTypeExtension.php
15341534

15351535
-

resources/functionMap_php80delta.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
'str_ends_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
103103
'str_starts_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
104104
'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
105-
'stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
105+
'stripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
106106
'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
107107
'strpos' => ['positive-int|0|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
108108
'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string'],
@@ -241,7 +241,7 @@
241241
'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['?string|?false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'],
242242
'SplFileObject::fgetss' => ['string|false', 'allowable_tags='=>'string'],
243243
'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
244-
'stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
244+
'stripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
245245
'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
246246
'strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
247247
'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int'],

src/Analyser/MutatingScope.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
use PHPStan\Type\DynamicReturnTypeExtensionRegistry;
9797
use PHPStan\Type\ErrorType;
9898
use PHPStan\Type\ExpressionTypeResolverExtensionRegistry;
99+
use PHPStan\Type\FloatType;
99100
use PHPStan\Type\GeneralizePrecision;
100101
use PHPStan\Type\Generic\GenericClassStringType;
101102
use PHPStan\Type\Generic\GenericObjectType;
@@ -1505,7 +1506,7 @@ static function (): void {
15051506
} elseif ($node instanceof Expr\PreInc || $node instanceof Expr\PreDec) {
15061507
$varType = $this->getType($node->var);
15071508
$varScalars = $varType->getConstantScalarValues();
1508-
$stringType = new StringType();
1509+
15091510
if (count($varScalars) > 0) {
15101511
$newTypes = [];
15111512

@@ -1521,9 +1522,24 @@ static function (): void {
15211522
return TypeCombinator::union(...$newTypes);
15221523
} elseif ($varType->isString()->yes()) {
15231524
if ($varType->isLiteralString()->yes()) {
1524-
return new IntersectionType([$stringType, new AccessoryLiteralStringType()]);
1525+
return new IntersectionType([
1526+
new StringType(),
1527+
new AccessoryLiteralStringType(),
1528+
]);
1529+
}
1530+
1531+
if ($varType->isNumericString()->yes()) {
1532+
return new BenevolentUnionType([
1533+
new IntegerType(),
1534+
new FloatType(),
1535+
]);
15251536
}
1526-
return $stringType;
1537+
1538+
return new BenevolentUnionType([
1539+
new StringType(),
1540+
new IntegerType(),
1541+
new FloatType(),
1542+
]);
15271543
}
15281544

15291545
if ($node instanceof Expr\PreInc) {

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2956,19 +2956,19 @@ public function dataBinaryOperations(): array
29562956
'$string--',
29572957
],
29582958
[
2959-
'string',
2959+
'(float|int|string)',
29602960
'++$string',
29612961
],
29622962
[
2963-
'string',
2963+
'(float|int|string)',
29642964
'--$string',
29652965
],
29662966
[
2967-
'string',
2967+
'(float|int|string)',
29682968
'$incrementedString',
29692969
],
29702970
[
2971-
'string',
2971+
'(float|int|string)',
29722972
'$decrementedString',
29732973
],
29742974
[

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,7 @@ public function dataFileAsserts(): iterable
14541454
yield from $this->gatherAssertTypes(__DIR__ . '/data/sort.php');
14551455
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-3312.php');
14561456
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5961.php');
1457+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10122.php');
14571458
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10189.php');
14581459
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10317.php');
14591460
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10302-interface-extends.php');
@@ -1466,6 +1467,7 @@ public function dataFileAsserts(): iterable
14661467
yield from $this->gatherAssertTypes(__DIR__ . '/data/set-type-type-specifying.php');
14671468
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10468.php');
14681469
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6613.php');
1470+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10187.php');
14691471
}
14701472

14711473
/**
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Bug10122;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function doFoo():void
8+
{
9+
function(string $s) {
10+
assertType('(float|int|string)', ++$s);
11+
};
12+
function(string $s) {
13+
assertType('(float|int|string)', --$s);
14+
};
15+
function(string $s) {
16+
assertType('string', $s++);
17+
assertType('(float|int|string)', $s);
18+
};
19+
function(string $s) {
20+
assertType('string', $s--);
21+
assertType('(float|int|string)', $s);
22+
};
23+
24+
function(float $f) {
25+
assertType('float', ++$f);
26+
};
27+
function(float $f) {
28+
assertType('float', --$f);
29+
};
30+
function(float $f) {
31+
assertType('float', $f++);
32+
};
33+
function(float $f) {
34+
assertType('float', $f--);
35+
};
36+
}
37+
38+
/** @param numeric-string $ns */
39+
function doNumericString(string $ns) {
40+
function() use ($ns) {
41+
assertType('(float|int)', ++$ns);
42+
};
43+
function() use ($ns) {
44+
assertType('(float|int)', --$ns);
45+
};
46+
function() use ($ns) {
47+
assertType('numeric-string', $ns++);
48+
assertType('(float|int)', $ns);
49+
};
50+
function() use ($ns) {
51+
assertType('numeric-string', $ns--);
52+
assertType('(float|int)', $ns);
53+
};
54+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug10187;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function inc(string $n): string
8+
{
9+
$before = $n;
10+
$after = ++$n;
11+
assertType('array{n: (float|int|string), before: string, after: (float|int|string)}', compact('n', 'before', 'after'));
12+
13+
return (string)$after; // No warnings expected here
14+
}

tests/PHPStan/Analyser/data/literal-string.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function increment($literalString, string $string)
5757
assertType('literal-string', $literalString);
5858

5959
$string++;
60-
assertType('string', $string);
60+
assertType('(float|int|string)', $string);
6161
}
6262

6363
}

0 commit comments

Comments
 (0)