Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/Type/IntersectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,23 @@ public function isSubTypeOf(Type $otherType): IsSuperTypeOfResult

public function isAcceptedBy(Type $acceptingType, bool $strictTypes): AcceptsResult
{
$types = $this->types;
if ($this->isCallable()->yes() && $this->isArray()->yes()) {
$narrowedKeyType = $this->getIterableKeyType();
$narrowedValueType = $this->getIterableValueType();
$types = array_map(static function (Type $innerType) use ($narrowedKeyType, $narrowedValueType): Type {
if (!$innerType->isArray()->yes()) {
return $innerType;
}
if (!$innerType->getIterableValueType() instanceof MixedType) {
return $innerType;
}
return new ArrayType($narrowedKeyType, $narrowedValueType);
}, $types);
}

$result = AcceptsResult::lazyMaxMin(
$this->types,
$types,
static fn (Type $innerType) => $acceptingType->accepts($innerType, $strictTypes),
);

Expand Down
17 changes: 17 additions & 0 deletions tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4017,4 +4017,21 @@ public function testBug13272(): void
$this->analyse([__DIR__ . '/data/bug-13272.php'], []);
}

public function testBug14549(): void
{
$this->checkThisOnly = false;
$this->checkNullables = true;
$this->checkUnionTypes = true;
$this->analyse([__DIR__ . '/data/bug-14549.php'], [
[
'Parameter #1 $param of method Bug14549\Foo::call() expects array<int>, array&callable given.',
67,
],
[
'Parameter #1 $param of method Bug14549\Foo::call() expects array<int>, array&callable given.',
75,
],
]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ public function testBug14549(): void
46,
MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP,
],
[
'Method Bug14549\Foo::doBaz() has parameter $task with no signature specified for callable.',
53,
],
[
'Method Bug14549\Foo::doCallWithCallableArray() has parameter $task with no signature specified for callable.',
65,
],
[
'Method Bug14549\Foo::doCallWithCallableAndArray() has parameter $task with no signature specified for callable.',
73,
],
]);
}

Expand Down
28 changes: 28 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-14549.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,34 @@ public function doIntersection($array): void
{
}

/**
* @param callable&array $task
*/
public function doBaz(array $task): void
{
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Removed the doBaz() method from bug-14549.php and its corresponding test expectation in MissingMethodParameterTypehintRuleTest.php. All 11,971 tests pass and make phpstan reports no errors.


/** @param array<int> $param */
public function call(array $param): void
{
}

/**
* @param callable-array $task
*/
public function doCallWithCallableArray(array $task): void
{
$this->call($task);
}

/**
* @param callable&array $task
*/
public function doCallWithCallableAndArray(array $task): void
{
$this->call($task);
}

}


Loading