Skip to content

preg_match param-out is a list, and phpstan kind of agrees, but not enough #12397

@rudiedirkx

Description

@rudiedirkx

Bug report

The $match param-out in preg_match($pattern, $string, $match) is always a list (unless named capture groups). Phpstan kind of knows that:

Dumped type: array{0?: string, 1?: non-falsy-string, 2?: numeric-string}

But that's not exactly a list, so it complains when I return that when a list<string> is expected.

I think it's impossible to get a $match where 0 and 2 are set, but 1 is not. And other non-list combinations. PregMatchParameterOutTypeExtension and RegexArrayShapeMatcher should know that.

Code snippet that reproduces the problem

https://phpstan.org/r/5efc781a-6381-4d1b-ac96-cd96f373ece4

Expected output

This exact example is fine, because Phpstan doesn't complain about the return value, but without the if breakout, it does complain, and that's wrong IMO. Even without knowing the preg_match return value, we know that $match is a list.

Unless I am mistaken, and it IS possible to get a non-list array. But I don't think so. See Playground example too. Without the breakout if, Phpstan complains, even though an empty array is a perfectly valid list<string>. And after the if $match is a known list?? something is off here.

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