Skip to content

Commit cbbfa11

Browse files
phpstan-botclaude
andcommitted
Return array explicitly for non-list fetch modes instead of falling back
When the extension returned null for FETCH_KEY_PAIR, FETCH_GROUP, and FETCH_UNIQUE modes, the fallback in MethodCallReturnTypeHelper used a parametersAcceptor selected from named argument variants. On PHP 8.5, the named variants for fetchAll() have only a mode parameter and return list<mixed>, causing incorrect list inference for non-list modes. Fix by having the extension explicitly return array<mixed, mixed> for non-list modes instead of returning null and relying on the fallback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7d0c9f4 commit cbbfa11

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

src/Type/Php/PdoStatementFetchAllReturnTypeExtension.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,33 @@ public function getTypeFromMethodCall(
5454
return null;
5555
}
5656

57+
$isList = true;
5758
foreach ($constantIntegers as $constantInteger) {
5859
$mode = $constantInteger->getValue();
5960
if ($mode === 0 || ($mode & 0xFFFF) === self::FETCH_KEY_PAIR || ($mode & self::FETCH_GROUP) !== 0) {
60-
return null;
61+
$isList = false;
62+
break;
6163
}
6264
}
6365

6466
$variant = ParametersAcceptorSelector::selectFromArgs($scope, $args, $methodReflection->getVariants());
6567
$returnType = $variant->getReturnType();
68+
$canBeFalse = !$returnType->isFalse()->no();
69+
70+
if ($isList) {
71+
$resultType = TypeCombinator::intersect(
72+
new ArrayType(new IntegerType(), new MixedType()),
73+
new AccessoryArrayListType(),
74+
);
75+
} else {
76+
$resultType = new ArrayType(new MixedType(), new MixedType());
77+
}
6678

67-
$listType = TypeCombinator::intersect(
68-
new ArrayType(new IntegerType(), new MixedType()),
69-
new AccessoryArrayListType(),
70-
);
71-
72-
if (!$returnType->isFalse()->no()) {
73-
return TypeCombinator::union($listType, new ConstantBooleanType(false));
79+
if ($canBeFalse) {
80+
return TypeCombinator::union($resultType, new ConstantBooleanType(false));
7481
}
7582

76-
return $listType;
83+
return $resultType;
7784
}
7885

7986
}

0 commit comments

Comments
 (0)