Skip to content

Commit c26886d

Browse files
rvanvelzenondrejmirtes
authored andcommitted
Prevent resolving conditional types in callable param/return types
1 parent 3e52bb0 commit c26886d

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

Diff for: src/Type/TypeUtils.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -411,11 +411,22 @@ public static function containsTemplateType(Type $type): bool
411411

412412
public static function resolveLateResolvableTypes(Type $type, bool $resolveUnresolvableTypes = true): Type
413413
{
414-
return TypeTraverser::map($type, static function (Type $type, callable $traverse) use ($resolveUnresolvableTypes): Type {
415-
while ($type instanceof LateResolvableType && ($resolveUnresolvableTypes || $type->isResolvable())) {
414+
/** @var int $ignoreResolveUnresolvableTypesLevel */
415+
$ignoreResolveUnresolvableTypesLevel = 0;
416+
417+
return TypeTraverser::map($type, static function (Type $type, callable $traverse) use ($resolveUnresolvableTypes, &$ignoreResolveUnresolvableTypesLevel): Type {
418+
while ($type instanceof LateResolvableType && (($resolveUnresolvableTypes && $ignoreResolveUnresolvableTypesLevel === 0) || $type->isResolvable())) {
416419
$type = $type->resolve();
417420
}
418421

422+
if ($type instanceof CallableType || $type instanceof ClosureType) {
423+
$ignoreResolveUnresolvableTypesLevel++;
424+
$result = $traverse($type);
425+
$ignoreResolveUnresolvableTypesLevel--;
426+
427+
return $result;
428+
}
429+
419430
return $traverse($type);
420431
});
421432
}

Diff for: tests/PHPStan/Analyser/nsrt/bug-11472.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php declare(strict_types = 1); // lint >= 8.1
2+
3+
namespace Bug11472;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @phpstan-return ($maybeFoo is 'foo' ? true : false)
9+
*/
10+
function isFoo(mixed $maybeFoo): bool
11+
{
12+
return $maybeFoo === 'foo';
13+
}
14+
15+
function (): void {
16+
assertType('true', isFoo('foo'));
17+
assertType('true', isFoo(...)('foo'));
18+
};

0 commit comments

Comments
 (0)