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

Incorrect UninitializedProperty / PossiblyNullReference error due to buggy parent constructor detection #4540

Closed
colinodell opened this issue Nov 12, 2020 · 4 comments
Labels

Comments

@colinodell
Copy link

colinodell commented Nov 12, 2020

In the following example, I have three classes which extend from each other (C extends B extends A): https://psalm.dev/r/6f670c1ffe The middle class does not have a constructor but the other two do.

Psalm doesn't seem to realize that when C's constructor calls parent::__construct() it results in A's constructor being called. As a result, Psalm thinks the property is never set, although it definitely is: https://3v4l.org/Q8lq3

@psalm-github-bot
Copy link

I found these snippets:

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

class A
{
    protected DateTimeImmutable $date;
    
    public function __construct()
    {
        $this->date = new DateTimeImmutable();
    }
}

class B extends A
{
}

class C extends B
{
    public function __construct()
    {
        parent::__construct();

        echo "I was instantiated at " . $this->date->format('c');
    }
}

new C();
Psalm output (using commit 929efcc):

ERROR: UninitializedProperty - 23:41 - Cannot use uninitialized property $this->date

ERROR: PossiblyNullReference - 23:54 - Cannot call method format on possibly null value

ERROR: PropertyNotSetInConstructor - 17:7 - Property C::$date is not defined in constructor of C and in any methods called in the constructor

@muglug
Copy link
Collaborator

muglug commented Nov 12, 2020

One workaround is to specify the constructor explicitly: https://psalm.dev/r/0851f087dc

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/0851f087dc
<?php

class A
{
    protected DateTimeImmutable $date;
    
    public function __construct()
    {
        $this->date = new DateTimeImmutable();
    }
}

class B extends A
{
}

class C extends B
{
    public function __construct()
    {
        A::__construct();

        echo "I was instantiated at " . $this->date->format('c');
    }
}

new C();
Psalm output (using commit 3dd185e):

No issues!

@weirdan weirdan added the bug label Nov 13, 2020
@weirdan
Copy link
Collaborator

weirdan commented Nov 13, 2020

One workaround is to specify the constructor explicitly

It's would be very unusual to see the code like that. parent::__construct() is idiomatic in PHP, it's not something that's going to change.

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