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

False positive Static property HelloWorld::$bug (WeakMap<stdClass, stdClass>) does not accept WeakMap<object, mixed>. #5551

Open
LastDragon-ru opened this issue Aug 28, 2021 · 9 comments · May be fixed by phpstan/phpstan-src#3364
Labels
Milestone

Comments

@LastDragon-ru
Copy link

Bug report

When you do something like phpstan will report "Static property HelloWorld::$bug (WeakMap<stdClass, stdClass>) does not accept WeakMap<object, mixed>", probably it must not do this (non-static property work as expected).

class HelloWorld
{
    /**
     * @var WeakMap<\stdClass,\stdClass>
     */
    protected static WeakMap $bug;

    public function bug(): void
    {
        static::$bug = new WeakMap();
    }
}
name     : phpstan/phpstan
descrip. : PHPStan - PHP Static Analysis Tool
keywords :
versions : * 0.12.96
type     : library
license  : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
homepage :
source   : [git] https://github.com/phpstan/phpstan.git a98bdc51318f20fcae8c953d266f81a70254917f
dist     : [zip] https://api.github.com/repos/phpstan/phpstan/zipball/a98bdc51318f20fcae8c953d266f81a70254917f a98bdc51318f20fcae8c953d266f81a70254917f
path     : /project/vendor/phpstan/phpstan
names    : phpstan/phpstan

Code snippet that reproduces the problem

https://phpstan.org/r/c82951da-ead5-4999-a670-db23e6fb07b3

Expected output

no error

Did PHPStan help you today? Did it make you happy in any way?

Yep, it is found one possible bug today.

@ondrejmirtes
Copy link
Member

WeakMap doesn't have @template-covariant, it's just invariant, so it's not safe to pass WeakMap<stdClass, stdClass> into WeakMap<object, mixed>. Both of the lines should report an error.

This is because WeakMap implements ArrayAccess and thus has mutable methods. If you'd pass WeakMap<stdClass, stdClass> into WeakMap<object, mixed>, someone might assign something else than stdClass into the object which isn't something you'd want.

@ondrejmirtes
Copy link
Member

Oh I get it now, the bug really shouldn't be reported. The fact is that PHPStan infers the new WeakMap to the type of the property in case of $this->ok but doesn't do that for static property fetches :)

@davidkmenta
Copy link

Any news here? 😊

@netpok
Copy link

netpok commented Sep 25, 2023

Same issue here, also fails on dynamic property with ??=

https://phpstan.org/r/67aa61ad-8ea4-4028-a5b9-313de5bfdb51

@mvorisek
Copy link
Contributor

another repro: https://phpstan.org/r/9cdef996-1e77-4334-bc79-1af78d5b4139

I can confirm this issue is present only when assigning into static property.

@mvorisek
Copy link
Contributor

should be easy fix

@herndlm
Copy link
Contributor

herndlm commented Apr 17, 2024

should be easy fix

Waiting for your PR 😊

@mvorisek
Copy link
Contributor

Let's work on this collaboratively 😊

@phpstan-bot
Copy link
Contributor

@netpok After the latest push in 1.11.x, PHPStan now reports different result with your code snippet:

@@ @@
-PHP 8.0 – 8.3 (2 errors)
+PHP 8.0 – 8.3 (1 error)
 ==========
 
 18: Property HelloWorld::$vm2 (WeakMap<HelloWorld, HelloWorld>) does not accept WeakMap<HelloWorld, HelloWorld>|WeakMap<object, mixed>.
-20: Parameter #1 $a of method HelloWorld::sayHello() expects HelloWorld, HelloWorld|null given.
 
 PHP 7.2 – 7.4 (7 errors)
 ==========
Full report

PHP 8.0 – 8.3 (1 error)

Line Error
18 `Property HelloWorld::$vm2 (WeakMap<HelloWorld, HelloWorld>) does not accept WeakMap<HelloWorld, HelloWorld>

PHP 7.2 – 7.4 (7 errors)

Line Error
10 Property HelloWorld::$vm has unknown class Weakmap as its type.
10 Property HelloWorld::$vm has unknown class Weakmap as its type.
14 Property HelloWorld::$vm2 has unknown class Weakmap as its type.
14 Property HelloWorld::$vm2 has unknown class Weakmap as its type.
18 Instantiated class Weakmap not found.
19 Instantiated class Weakmap not found.
20 Access to offset $this(HelloWorld) on an unknown class Weakmap.

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

Successfully merging a pull request may close this issue.

7 participants