Skip to content

Commit 0af1609

Browse files
committed
Allow concatenation between (string|int) and similar types
Fixes #11337
1 parent 81c8a77 commit 0af1609

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ private static function analyzeOperand(
466466

467467
if (!$operand_type_match
468468
&& (!$comparison_result->scalar_type_match_found
469-
|| (!$operand_type->isInt() && $config->strict_binary_operands)
469+
|| (!$operand_type->isConcatSafe() && $config->strict_binary_operands)
470470
)
471471
) {
472472
if ($has_valid_operand) {

src/Psalm/Type/UnionTrait.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Psalm\StatementsSource;
1919
use Psalm\Storage\FileStorage;
2020
use Psalm\Type\Atomic\TArray;
21+
use Psalm\Type\Atomic\TArrayKey;
2122
use Psalm\Type\Atomic\TCallable;
2223
use Psalm\Type\Atomic\TClassString;
2324
use Psalm\Type\Atomic\TClassStringMap;
@@ -766,7 +767,7 @@ public function hasTemplate(): bool
766767
if ($t instanceof TTemplateParam) {
767768
return true;
768769
}
769-
770+
770771
if ($t instanceof TNamedObject) {
771772
foreach ($t->extra_types as $sub) {
772773
if ($sub instanceof TTemplateParam) {
@@ -1117,6 +1118,23 @@ public function isSingleStringLiteral(): bool
11171118
return count($this->types) === 1 && count($this->literal_string_types) === 1;
11181119
}
11191120

1121+
1122+
/**
1123+
* @psalm-mutation-free
1124+
* @return bool true if this type is a safe operand for string concatenation (int|string|array-key)
1125+
*/
1126+
public function isConcatSafe(): bool
1127+
{
1128+
foreach ($this->types as $type) {
1129+
if (!($type instanceof TInt)
1130+
&& !($type instanceof TString)
1131+
&& !($type instanceof TArrayKey)) {
1132+
return false;
1133+
}
1134+
}
1135+
return true;
1136+
}
1137+
11201138
/**
11211139
* @throws InvalidArgumentException if isSingleStringLiteral is false
11221140
* @psalm-mutation-free

0 commit comments

Comments
 (0)