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 positives on array access on iterable property with PHPDoc type that allows it #6243

Closed
julienfalque opened this issue Dec 27, 2021 · 9 comments · Fixed by phpstan/phpstan-src#1860

Comments

@julienfalque
Copy link

Bug report

Given a property with native type iterable and PHPDoc type that allows array access, e.g. array, reading or writing to this property using array access is reported as an error.

Code snippet that reproduces the problem

<?php

class Foo
{
    /** @var list<string>|(\ArrayAccess<int, string>&iterable<int, string>) */
    private iterable $values;

    /**
     * @param list<string> $values
     */
    public function update(array $values): void {
        foreach ($this->values as $key => $_) {
            unset($this->values[$key]);
        }

        foreach ($values as $value) {
            $this->values[] = $value;
        }
    }
}

PHPStan reports the following errors:

13 | Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)\|iterable<int, string>.
-- | --
17 | Cannot access an offset on iterable<int, string>.

https://phpstan.org/r/42af72fd-760d-4132-8e1b-14449f2efe59

Expected output

No errors

@ondrejmirtes
Copy link
Member

The problem is that having:

  • list<string>|(\ArrayAccess<int, string>&iterable<int, string>) in PHPDoc
  • iterable in the native type

leads to (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string> actual type: https://phpstan.org/r/c85fad6d-0047-4f3f-a5f9-a41753298935

So that's what we need to solve here.

@julienfalque
Copy link
Author

phpstan/phpstan-src#891 solves that by keeping the PHPDoc type as-is. I had to change a few existing tests but that seemed legit to me. Are there use cases I am missing that would require a different fix?

@phpstan-bot
Copy link
Contributor

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

@@ @@
-13: Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>.
+13: Cannot access offset int on iterable<int, string>.
 17: Cannot access an offset on iterable<int, string>.
Full report
Line Error
13 Cannot access offset int on iterable<int, string>.
17 Cannot access an offset on iterable<int, string>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
 12: Dumped type: (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>
-14: Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>.
+14: Cannot access offset int on iterable<int, string>.
 18: Cannot access an offset on iterable<int, string>.
Full report
Line Error
12 `Dumped type: (ArrayAccess<int, string>&iterable<int, string>)
14 Cannot access offset int on iterable<int, string>.
18 Cannot access an offset on iterable<int, string>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-13: Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>.
 17: Cannot access an offset on iterable<int, string>.
Full report
Line Error
17 Cannot access an offset on iterable<int, string>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
 12: Dumped type: (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>
-14: Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>.
 18: Cannot access an offset on iterable<int, string>.
Full report
Line Error
12 `Dumped type: (ArrayAccess<int, string>&iterable<int, string>)
18 Cannot access an offset on iterable<int, string>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-13: Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>.
-17: Cannot access an offset on iterable<int, string>.
+No errors

@phpstan-bot
Copy link
Contributor

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

@@ @@
-12: Dumped type: (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>
-14: Cannot access offset int on (ArrayAccess<int, string>&iterable<int, string>)|iterable<int, string>.
-18: Cannot access an offset on iterable<int, string>.
+12: Dumped type: list<string>|(ArrayAccess<int, string>&iterable<int, string>)
Full report
Line Error
12 `Dumped type: list

@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 Nov 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants