phpstan / phpstan

PHP Static Analysis Tool - discover bugs in your code without running it!
https://phpstan.org/
MIT License
12.92k stars 883 forks source link

Type mismatch with literal-string is reported on higher level than others #10930

Open integer opened 6 months ago

integer commented 6 months ago

Bug report

Function like /** @param int $a */ function barInt($a): void { } must be called with int parameter. When string is given, we get error Parameter #1 $a of function barInt expects int, string given. on level 5.

Similarly for annotated class-string (see linked snippet).

For annotated literal-string there is error reported only on level 7 and higher.

I understand why this is reported only with parameter checkUnionTypes: true but from user perspective it is as same error as sending string into class-string

Code snippet that reproduces the problem

https://phpstan.org/r/86fb5a64-e35e-4c40-9cd9-7560f2cc8d8f

Expected output

string into literal-string is as same type of error as string into class-string so they should be reported on same level. Expected output should be: 3 errors reported on level 5.

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

No response

ondrejmirtes commented 6 months ago

I agree these should be reported on the same level but I steer more towards level 7. My reasoning: level 5 is about types that are definitely wrong, like string passed into int. So level 5 is about "proving incorrectness".

But string passed into class-string or literal-string might be wrong. Because the string might actually be literal-string or class-string. And level 7 is about these "maybes", thanks to checkUnionTypes: true and reportMaybes: true.

The reason why is this currently inconsistent is because literal-string is implemented as an AccessoryType, meaning literal-string is actually an IntersectionType of StringType and AccessoryLiteralStringType. But class-string is just a single class called ClassStringType.

As I always point out in issues like these is that you should be aware that unless you're on the highest level, you're always missing out on potential errors :) Personally I feel quite safe on level 8, level 9 is too brutal for me. But level 7 will definitely show a lot of useful errors when compared to level 5.