Skip to content

Propagate @phpstan-assert-* annotations to First-class callables (Closures) and string callables #14249

@uekann

Description

@uekann

Feature request

Description

Currently, type assertions like @phpstan-assert-if-true work perfectly for direct function calls. However, when a function is converted to a First-class callable (...), it becomes a Closure and loses its original assertion metadata. The same limitation applies to string callables.

It would be a great feature if PHPStan could propagate or retain these assertion definitions within the resulting Closure type so that type narrowing works even when the function is invoked dynamically.

Playground

https://phpstan.org/r/3b0c30b7-5eba-4fb2-89df-02ee7a8c8d2d

Expected Result

PHPStan should ideally be able to track the @phpstan-assert-if-true metadata on the created Closure (or callable), narrowing the type of $v to int<1, max> successfully without emitting errors.

Actual Result

The assertion context is not preserved, resulting in the following errors:

  23     Expected type int<1, max>, actual: mixed
         🪪  phpstan.type (non-ignorable)
  27     Expected type int<1, max>, actual: mixed
         🪪  phpstan.type (non-ignorable)

Did PHPStan help you today? Did it make you happy in any way?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions