psalm icon indicating copy to clipboard operation
psalm copied to clipboard

TypeDoesNotContainType - false positive on static properties

Open bkdotcom opened this issue 1 year ago • 3 comments

https://psalm.dev/r/f5adb03835

ERROR: TypeDoesNotContainType - Type false for Widget::$isSomething is always !falsy

This is called from within a loop that calls at least one member method (that may update said property)

Interestingly, instance properties do not raise this error, but static properties do. ¯\_(ツ)_/¯


Preconditions #7169

This example also raises

ERROR: PossiblyNullReference - Cannot call method someMethod on possibly null value

This is being raised from within a private method... I know the state of my properties and that the value is not null.
I would like the option to suppress or "info-level" this class of issue when raised from within a private method

bkdotcom avatar Feb 14 '24 00:02 bkdotcom

I found these snippets:

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

class SomeObject
{
    public function someMethod(): void
    {
    }
}

class Widget
{
	/** @var bool */
    private static $isSomething = false;
    
    /** @var bool */
    private $isNothing = false;
    
    /** @var SomeObject|null */
    private $someObject;
    
	/**
     * @param string[] $vals 
     *
     * @return void
     */
    public function doSomething(array $vals)
    {
		self::$isSomething = false;
		$this->isNothing = false;
        
        $this->someObject = new SomeObject();
        
        foreach ($vals as $val) {
			// psalm complains that this static property is always false... it's not
            if (self::$isSomething) {
                echo $val;
                continue;
            }
            // psalm doesn't complain about this non-static property being always false... it is
            if ($this->isNothing) {
                echo $val;
                continue;
            }
            // we're calling methods
            $this->helperThing();
        }
    }
    
	/**
     * @return void
     */
    private function helperThing()
    {
        self::$isSomething = true;
        $this->isNothing = false;
        $this->someObject->someMethod();   // I'm in a private method...  I know that $this->someObject isn't null
    }
}
Psalm output (using commit 639bed0):

ERROR: TypeDoesNotContainType - 35:17 - Operand of type false is always falsy

ERROR: TypeDoesNotContainType - 35:17 - Type false for Widget::$isSomething is always !falsy

ERROR: PossiblyNullReference - 56:28 - Cannot call method someMethod on possibly null value

psalm-github-bot[bot] avatar Feb 14 '24 00:02 psalm-github-bot[bot]

IMHO, preconditions (#7169) would be a better way to address it.

weirdan avatar Feb 14 '24 01:02 weirdan

@weirdan - indeed! I like it

I've updated this "request" to focus on the TypeDoesNotContainType false positive on static properties

bkdotcom avatar Feb 14 '24 01:02 bkdotcom