Skip to content

Incorrect template type inferred from closure #2575

@muglug

Description

@muglug

Bug report

In the code below the type T should not be inferred from the callable param, but from the first arg. Callable params act as an upper bound on the possible type.

Code snippet that reproduces the problem

class C {
	public function foo() : void {}
}

/**
 * @psalm-template T
 * @psalm-param T $t
 * @psalm-param callable(?T):void $callable
 * @return T
 */
function makeConcrete($t, callable $callable) {
	$callable(rand(0, 1) ? $t : null);
	return $t;
}

$c = makeConcrete(new C(), function (?C $c) : void {});
$c->foo();

https://phpstan.org/r/a30bb64f-9723-460b-8d09-33efb3afdc40

Expected output

No issue

Actual output

Cannot call method foo() on C|null

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions