vimeo / psalm

A static analysis tool for finding errors in PHP applications
https://psalm.dev
MIT License
5.58k stars 664 forks source link

(Throwable~PDOException)::getCode() should be an int #8802

Open VincentLanglet opened 2 years ago

VincentLanglet commented 2 years ago

Follow up of https://github.com/vimeo/psalm/pull/7390 https://github.com/vimeo/psalm/pull/7525 https://github.com/vimeo/psalm/pull/7673 @orklah

There is an error in psalm with https://psalm.dev/r/23800504eb but it works fine for phpstan https://phpstan.org/r/014a6319-6af4-4fac-971d-4f4dbb76f57d

Is possible to say to psalm that (Throwable~ PDOException)::getCode() always return an int ?

Current PHPStan implementation: https://github.com/phpstan/phpstan-src/blob/1.9.x/src/Type/Php/ThrowableReturnTypeExtension.php Current Psalm implementation: https://github.com/vimeo/psalm/blob/65c31ce89ebab3d73ad038957ce37163a2307ac4/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php#L102

psalm-github-bot[bot] commented 2 years ago

I found these snippets:

https://psalm.dev/r/23800504eb ```php getCode(); } return 0; } ``` ``` Psalm output (using commit c3cc906): ERROR: InvalidReturnStatement - 5:16 - The inferred type 'int|string' does not match the declared return type 'int' for test ERROR: InvalidReturnType - 3:30 - The declared return type 'int' for test is incorrect, got 'int|string' ```
orklah commented 2 years ago

Psalm can't handle Throwable~PDOException as a type in itself.

This means this can't be handled in Psalm with the current type system: https://phpstan.org/r/0112ebba-a9c6-454d-9182-a0e78fa7d014

However, there is a small trick that we can use for your specific example of Throwable~Exception because it can be transformed into Error and Error::getCode is indeed an int

If you're interested, this could be handled the same way as DateTime/DateTimeImmutable: https://github.com/vimeo/psalm/blob/d0be59e16ef6e55f0349c60eab272947e21a2c11/src/Psalm/Internal/Type/NegatedAssertionReconciler.php#L151

weirdan commented 2 years ago

Can't we access (and evaluate) assertions in MethodCallReturnTypeFetcher?