Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion src/Type/Php/ClosureBindDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use PHPStan\Analyser\Scope;
use PHPStan\DependencyInjection\AutowiredService;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\BenevolentUnionType;
use PHPStan\Type\ClosureType;
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
use PHPStan\Type\NullType;
use PHPStan\Type\Type;

#[AutowiredService]
Expand All @@ -32,7 +34,7 @@ public function getTypeFromStaticMethodCall(MethodReflection $methodReflection,
return null;
}

return $closureType;
return new BenevolentUnionType([$closureType, new NullType()]);
}

}
4 changes: 3 additions & 1 deletion src/Type/Php/ClosureBindToDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use PHPStan\Analyser\Scope;
use PHPStan\DependencyInjection\AutowiredService;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\BenevolentUnionType;
use PHPStan\Type\ClosureType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\NullType;
use PHPStan\Type\Type;

#[AutowiredService]
Expand All @@ -32,7 +34,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

return $closureType;
return new BenevolentUnionType([$closureType, new NullType()]);
}

}
25 changes: 25 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-5009.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types = 1);

namespace Bug5009;

use Closure;
use function PHPStan\Testing\assertType;

$foo = function (): void {};
$bar = $foo->bindTo(null);
assertType('((Closure(): void)|null)', $bar);

$baz = Closure::bind($foo, null);
assertType('((Closure(): void)|null)', $baz);

$newThis = new \stdClass();
$bound = $foo->bindTo($newThis);
assertType('((Closure(): void)|null)', $bound);

$staticBound = Closure::bind($foo, $newThis);
assertType('((Closure(): void)|null)', $staticBound);

$bound2 = $foo->bindTo($newThis, 'stdClass');
assertType('((Closure(): void)|null)', $bound2);
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@

$newThis = new class {};
$boundClosure = $closure->bindTo($newThis);
assertType('Closure(object): true', $boundClosure);
assertType('((Closure(object): true)|null)', $boundClosure);

$staticallyBoundClosure = \Closure::bind($closure, $newThis);
assertType('Closure(object): true', $staticallyBoundClosure);
assertType('((Closure(object): true)|null)', $staticallyBoundClosure);

$returnType = $closure->call($newThis, new class {});
assertType('true', $returnType);

$staticallyBoundClosureCaseInsensitive = \closure::bind($closure, $newThis);
assertType('Closure(object): true', $staticallyBoundClosureCaseInsensitive);
assertType('((Closure(object): true)|null)', $staticallyBoundClosureCaseInsensitive);
Loading