phpstan / phpstan

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

Throw exception in called method will not change the possible return types #773

Closed pilec closed 6 years ago

pilec commented 6 years ago

https://phpstan.org/r/796b65022c2cccf0d86a95d2a4754b6f

Especially annoying with Dibi. Can be solved by workaround:

private function checkIfExists($user)
{
  if ($user === false) {
    throw UserNotFoundException;
  }

  return $user;
}
hrach commented 6 years ago

That's intentional, analyzer can't do assumptions recursively. If you put the check directly into the code, it will be ok. The same way it would work in other typed languages.

e.g. Kotlin

fun test(): Int {

    val a: Int? = null

    check(a)

    return a
}

fun check(a: Int?) {
    if (a == null) {
        throw NullPointerException()
    }
}

One solution is to introduce null (false) filter function. When generics will be introduced, you could have a general one then.

https://phpstan.org/r/4de432507fa6e7362370b35da0e2417a

hrach commented 6 years ago

Other solution is do an assert manually.

$this->check($user);
assert($user instanceof User);

which is quite similar to !! operator in Kotlin

check(a)
a!!
ondrejmirtes commented 6 years ago

Hi, this is a duplicate of #201, please see the discussion there (and other issues linked in the milestone as well).

pilec commented 6 years ago

Ah, you are right! Sorry for inconvenience, I tried to find similar issue and failed.