Repository navigation
Conversation
7ac51a6 to
c062fdd
Compare
619e135 to
babb3d5
Compare
|
The last commit is a cherry-pick of #6697 (author kept): |
35cedda to
fd0daee
Compare
|
Rebased on the current The last commit is a cherry-pick of #6729 (author kept): the |
21d27fb to
eedada2
Compare
|
@staabm would you mind taking a look? With phpstan/phpstan#15468 merged, CI here is fully green now. The fix is in |
b5f2604 to
d58614e
Compare
b1ede1d to
9e52a3d
Compare
| # A reflection error, here a class that extends itself, still keeps the result cache from | ||
| # being saved. | ||
| cp loop/Loop.php src/Loop.php | ||
| OUTPUT=$(../bashunit assert exit_code "1" "../../bin/phpstan analyse -vvv --error-format raw") | ||
| echo "$OUTPUT" | ||
| ../bashunit assert contains 'Result cache was not saved because of non-ignorable exception: Reflection error: Circular reference' "$OUTPUT" |
There was a problem hiding this comment.
why do we need to adjust this tests expectations?
| @@ -0,0 +1,49 @@ | |||
| <?php declare(strict_types = 1); | |||
There was a problem hiding this comment.
ondrej talks about his expectations in phpstan/phpstan#12680 (comment)
we should assert these in a separate test
|
|
||
| namespace ResultCacheE2EParseError; | ||
|
|
||
| class Loop extends Loop |
There was a problem hiding this comment.
why do we delete this file?
9e52a3d to
0934995
Compare
…eturn type A return type like `static<int, string>` (no template type in its arguments) was turned into a GenericObjectType that kept the ClassReflection of the declaring class, so methods called on the result saw unresolved TKey/TValue (`array<TKey, TValue>`). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Mirrors CalledOnTypeUnresolvedMethodPrototypeReflection::transformStaticType() from the previous commit. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rule Since the BetterReflection update in 613b1b1, a class that extends itself is no longer a reflection error, so the last part of the result-cache-parse-error e2e test failed. A rule that throws ClassNotFoundException now tests the same branch of the save, in the result-cache-internal-error fixture. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
0934995 to
befece6
Compare
A
static<...>return type whose arguments reference no template type is not resolved on a generic receiver:CalledOnTypeUnresolvedMethodPrototypeReflection::transformStaticType()turns theGenericStaticTypeintogetStaticObjectType(), which hands the declaring class'ClassReflection(without the type arguments) to theGenericObjectType. When an argument contains a template,traverse()recreates the object and the reflection is resolved lazily, which is why only the fully concrete case breaks. I reproduced this on 2.2.14 and 2.3.0, so it is not a regression.It is visible in Laravel's
Collection(@return static<int, mixed>onflatten(),collapse(),values(), …):$collection->flatten()->merge($x)leaksTKey/TValue, which Larastan has to baseline in its monica E2E.The fix builds the object without the stale reflection in
transformStaticType()only. I first changedGenericStaticType::getStaticObjectType(), but that also changesnew static(...)(NewHandler) and drops the expected error ofReturnTypeRuleTest::testBug4590, so I narrowed it to the method return type resolution.Caveats:
CalledOnTypeUnresolvedMethodPrototypeReflectionis shadowed byturbo-ext. I have not ported the change to the.cppmirror or run the suite with the extension loaded, since I can't build and verify it properly here. Happy to follow up if you prefer that in this PR.paratest, 22505 tests) passes without the extension.🤖 Generated with Claude Code