Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static methods declared via @method static ReturnType methodName() do not inherit __callStatic() purity #6941

Closed
Ocramius opened this issue Nov 18, 2021 · 2 comments · Fixed by #6953

Comments

@Ocramius
Copy link
Contributor

Given following example ( https://psalm.dev/r/c076bbc487 ):

<?php

/**
 * @method self FOO()
 * @method static BAR()
 * @method static BAZ()
 *
 * @psalm-immutable
 */
class MyEnum
{
    const FOO = 'foo';
    const BAR = 'bar';
    const BAZ = 'baz';
    
    /** @psalm-pure */
    public static function __callStatic(string $name, array $params): static
    {
        throw new BadMethodCallException('not implemented');
    }
}

/** @psalm-pure */
function gimmeFoo(): MyEnum
{
    return MyEnum::FOO();
}

No errors are produced.

As soon as @method static self FOO() is declared (to make it clear that the dynamic method is only available when called statically), we get an error ( https://psalm.dev/r/327af3563f ):

<?php

/**
- * @method self FOO()
+ * @method static self FOO()
- * @method static BAR()
+ * @method static static BAR()
- * @method static BAZ()
+ * @method static static BAZ()
 *
 * @psalm-immutable
 */
class MyEnum
{
    const FOO = 'foo';
    const BAR = 'bar';
    const BAZ = 'baz';
    
    /** @psalm-pure */
    public static function __callStatic(string $name, array $params): static
    {
        throw new BadMethodCallException('not implemented');
    }
}

/** @psalm-pure */
function gimmeFoo(): MyEnum
{
    return MyEnum::FOO();
}
Psalm output (using commit 6097e02): 

ERROR: ImpureMethodCall - 26:20 - Cannot call an impure method from a pure context

Therefore, I'm wondering if:

  1. vimeo/psalm at 4.12.0 removed __callStatic() purity from @method definitions (worked in 4.10.0
  2. I'm misusing @method by declaring the static modifier? 🤔
@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @method self FOO()
 * @method static BAR()
 * @method static BAZ()
 *
 * @psalm-immutable
 */
class MyEnum
{
    const FOO = 'foo';
    const BAR = 'bar';
    const BAZ = 'baz';
    
    /** @psalm-pure */
    public static function __callStatic(string $name, array $params): static
    {
        throw new BadMethodCallException('not implemented');
    }
}

/** @psalm-pure */
function gimmeFoo(): MyEnum
{
    return MyEnum::FOO();
}
Psalm output (using commit 6097e02):

No issues!
https://psalm.dev/r/327af3563f
<?php

/**
 * @method static self FOO()
 * @method static static BAR()
 * @method static static BAZ()
 *
 * @psalm-immutable
 */
class MyEnum
{
    const FOO = 'foo';
    const BAR = 'bar';
    const BAZ = 'baz';
    
    /** @psalm-pure */
    public static function __callStatic(string $name, array $params): static
    {
        throw new BadMethodCallException('not implemented');
    }
}

/** @psalm-pure */
function gimmeFoo(): MyEnum
{
    return MyEnum::FOO();
}
Psalm output (using commit 6097e02):

ERROR: ImpureMethodCall - 26:20 - Cannot call an impure method from a pure context

@weirdan weirdan added the bug label Nov 18, 2021
@orklah
Copy link
Collaborator

orklah commented Nov 18, 2021

Probably related to #6724, I'll check this later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants