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

Feature: psalm-assert "one of" while providing the list of possible values via variable #5657

Closed
boesing opened this issue Apr 21, 2021 · 4 comments

Comments

@boesing
Copy link
Contributor

boesing commented Apr 21, 2021

Hey there,

I think, many of us are using webmozart/assert.
I am experiencing some kind of problem for now, as I cannot tell that a value contains one of the values provided by another value.

Lets assume, I have this piece of code:
https://psalm.dev/r/e5faadd216

I dont know any way to provide psalm-assert informations that the unknownValue is one of these which were provided via the $values argument of Assert::oneOf.

Is that something which could be achieved in any way?

@psalm-github-bot
Copy link

I found these snippets:

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

namespace Webmozart
{
    class Assert
    {
        /**
         * @psalm-pure
         * @throws \InvalidArgumentException
         */
        public static function oneOf(mixed $value, array $values): void
        {
            if (!\in_array($value, $values, true)) {
            	throw new \InvalidArgumentException('whatever');
	        }
        }
    }
}

namespace {
    class Foo
    {
        public const VALUE_FOO = 'foo';
	    public const VALUE_BAR = 'bar';
	    public const VALUE_BAZ = 'baz';

        /** @psalm-param self::VALUE_* $value */
        public static function qoo(string $value): void
        {
            $value;
        }
    }
    
    /** @var string $unknownValue */
    $unknownValue = $_SERVER['QUERY_STRING'] ?? '';
    \Webmozart\Assert::oneOf($unknownValue, [Foo::VALUE_FOO, Foo::VALUE_BAR, Foo::VALUE_BAZ]);
        
    Foo::qoo($unknownValue);
}
Psalm output (using commit 0d524ec):

ERROR: ArgumentTypeCoercion - 38:14 - Argument 1 of Foo::qoo expects "bar"|"baz"|"foo", parent type string provided

@weirdan
Copy link
Collaborator

weirdan commented Apr 21, 2021

I would expect something like this to work: https://psalm.dev/r/13845d6d06 (but it doesn't)

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/13845d6d06
<?php

namespace Webmozart {
    class Assert {
        /**
         * @psalm-pure
         * @template T
         * @param array<array-key, T> $values
         * @psalm-assert T $value
         *
         * @throws \InvalidArgumentException
         */
        public static function oneOf(mixed $value, array $values): void {
            if (!\in_array($value, $values, true)) {
            	throw new \InvalidArgumentException('whatever');
	        }
        }
    }
}

namespace {
    /**
     * @return 'a'|'b' 
     */
    function f(string $unknownValue): string {
        \Webmozart\Assert::oneOf($unknownValue, ['a', 'b']);
    	/** @psalm-trace $unknownValue */;
        return $unknownValue;
    }
}
Psalm output (using commit 0d524ec):

INFO: Trace - 27:39 - $unknownValue: string

INFO: LessSpecificReturnStatement - 28:16 - The type 'string' is more general than the declared return type '"a"|"b"' for f

INFO: MoreSpecificReturnType - 23:16 - The declared return type '"a"|"b"' for f is more specific than the inferred return type 'string'

@weirdan weirdan added the bug label Apr 21, 2021
orklah pushed a commit that referenced this issue Jun 27, 2022
fixes #5657

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>
@boesing
Copy link
Contributor Author

boesing commented Jun 27, 2022

Closed with #8077

@boesing boesing closed this as completed Jun 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants