Skip to content

Commit 53fb00a

Browse files
authored
Merge branch 'stable' into bedrock-1.21.80
2 parents 4b85e57 + d789c75 commit 53fb00a

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

phpstan.neon.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rules:
1515
- pocketmine\phpstan\rules\DisallowEnumComparisonRule
1616
- pocketmine\phpstan\rules\DisallowForeachByReferenceRule
1717
- pocketmine\phpstan\rules\ExplodeLimitRule
18-
- pocketmine\phpstan\rules\UnsafeForeachArrayOfStringRule
18+
- pocketmine\phpstan\rules\UnsafeForeachRule
1919
# - pocketmine\phpstan\rules\ThreadedSupportedTypesRule
2020

2121
parameters:

tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php renamed to tests/phpstan/rules/UnsafeForeachRule.php

+25-18
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
/**
4242
* @implements Rule<Foreach_>
4343
*/
44-
final class UnsafeForeachArrayOfStringRule implements Rule{
44+
final class UnsafeForeachRule implements Rule{
4545

4646
public function getNodeType() : string{
4747
return Foreach_::class;
@@ -73,7 +73,7 @@ public function processNode(Node $node, Scope $scope) : array{
7373
$benevolentUnionDepth--;
7474
return $result;
7575
}
76-
if($type instanceof IntegerType && $benevolentUnionDepth === 0){
76+
if($type instanceof IntegerType){
7777
$expectsIntKeyTypes = true;
7878
return $type;
7979
}
@@ -87,24 +87,31 @@ public function processNode(Node $node, Scope $scope) : array{
8787
$hasCastableKeyTypes = true;
8888
return $type;
8989
});
90-
if($hasCastableKeyTypes && !$expectsIntKeyTypes){
91-
$tip = $implicitType ?
92-
sprintf(
93-
"Declare a key type using @phpstan-var or @phpstan-param, or use %s() to promote the key type to get proper error reporting",
90+
$errors = [];
91+
if($implicitType){
92+
$errors[] = RuleErrorBuilder::message("Possible unreported errors in foreach on array with unspecified key type.")
93+
->tip(sprintf(
94+
<<<TIP
95+
PHPStan might not be reporting some type errors if the key type is not specified.
96+
Declare a key type using @phpstan-var or @phpstan-param, or use %s() to force PHPStan to report proper errors.
97+
TIP,
9498
Utils::getNiceClosureName(Utils::promoteKeys(...))
95-
) :
96-
sprintf(
97-
"Use %s() to get a \Generator that will force the keys to string",
98-
Utils::getNiceClosureName(Utils::stringifyKeys(...)),
99-
);
100-
return [
101-
RuleErrorBuilder::message(sprintf(
102-
"Unsafe foreach on array with key type %s (they might be casted to int).",
103-
$iterableType->getIterableKeyType()->describe(VerbosityLevel::value())
104-
))->tip($tip)->identifier('pocketmine.foreach.stringKeys')->build()
105-
];
99+
))->identifier('pocketmine.foreach.implicitKeys')->build();
100+
}
101+
if($hasCastableKeyTypes && !$expectsIntKeyTypes){
102+
$errors[] = RuleErrorBuilder::message(sprintf(
103+
"Unsafe foreach on array with key type %s.",
104+
$iterableType->getIterableKeyType()->describe(VerbosityLevel::value())
105+
))
106+
->tip(sprintf(
107+
<<<TIP
108+
PHP coerces numeric strings to integers when used as array keys, which can lead to unexpected type errors when passing the key to a function.
109+
Use %s() to wrap the array in a \Generator that will force the keys back to string during iteration.
110+
TIP,
111+
Utils::getNiceClosureName(Utils::stringifyKeys(...))
112+
))->identifier('pocketmine.foreach.stringKeys')->build();
106113
}
107-
return [];
114+
return $errors;
108115
}
109116

110117
}

0 commit comments

Comments
 (0)