psalm icon indicating copy to clipboard operation
psalm copied to clipboard

Allow for validation guards without complaining

Open bwoebi opened this issue 1 year ago • 3 comments

While psalm is absolutely correct in deducing that with the annotated type the condition cannot ever be true, it's annoying for library authors to suppress the psalm errors, as the goal is to provide some runtime safety for users who might not use psalm. Or even just catch cases where the psalm static analysis failed (or was erroneously suppressed).

I found it an especially common pattern with ranges like positive-int.

https://psalm.dev/r/ad2a2cb6dd

I would propose that any branches which unconditionally throw (i.e. cause a never return type for the branch) - if the function as a whole doesn't unconditionally throw, the guards are accepted as valid by psalm.

I could also imagine this feature request being implemented as a psalm.xml option rather than just ignoring it by default.

bwoebi avatar Feb 06 '24 23:02 bwoebi

I found these snippets:

https://psalm.dev/r/ad2a2cb6dd
<?php

/**
 * @param positive-int $i
 * @return negative-int
 */
function returnsNegativeInt(int $i): int {
    if ($i <= 0) {
        throw new \Error("Invalid argument $i");
    }
    return -$i;
}
Psalm output (using commit 4b2c698):

ERROR: DocblockTypeContradiction - 8:9 - Docblock-defined type int<1, max> for $i is always >= 0

ERROR: InvalidCast - 9:44 - never cannot be cast to string

psalm-github-bot[bot] avatar Feb 06 '24 23:02 psalm-github-bot[bot]

(Nitpick: Docblock-defined type int<1, max> for $i is always >= 0 also should read is always > 0 or >= 1)

bwoebi avatar Feb 06 '24 23:02 bwoebi

Yeah that's quite on common on codebases of libraries, usable by users without a static analyzer to catch misuses of APIs.

A good idea would be to enable the behavior only on checks made on parameters of functions/methods that are public API, only for docblock-originated types, not types enforced by runtime typehints.

danog avatar Feb 06 '24 23:02 danog