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

Test issue #6

Open
weirdan opened this issue Dec 11, 2019 · 69 comments
Open

Test issue #6

weirdan opened this issue Dec 11, 2019 · 69 comments

Comments

@weirdan
Copy link
Member

weirdan commented Dec 11, 2019

https://psalm.dev/r/fa74710ae3

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 05783eb):

No issues!

@psalm psalm deleted a comment from psalm-github-bot bot Dec 12, 2019
@weirdan
Copy link
Member Author

weirdan commented Dec 12, 2019

Still there? https://psalm.dev/r/fa74710ae3

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 6ff312f):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Dec 13, 2019

Hey @psalm-github-bot, can you please fetch this for me: https://psalm.dev/r/fa74710ae3

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 6ff312f):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Dec 28, 2019

Still there? https://psalm.dev/r/fa74710ae3

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 4110ec3):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Dec 28, 2019

@psalm-github-bot
Copy link

psalm-github-bot bot commented Dec 28, 2019

I found these snippets:

https://psalm.dev/r/6f8098b9ef
<?php

class MyStreamFilter extends \php_user_filter
{
    /** @var string */
    private $append;

    /**
     * @see https://php.net/manual/en/php-user-filter.oncreate.php
     *
     * @return bool
     */
    public function onCreate()
    {
        if (!isset($this->params['append'])) {
            return false;
        }
        $this->append = (string) $this->params['append'];

        return true;
    }

    /**
     * @param resource $in
     * @param resource $out
     * @param int      $consumed
     * @param bool     $closing
     *
     * @return int
     */
    public function filter($in, $out, &$consumed, $closing)
    {
        while ($bucket = stream_bucket_make_writeable($in)) {
            $bucket->data .= $this->append;

            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }

        return \PSFS_PASS_ON;
    }
}
Psalm output (using commit 4110ec3):

INFO: MixedArrayAccess - 18:34 - Cannot access array value on mixed variable $this->params

INFO: MixedOperand - 34:13 - Left operand cannot be mixed

INFO: MixedOperand - 36:13 - Left operand cannot be mixed

ERROR: MissingConstructor - 6:13 - MyStreamFilter has an uninitialized variable $this->append, but no constructor
https://psalm.dev/r/fa74710ae3
<?php

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 4110ec3):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Mar 28, 2020

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit e3ff856):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Mar 28, 2020

Without true && it works as expected.

https://psalm.dev/r/9163d1b90e
https://psalm.dev/r/7005ba3a7a

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/9163d1b90e
<?php

$pointers = ['hi'];

while (true && 0 < ($parent = 0)) {
    print $pointers[$parent];
}
Psalm output (using commit 86a89b2):

No issues!
https://psalm.dev/r/7005ba3a7a
<?php

namespace Amp\Loop\Internal;

final class TimerQueue
{
    /** @var int[] */
    private $pointers = [];

    public function foobar(): void
    {
       	$node = 0;
        
        while ($node !== 0 && 0 < $this->pointers[$parent = ($node - 1) >> 1]) {
            print $this->pointers[$parent];
        }
    }
}
Psalm output (using commit 86a89b2):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Mar 28, 2020

Without true && it works as expected.

https://psalm.dev/r/9163d1b90e
https://psalm.dev/r/7005ba3a7a

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/9163d1b90e
<?php

$pointers = ['hi'];

while (true && 0 < ($parent = 0)) {
    print $pointers[$parent];
}
Psalm output (using commit 86a89b2):

No issues!
https://psalm.dev/r/7005ba3a7a
<?php

namespace Amp\Loop\Internal;

final class TimerQueue
{
    /** @var int[] */
    private $pointers = [];

    public function foobar(): void
    {
       	$node = 0;
        
        while ($node !== 0 && 0 < $this->pointers[$parent = ($node - 1) >> 1]) {
            print $this->pointers[$parent];
        }
    }
}
Psalm output (using commit 86a89b2):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Mar 29, 2020

Without true && it works as expected.

https://psalm.dev/r/9163d1b90e
https://psalm.dev/r/7005ba3a7a

1 similar comment
@weirdan
Copy link
Member Author

weirdan commented Mar 29, 2020

Without true && it works as expected.

https://psalm.dev/r/9163d1b90e
https://psalm.dev/r/7005ba3a7a

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/9163d1b90e
<?php

$pointers = ['hi'];

while (true && 0 < ($parent = 0)) {
    print $pointers[$parent];
}
Psalm output (using commit 9373571):

No issues!
https://psalm.dev/r/7005ba3a7a
<?php

namespace Amp\Loop\Internal;

final class TimerQueue
{
    /** @var int[] */
    private $pointers = [];

    public function foobar(): void
    {
       	$node = 0;
        
        while ($node !== 0 && 0 < $this->pointers[$parent = ($node - 1) >> 1]) {
            print $this->pointers[$parent];
        }
    }
}
Psalm output (using commit 9373571):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Mar 29, 2020

Without true && it works as expected.

https://psalm.dev/r/9163d1b90e
https://psalm.dev/r/7005ba3a7a

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/9163d1b90e
<?php

$pointers = ['hi'];

while (true && 0 < ($parent = 0)) {
    print $pointers[$parent];
}
Psalm output (using commit 9373571):

No issues!
https://psalm.dev/r/7005ba3a7a
<?php

namespace Amp\Loop\Internal;

final class TimerQueue
{
    /** @var int[] */
    private $pointers = [];

    public function foobar(): void
    {
       	$node = 0;
        
        while ($node !== 0 && 0 < $this->pointers[$parent = ($node - 1) >> 1]) {
            print $this->pointers[$parent];
        }
    }
}
Psalm output (using commit 9373571):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Sep 22, 2020

Footnotes

> something [1]

[1] https://example.org

is rendered as

something 1

@weirdan
Copy link
Member Author

weirdan commented Sep 22, 2020

and quoted (Quote reply menu item, or r hotkey) as

> is rendered as
> 
> > something [1](https://example.org)

which is rendered as

is rendered as

something 1

@weirdan
Copy link
Member Author

weirdan commented Apr 10, 2021

psalm.dev/r/fa74710ae3

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 012dafa):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Jun 29, 2021

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/fb2fdbf173
<?php
enum Method: string {
    case HEAD = 'HEAD';
    case GET = 'GET';
    case POST = 'POST';
    case PUT = 'PUT';
    case PATCH = 'PATCH';
    case DELETE = 'DELETE';
    case PURGE = 'PURGE';
    case OPTIONS = 'OPTIONS';
    case TRACE = 'TRACE';
}

/**
 * @psalm-consistent-constructor
 */
class Request {
    private Method $method;
    /**
     * Request constructor.
     * @param array $server
     * @param array $query
     * @param array $formData
     * @param array $cookie
     * @param array $files
     */
    public function __construct(
        array $server,
        array $query,
        array $formData,
        array $cookie,
        array $files
    ) {
        $this->method = Method::from((string) $server['REQUEST_METHOD']);
    }

    /**
     * @return Request
     */
    public static function createFromGlobals(): self {
        return new static($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES);
    }
}
Psalm output (using commit 0196afc):

ERROR: UndefinedMethod - 34:25 - Method Method::from does not exist

INFO: PossiblyUndefinedStringArrayOffset - 34:47 - Possibly undefined array offset '"REQUEST_METHOD"' is risky given expected type 'array-key'. Consider using isset beforehand.

INFO: MixedAssignment - 34:9 - Unable to determine the type that $this->method is being assigned to

@weirdan
Copy link
Member Author

weirdan commented Jun 30, 2021

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/48609634a5
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}   sdf
Psalm output (using commit 667dcc2):

ERROR: ParseError - 15:31 - Syntax error, unexpected EOF on line 15

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, "hello"}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, "hello"}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, "some text" provided

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always falsy

ERROR: UndefinedConstant - 15:28 - Const sdf is not defined

@weirdan
Copy link
Member Author

weirdan commented Jul 2, 2021

psalm.dev/r/48609634a5

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 028ac7f):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Oct 1, 2022

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 028ac7f):

No issues!

1 similar comment
@ghost
Copy link

ghost commented Oct 1, 2022

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit 028ac7f):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Oct 1, 2022

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @template A
 */
class Config {
    /**
     * @param (callable(): A)|null $x
     */
    public function __construct($x = null)
    {}

    /**
     * @template NewA
     * @param (callable(): NewA)|null $x
     * @return Config<NewA>
     */
    public static function create($x = null)
    {
        return new self($x);
    }
}

// Named constructor Tests:
/** @return Config<never>*/
function namedEmptyConfig() {
    return Config::create();
}

/**
 * This somehow resolves to mixed instead of never - even though the value is also null here:
 * @return Config<never>
 */
function namedNullConfig() {
    return Config::create(null);
}


// Test config constructor:
/**
 * @return Config<never>
 * Why does this work differently than the named constructor?
 * I would expect "never" to be the result here, but instead it is mixed.
 */
function emptyConfig() {
    return new Config();
}

/**
 * @return Config<never>
 * Same issue as in named constructor test - I'dd expect never here.
 */
function nullConfig() {
    return new Config(null);
}

/** @return Config<string> */
function configured() {
    return new Config(fn () => 'hello');
}
Psalm output (using commit 028ac7f):

INFO: MixedReturnTypeCoercion - 35:12 - The type 'Config<mixed>' is more general than the declared return type 'Config<never>' for namedNullConfig

INFO: MixedReturnTypeCoercion - 32:12 - The declared return type 'Config<never>' for namedNullConfig is more specific than the inferred return type 'Config<mixed>'

INFO: MixedReturnTypeCoercion - 46:12 - The type 'Config<mixed>' is more general than the declared return type 'Config<never>' for emptyConfig

INFO: MixedReturnTypeCoercion - 41:12 - The declared return type 'Config<never>' for emptyConfig is more specific than the inferred return type 'Config<mixed>'

INFO: MixedReturnTypeCoercion - 54:12 - The type 'Config<mixed>' is more general than the declared return type 'Config<never>' for nullConfig

INFO: MixedReturnTypeCoercion - 50:12 - The declared return type 'Config<never>' for nullConfig is more specific than the inferred return type 'Config<mixed>'

1 similar comment
@ghost
Copy link

ghost commented Oct 1, 2022

I found these snippets:

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

/**
 * @template A
 */
class Config {
    /**
     * @param (callable(): A)|null $x
     */
    public function __construct($x = null)
    {}

    /**
     * @template NewA
     * @param (callable(): NewA)|null $x
     * @return Config<NewA>
     */
    public static function create($x = null)
    {
        return new self($x);
    }
}

// Named constructor Tests:
/** @return Config<never>*/
function namedEmptyConfig() {
    return Config::create();
}

/**
 * This somehow resolves to mixed instead of never - even though the value is also null here:
 * @return Config<never>
 */
function namedNullConfig() {
    return Config::create(null);
}


// Test config constructor:
/**
 * @return Config<never>
 * Why does this work differently than the named constructor?
 * I would expect "never" to be the result here, but instead it is mixed.
 */
function emptyConfig() {
    return new Config();
}

/**
 * @return Config<never>
 * Same issue as in named constructor test - I'dd expect never here.
 */
function nullConfig() {
    return new Config(null);
}

/** @return Config<string> */
function configured() {
    return new Config(fn () => 'hello');
}
Psalm output (using commit 028ac7f):

INFO: MixedReturnTypeCoercion - 35:12 - The type 'Config<mixed>' is more general than the declared return type 'Config<never>' for namedNullConfig

INFO: MixedReturnTypeCoercion - 32:12 - The declared return type 'Config<never>' for namedNullConfig is more specific than the inferred return type 'Config<mixed>'

INFO: MixedReturnTypeCoercion - 46:12 - The type 'Config<mixed>' is more general than the declared return type 'Config<never>' for emptyConfig

INFO: MixedReturnTypeCoercion - 41:12 - The declared return type 'Config<never>' for emptyConfig is more specific than the inferred return type 'Config<mixed>'

INFO: MixedReturnTypeCoercion - 54:12 - The type 'Config<mixed>' is more general than the declared return type 'Config<never>' for nullConfig

INFO: MixedReturnTypeCoercion - 50:12 - The declared return type 'Config<never>' for nullConfig is more specific than the inferred return type 'Config<mixed>'

@weirdan
Copy link
Member Author

weirdan commented Oct 2, 2022

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/4121eceef8
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}
Psalm output (using commit 028ac7f):

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, 'hello'}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, 'hello'}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, 'some text' provided

ERROR: TypeDoesNotContainType - 15:11 - Operand of type 0 is always falsy

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always !falsy

1 similar comment
@ghost
Copy link

ghost commented Oct 2, 2022

I found these snippets:

https://psalm.dev/r/4121eceef8
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}
Psalm output (using commit 028ac7f):

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, 'hello'}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, 'hello'}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, 'some text' provided

ERROR: TypeDoesNotContainType - 15:11 - Operand of type 0 is always falsy

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always !falsy

@weirdan
Copy link
Member Author

weirdan commented Oct 2, 2022

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/4121eceef8
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}
Psalm output (using commit 028ac7f):

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, 'hello'}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, 'hello'}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, 'some text' provided

ERROR: TypeDoesNotContainType - 15:11 - Operand of type 0 is always falsy

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always !falsy

1 similar comment
@ghost
Copy link

ghost commented Oct 2, 2022

I found these snippets:

https://psalm.dev/r/4121eceef8
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}
Psalm output (using commit 028ac7f):

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, 'hello'}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, 'hello'}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, 'some text' provided

ERROR: TypeDoesNotContainType - 15:11 - Operand of type 0 is always falsy

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always !falsy

@weirdan
Copy link
Member Author

weirdan commented Oct 2, 2022

@ghost
Copy link

ghost commented Oct 2, 2022

I found these snippets:

https://psalm.dev/r/4121eceef8
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}
Psalm output (using commit 028ac7f):

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, 'hello'}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, 'hello'}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, 'some text' provided

ERROR: TypeDoesNotContainType - 15:11 - Operand of type 0 is always falsy

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always !falsy

1 similar comment
@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/4121eceef8
<?php

/**
 * @return array<string>
 */
function takesAnInt(int $i) {
    return [$i, "hello"];
}

$data = ["some text", 5];
takesAnInt($data[0]);

$condition = rand(0, 5);
if ($condition) {
} elseif ($condition) {}
Psalm output (using commit 028ac7f):

ERROR: InvalidReturnStatement - 7:12 - The inferred type 'array{int, 'hello'}' does not match the declared return type 'array<array-key, string>' for takesAnInt

ERROR: InvalidReturnType - 4:12 - The declared return type 'array<array-key, string>' for takesAnInt is incorrect, got 'array{int, 'hello'}'

ERROR: InvalidScalarArgument - 11:12 - Argument 1 of takesAnInt expects int, 'some text' provided

ERROR: TypeDoesNotContainType - 15:11 - Operand of type 0 is always falsy

ERROR: TypeDoesNotContainType - 15:11 - Type 0 for $condition is always !falsy

@weirdan
Copy link
Member Author

weirdan commented Nov 19, 2022

Let's check it again: https://psalm.dev/r/dd01eef1e0

@ghost
Copy link

ghost commented Nov 19, 2022

I found these snippets:

https://psalm.dev/r/dd01eef1e0
<?php
abstract class Arr0 {

     /**
     * @param iterable<mixed>              $arr
     * @param \Closure|int|string|string[] $map
     * @psalm-suppress UnusedParam
     */

    static function map(
        iterable $arr,
        int|string|array|\Closure $map = null,
        mixed $where = null,
        mixed $skip = null,
        mixed $while = null,
        mixed $reverse = false,
    ): void {
        
    }
}
function v(): int|string|object|array|bool {
    return true;
}
$a = Arr0::map([], 1, v(), v(), v());
Psalm output (using commit 4e17585):

ERROR: AssignmentToVoid - 24:1 - Cannot assign $a to type void

INFO: UnusedVariable - 24:1 - $a is never referenced or the value is not used

1 similar comment
@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/dd01eef1e0
<?php
abstract class Arr0 {

     /**
     * @param iterable<mixed>              $arr
     * @param \Closure|int|string|string[] $map
     * @psalm-suppress UnusedParam
     */

    static function map(
        iterable $arr,
        int|string|array|\Closure $map = null,
        mixed $where = null,
        mixed $skip = null,
        mixed $while = null,
        mixed $reverse = false,
    ): void {
        
    }
}
function v(): int|string|object|array|bool {
    return true;
}
$a = Arr0::map([], 1, v(), v(), v());
Psalm output (using commit 4e17585):

ERROR: AssignmentToVoid - 24:1 - Cannot assign $a to type void

INFO: UnusedVariable - 24:1 - $a is never referenced or the value is not used

@weirdan
Copy link
Member Author

weirdan commented Nov 19, 2022

And again: https://psalm.dev/r/dd01eef1e0

@ghost
Copy link

ghost commented Nov 19, 2022

I found these snippets:

https://psalm.dev/r/dd01eef1e0
<?php
abstract class Arr0 {

     /**
     * @param iterable<mixed>              $arr
     * @param \Closure|int|string|string[] $map
     * @psalm-suppress UnusedParam
     */

    static function map(
        iterable $arr,
        int|string|array|\Closure $map = null,
        mixed $where = null,
        mixed $skip = null,
        mixed $while = null,
        mixed $reverse = false,
    ): void {
        
    }
}
function v(): int|string|object|array|bool {
    return true;
}
$a = Arr0::map([], 1, v(), v(), v());
Psalm output (using commit 4e17585):

ERROR: AssignmentToVoid - 24:1 - Cannot assign $a to type void

INFO: UnusedVariable - 24:1 - $a is never referenced or the value is not used

1 similar comment
@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/dd01eef1e0
<?php
abstract class Arr0 {

     /**
     * @param iterable<mixed>              $arr
     * @param \Closure|int|string|string[] $map
     * @psalm-suppress UnusedParam
     */

    static function map(
        iterable $arr,
        int|string|array|\Closure $map = null,
        mixed $where = null,
        mixed $skip = null,
        mixed $while = null,
        mixed $reverse = false,
    ): void {
        
    }
}
function v(): int|string|object|array|bool {
    return true;
}
$a = Arr0::map([], 1, v(), v(), v());
Psalm output (using commit 4e17585):

ERROR: AssignmentToVoid - 24:1 - Cannot assign $a to type void

INFO: UnusedVariable - 24:1 - $a is never referenced or the value is not used

@weirdan
Copy link
Member Author

weirdan commented Nov 19, 2022

How are we doing?
https://psalm.dev/r/034888a55f

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/034888a55f
<?php

/**
 * @param scalar $literal
 */
function quoteLiteral($literal): string
{
	if (is_numeric($literal) && ! is_string($literal)) {
		return (string) $literal;
	} elseif (is_bool($literal)) {
		return $literal ? 'true' : 'false';
	}
    
    /** @psalm-trace $literal */

	return "'" . str_replace("'", "''", $literal) . "'";
}
Psalm output (using commit 4e17585):

ERROR: PossiblyInvalidArgument - 16:38 - Argument 3 of str_replace expects array<array-key, float|int|string>|string, but possibly different type float|int|string provided

INFO: Trace - 16:2 - $literal: float|int|string

@weirdan
Copy link
Member Author

weirdan commented Nov 23, 2022

Still there? psalm.dev/r/fa74710ae3

@weirdan
Copy link
Member Author

weirdan commented Nov 23, 2022

Still there? https://psalm.dev/r/fa74710ae3

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-type Person = array{name: string, age: int}
 */

/**
 * @psalm-return Person
 */
function getPerson_error(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok1(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var array{name: string, age: int} */
  return json_decode($json, true);
}

/**
 * @psalm-return Person
 */
function getPerson_ok2(): array {
  $json = '{"name": "John", "age": 44}';
  /** @psalm-var Person */
  $person = json_decode($json, true);
  return $person;
}
Psalm output (using commit e83ac65):

No issues!

@weirdan
Copy link
Member Author

weirdan commented Jan 29, 2024

Copy link

I found these snippets:

https://psalm.dev/r/7a2cc47bec
<?php

/** @property-read bool $val */
class Request {
    function b(bool $_b): void {}
    public function __get(string $key): mixed { return true; }
}
class C {
function f(Request $r): void {
    /** @psalm-suppress UndefinedVariable */
    $r->b(_b: filter_var($val, FILTER_VALIDATE_BOOL));
}
}
Psalm output (using commit 275dfd8):

No issues!

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

No branches or pull requests

1 participant