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

Empty if clause changes type of variable from T|null to T|array|null #4117

Closed
AJenbo opened this issue Nov 24, 2020 · 12 comments · Fixed by phpstan/phpstan-src#1444
Closed
Labels
Milestone

Comments

@AJenbo
Copy link
Contributor

AJenbo commented Nov 24, 2020

Bug report

    /** @var array<int, T> */
    protected $items = [];

    /**
     * @return ?T
     */
	public function broken(int $key)
    {
        $item = $this->items[$key] ?? null;
        if ($item) {
        }

        return $item;
    }

Method GenericList::broken() should return T|null but returns array|T|null.

Code snippet that reproduces the problem

https://phpstan.org/r/54561da3-8e55-438b-91b1-cf4c73eed57f

Expected output

No errors

@ondrejmirtes
Copy link
Member

I'm not surprised this happens, the relationship between NonEmptyArrayType and TemplateMixedType will have to be fixed I guess.

@ondrejmirtes ondrejmirtes added this to the Easy fixes milestone Nov 24, 2020
@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T|null but returns array|(float&T)|(int&T)|(string&T)|(string&T)|T|(T&bool)|null.
Full report
Line Error
30 `Method GenericList::broken() should return T

@AJenbo
Copy link
Contributor Author

AJenbo commented Oct 4, 2021

Different, but not correct 🙂

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+PHP 7.4 – 8.0 (1 error)
+==========
+
+30: Method GenericList::broken() should return T|null but returns array|(float&T)|(int&T)|(string&T)|(string&T)|T|(T&bool)|null.
+
+PHP 7.1 – 7.3 (2 errors)
+==========
+
+16: Return type ArrayIterator of method GenericList::getIterator() is not compatible with return type Traversable of method IteratorAggregate::getIterator().
+30: Method GenericList::broken() should return T|null but returns array|(float&T)|(int&T)|(string&T)|(string&T)|T|(T&bool)|null.
Full report

PHP 7.4 – 8.0 (1 error)

Line Error
30 `Method GenericList::broken() should return T

PHP 7.1 – 7.3 (2 errors)

Line Error
16 Return type ArrayIterator of method GenericList::getIterator() is not compatible with return type Traversable of method IteratorAggregate::getIterator().
30 `Method GenericList::broken() should return T

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T|null but returns array|(float&T)|(int&T)|(''&T)|('0'&T)|T|(T&bool)|null.
Full report
Line Error
30 `Method GenericList::broken() should return T

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T|null but returns array|(float&T)|(int&T)|(string&T)|(string&T)|T of mixed|(T&bool)|null.
Full report
Line Error
30 `Method GenericList::broken() should return T

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T but returns array|(float&T)|(int&T)|(string&T)|(string&T)|T of mixed|(T&bool)|null.
+40: Method GenericList::works() should return T but returns T|null.
Full report
Line Error
30 `Method GenericList::broken() should return T but returns array
40 `Method GenericList::works() should return T but returns T

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T but returns array|T of mixed|null.
+40: Method GenericList::works() should return T but returns T|null.
Full report
Line Error
30 `Method GenericList::broken() should return T but returns array
40 `Method GenericList::works() should return T but returns T

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T|null but returns array|T of mixed|null.
Full report
Line Error
30 `Method GenericList::broken() should return T

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in 1.7.x, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return (T)|null but returns array|(T of mixed)|null.
Full report
Line Error
30 `Method GenericList::broken() should return (T)

@phpstan-bot
Copy link
Contributor

@AJenbo After the latest commit in 1.7.x, PHPStan now reports different result with your code snippet:

@@ @@
-30: Method GenericList::broken() should return T|null but returns array|T|null.
+30: Method GenericList::broken() should return T|null but returns array|(T of mixed)|null.
Full report
Line Error
30 `Method GenericList::broken() should return T

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants