Skip to content

Commit

Permalink
Merge pull request #7200 from klimick/fix-closure-param-type-inferenc…
Browse files Browse the repository at this point in the history
…e-generic-context
  • Loading branch information
weirdan authored Dec 27, 2021
2 parents fb56d5c + 3d212c6 commit 66b5d60
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -405,13 +405,28 @@ function ($lower_bounds) use ($codebase) {
if ($replaced_type_part instanceof TCallable
|| $replaced_type_part instanceof TClosure
) {
if (isset($replaced_type_part->params[$closure_param_offset]->type)
&& !$replaced_type_part->params[$closure_param_offset]->type->hasTemplate()
) {
if (isset($replaced_type_part->params[$closure_param_offset]->type)) {
$replaced_param_type = $replaced_type_part->params[$closure_param_offset]->type;

if ($replaced_param_type->hasTemplate()) {
$replaced_param_type = TypeExpander::expandUnion(
$codebase,
$replaced_param_type,
null,
null,
null,
true,
false,
false,
true,
true
);
}

if ($param_storage->type && !$param_type_inferred) {
$type_match_found = UnionTypeComparator::isContainedBy(
$codebase,
$replaced_type_part->params[$closure_param_offset]->type,
$replaced_param_type,
$param_storage->type
);

Expand All @@ -422,7 +437,7 @@ function ($lower_bounds) use ($codebase) {

$newly_inferred_type = Type::combineUnionTypes(
$newly_inferred_type,
$replaced_type_part->params[$closure_param_offset]->type,
$replaced_param_type,
$codebase
);
}
Expand Down
72 changes: 72 additions & 0 deletions tests/CallableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,42 @@ public function __invoke(Closure ...$_fn): int
'error_levels' => [],
'7.4',
],
'inferArgFromClassContextInGenericContext' => [
'<?php
/**
* @template A
*/
final class ArrayList
{
/**
* @template B
* @param Closure(A): B $ab
* @return ArrayList<B>
*/
public function map(Closure $ab): ArrayList
{
throw new RuntimeException("???");
}
}
/**
* @template T
* @param ArrayList<T> $list
* @return ArrayList<array{T}>
*/
function asTupled(ArrayList $list): ArrayList
{
return $list->map(function ($_a) {
return [$_a];
});
}
/** @var ArrayList<int> $a */
$a = new ArrayList();
$b = asTupled($a);',
'assertions' => [
'$b' => 'ArrayList<array{int}>',
],
],
'varReturnType' => [
'<?php
$add_one = function(int $a) : int {
Expand Down Expand Up @@ -1282,6 +1318,42 @@ function c(string $c): void {
c("hii");',
'error_message' => 'InvalidArgument',
],
'mismatchParamTypeFromDocblock' => [
'<?php
/**
* @template A
*/
final class ArrayList
{
/**
* @template B
* @param Closure(A): B $effect
* @return ArrayList<B>
*/
public function map(Closure $effect): ArrayList
{
throw new RuntimeException("???");
}
}
/**
* @template T
* @template B
*
* @param ArrayList<T> $list
* @return ArrayList<array{T}>
*/
function genericContext(ArrayList $list): ArrayList
{
return $list->map(
/** @param B $_a */
function ($_a) {
return [$_a];
}
);
}',
'error_message' => 'InvalidArgument',
]
];
}
}

0 comments on commit 66b5d60

Please sign in to comment.