psalm icon indicating copy to clipboard operation
psalm copied to clipboard

String variable created in `catch` is mixed type but psalm-trace reports string

Open spaze opened this issue 1 year ago • 2 comments

When a variable is created in catch (Exception $e) it always seems to be of mixed type, but later, @psalm-trace reports correct type, but it cannot be passed to a method that requires the same type that trace reports.

image

This is probably better explained by the code here https://psalm.dev/r/ee865b58ff

It works when I create the variable before the try/catch block with $param = null; like this https://psalm.dev/r/7e897e5348

spaze avatar Mar 04 '24 01:03 spaze

I found these snippets:

https://psalm.dev/r/ee865b58ff
<?php
class Foo
{
    public function __construct(?string $stringOrNullParam) {}
}
try {
    if (rand()) {
        throw new Exception();
    }
} catch (Exception $e) {
    $param = 'a';
}
if (!isset($param)) {
    $param = null; // to highlight trace inconsistency, no change with new Foo($param ?? null)
}
/** @psalm-trace $param */
new Foo($param);
Psalm output (using commit 3600d51):

INFO: MixedArgument - 17:9 - Argument 1 of Foo::__construct cannot be mixed|null, expecting null|string

INFO: Trace - 17:1 - $param: null|string
https://psalm.dev/r/7e897e5348
<?php
class Foo
{
    public function __construct(?string $stringOrNullParam) {}
}
$param = null;
try {
    if (rand()) {
        throw new Exception();
    }
} catch (Exception $e) {
    $param = 'a';
}
/** @psalm-trace $param */
new Foo($param);
Psalm output (using commit 3600d51):

INFO: Trace - 15:1 - $param: 'a'|null

psalm-github-bot[bot] avatar Mar 04 '24 01:03 psalm-github-bot[bot]

but later, @psalm-trace reports correct type

That's because you traced the type after the constructor call. You need to use /** @psalm-trace $param */; (note the semicolon) to trace the variable before the call.

weirdan avatar Mar 04 '24 20:03 weirdan