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

Switch regression? #3603

Closed
vudaltsov opened this issue Jun 18, 2020 · 3 comments
Closed

Switch regression? #3603

vudaltsov opened this issue Jun 18, 2020 · 3 comments
Labels

Comments

@vudaltsov
Copy link
Contributor

https://psalm.dev/r/6614a43b21

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/6614a43b21
<?php

/**
 * @psalm-immutable
 * @template T of self::READ_UNCOMMITTED|self::READ_COMMITTED|self::REPEATABLE_READ|self::SERIALIZABLE
 */
final class TransactionIsolationLevel
{
    private const READ_UNCOMMITTED = 'read uncommitted';
    private const READ_COMMITTED = 'read committed';
    private const REPEATABLE_READ = 'repeatable read';
    private const SERIALIZABLE = 'serializable';

    /**
     * @psalm-var T $level
     */
    private string $level;

    /**
     * @psalm-param T $level
     */
    private function __construct(string $level)
    {
        $this->level = $level;
    }

    /**
     * @psalm-return self<self::READ_UNCOMMITTED>
     */
    public static function readUncommitted(): self
    {
        return new self(self::READ_UNCOMMITTED);
    }

    /**
     * @psalm-return self<self::READ_COMMITTED>
     */
    public static function readCommitted(): self
    {
        return new self(self::READ_COMMITTED);
    }

    /**
     * @psalm-return self<self::REPEATABLE_READ>
     */
    public static function repeatableRead(): self
    {
        return new self(self::REPEATABLE_READ);
    }

    /**
     * @psalm-return self<self::SERIALIZABLE>
     */
    public static function serializable(): self
    {
        return new self(self::SERIALIZABLE);
    }

    /**
     * @psalm-return T
     */
    public function toString(): string
    {
        return $this->level;
    }

    /**
     * @psalm-template TResult
     * @psalm-param callable(self::READ_UNCOMMITTED): TResult $readUncommitted
     * @psalm-param callable(self::READ_COMMITTED): TResult $readCommitted
     * @psalm-param callable(self::REPEATABLE_READ): TResult $repeatableRead
     * @psalm-param callable(self::SERIALIZABLE): TResult $serializable
     * @psalm-return TResult
     */
    public function resolve(
        callable $readUncommitted,
        callable $readCommitted,
        callable $repeatableRead,
        callable $serializable
    ) {
        switch ($this->level) {
            case self::READ_UNCOMMITTED:
                return $readUncommitted($this->level);

            case self::READ_COMMITTED:
                return $readCommitted($this->level);

            case self::REPEATABLE_READ:
                return $repeatableRead($this->level);

            case self::SERIALIZABLE:
                return $serializable($this->level);

            default:
                throw new \LogicException(sprintf('Level "%s" is an invalid transaction isolation level.', $this->level));
        }
    }
}
Psalm output (using commit 21e5678):

ERROR: PossiblyInvalidArgument - 83:41 - Argument 1 expects string(read uncommitted), possibly different type T:TransactionIsolationLevel as string(read committed)|string(read uncommitted)|string(repeatable read)|string(serializable) provided

ERROR: PossiblyInvalidArgument - 86:39 - Argument 1 expects string(read committed), possibly different type T:TransactionIsolationLevel as string(read committed)|string(read uncommitted)|string(repeatable read)|string(serializable) provided

ERROR: PossiblyInvalidArgument - 89:40 - Argument 1 expects string(repeatable read), possibly different type T:TransactionIsolationLevel as string(read committed)|string(read uncommitted)|string(repeatable read)|string(serializable) provided

ERROR: PossiblyInvalidArgument - 92:38 - Argument 1 expects string(serializable), possibly different type T:TransactionIsolationLevel as string(read committed)|string(read uncommitted)|string(repeatable read)|string(serializable) provided

@weirdan weirdan added the bug label Jun 18, 2020
@muglug
Copy link
Collaborator

muglug commented Jun 18, 2020

narrowed to https://psalm.dev/r/321fb79d3f (without switch, but with ==)

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/321fb79d3f
<?php

/**
 * @psalm-immutable
 * @template T of self::READ_UNCOMMITTED|self::READ_COMMITTED|self::REPEATABLE_READ|self::SERIALIZABLE
 */
final class TransactionIsolationLevel
{
    private const READ_UNCOMMITTED = 'read uncommitted';
    private const READ_COMMITTED = 'read committed';
    private const REPEATABLE_READ = 'repeatable read';
    private const SERIALIZABLE = 'serializable';

    /**
     * @psalm-var T $level
     */
    private string $level;

    /**
     * @psalm-param T $level
     */
    private function __construct(string $level)
    {
        $this->level = $level;
    }

    /**
     * @psalm-return self<self::READ_UNCOMMITTED>
     */
    public static function readUncommitted(): self
    {
        return new self(self::READ_UNCOMMITTED);
    }

    /**
     * @psalm-return T
     */
    public function toString(): string
    {
        return $this->level;
    }

    /**
     * @psalm-template TResult
     * @psalm-param callable(self::READ_UNCOMMITTED): TResult $readUncommitted
     * @psalm-return TResult
     */
    public function resolve(callable $readUncommitted) {
        if ($this->level == self::READ_UNCOMMITTED) {
            return $readUncommitted($this->level);
        }
        
        throw new \LogicException(sprintf('Level "%s" is an invalid transaction isolation level.', $this->level));
    }
}
Psalm output (using commit 21e5678):

ERROR: PossiblyInvalidArgument - 50:37 - Argument 1 expects string(read uncommitted), possibly different type T:TransactionIsolationLevel as string(read committed)|string(read uncommitted)|string(repeatable read)|string(serializable) provided

@muglug muglug closed this as completed in 137647a Jun 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants