psalm icon indicating copy to clipboard operation
psalm copied to clipboard

`@immutable` on a singleton with a static method where a field populated makes Psalm crash

Open fluffycondor opened this issue 2 years ago • 1 comments

https://psalm.dev/r/51731007b1 Sandbox responds 500

Warning: Undefined array key "self::$doctrineNullLink" in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php on line 526 {"error":{"message":"/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php: __clone method called on non-object","line_from":526,"type":"psalm_error"}}

If I don't set the private field, everything works fine: https://psalm.dev/r/1a2579acd5

fluffycondor avatar Jul 25 '22 14:07 fluffycondor

I found these snippets:

https://psalm.dev/r/51731007b1
<?php

/**
 * @psalm-immutable
 */
class PhotoLink
{
    private const DOCTRINE_NULL_VALUE = '🖼';
    private static ?PhotoLink $doctrineNullLink = null;
    
    public function __construct(private string $value) {}

    public static function getNullInstance()
    {
        if (!isset(self::$doctrineNullLink)) {
            self::$doctrineNullLink = (new \ReflectionClass(static::class))->newInstanceWithoutConstructor();
            self::$doctrineNullLink->value = self::DOCTRINE_NULL_VALUE;
        }

        return self::$doctrineNullLink;
    }
}
Psalm encountered an internal error:

/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php: __clone method called on non-object
https://psalm.dev/r/1a2579acd5
<?php

/**
 * @psalm-immutable
 */
class PhotoLink
{
    private const DOCTRINE_NULL_VALUE = '🖼';
    private static ?PhotoLink $doctrineNullLink = null;
    
    public function __construct(private string $value) {}

    public static function getNullInstance()
    {
        if (!isset(self::$doctrineNullLink)) {
            self::$doctrineNullLink = (new \ReflectionClass(static::class))->newInstanceWithoutConstructor();
        }

        return self::$doctrineNullLink;
    }
}
Psalm output (using commit 4b2935f):

INFO: MissingReturnType - 13:28 - Method PhotoLink::getNullInstance does not have a return type, expecting PhotoLink|PhotoLink&ReflectionClass<PhotoLink&static>

psalm-github-bot[bot] avatar Jul 25 '22 14:07 psalm-github-bot[bot]

Simplified: https://psalm.dev/r/809ad5cc65

weirdan avatar Dec 03 '22 04:12 weirdan

I found these snippets:

https://psalm.dev/r/809ad5cc65
<?php

/** @psalm-immutable */
final class C {}

final class A {
    private static C $prop;
    public static function f()
    {
        self::$prop->val = 1;    
    }
}
Psalm encountered an internal error:

/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php: Call to a member function setParentNodes() on null

psalm-github-bot[bot] avatar Dec 03 '22 04:12 psalm-github-bot[bot]

Seems to happen only when unused code detection is turned on.

weirdan avatar Dec 03 '22 04:12 weirdan