psalm icon indicating copy to clipboard operation
psalm copied to clipboard

Arbitrary static variable initializers are not resolved

Open zmitic opened this issue 11 months ago • 6 comments

Latest 8.3 supports arbitrary static variable initializers but psalm doesn't detect the type. Like in this example, even thought it is valid code.

Isolating value calculation in another method didn't help, example here.

zmitic avatar Mar 02 '24 15:03 zmitic

I found these snippets:

https://psalm.dev/r/ada95c35e3
<?php
/** @template T */
class LazyValue
{
    /** @param Closure(): T $callable */
    public function __construct(private Closure $callable)
    {
    }

    /** @return T */
    public function getValue()
    {
        static $value = ($this->callable)();
        
        return $value;
    }
}
Psalm output (using commit b940c7e):

INFO: MixedReturnStatement - 15:16 - Could not infer a return type
https://psalm.dev/r/5bb476b9d3
<?php
/** @template T */
class LazyValue
{
    /** @param Closure(): T $callable */
    public function __construct(private Closure $callable)
    {
    }

    /** @return T */
    public function getValue()
    {
        static $value = $this->doGetValue();
        
        return $value;
    }
	
    /** @return T */
    private function doGetValue()
    {
        $callable = $this->callable;
        
        return $callable();
    }
}
Psalm output (using commit b940c7e):

INFO: MixedReturnStatement - 15:16 - Could not infer a return type

psalm-github-bot[bot] avatar Mar 02 '24 15:03 psalm-github-bot[bot]

Works if you do the assignment on a separate line: https://psalm.dev/r/0c39537a8c

kkmuffme avatar Mar 02 '24 19:03 kkmuffme

I found these snippets:

https://psalm.dev/r/0c39537a8c
<?php
/** @template T */
class LazyValue
{
    /** @param Closure(): T $callable */
    public function __construct(private Closure $callable)
    {
    }

    /** @return T */
    public function getValue()
    {
        static $value;
		$value = ($this->callable)();
        
        return $value;
    }
}
Psalm output (using commit b940c7e):

No issues!

psalm-github-bot[bot] avatar Mar 02 '24 19:03 psalm-github-bot[bot]

@kkmuffme

Works if you do the assignment on a separate line

It is the old functionality, not the new one. It will keep executing same code over and over, not initialize on first call like this.

zmitic avatar Mar 02 '24 19:03 zmitic

Yeah right, I meant to do https://psalm.dev/r/d72c5c4252 - which has the same issue (if not worse) and should be fixed here too.

kkmuffme avatar Mar 02 '24 21:03 kkmuffme

I found these snippets:

https://psalm.dev/r/d72c5c4252
<?php
/** @template T */
class LazyValue
{
    /** @param Closure(): T $callable */
    public function __construct(private Closure $callable)
    {
    }

    /** @return T */
    public function getValue()
    {
        static $value;
        if ($value === null) {
         	$value = ($this->callable)();   
        }
		
        
        return $value;
    }
}
Psalm output (using commit b940c7e):

INFO: MixedReturnStatement - 19:16 - Possibly-mixed return value

psalm-github-bot[bot] avatar Mar 02 '24 21:03 psalm-github-bot[bot]