Fix FiberScope filtering, @var destructuring check, and deferred constant-condition reporting - #6164
Merged
Conversation
… lists FiberScope::filterByFalseyValue() called parent::filterByTruthyValue(), so the filtered scope's expression types carried the TRUTHY narrowing: direct state reads (getVariableType(), hasVariableType(), anything via toMutatingScope()) returned the opposite answer, and synthetic-node type asks were derived from the wrongly-narrowed state. The fiber getType() path masked the bug for stored real nodes by re-deriving from the recorded falseyValueExprs. Both filter methods also copied only their own expression list onto the derived scope, so chaining filterByTruthyValue()->filterByFalseyValue() dropped the truthy filter from every fiber-routed type ask. Both lists are now carried, matching pushInFunctionCall()/popInFunctionCall(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The destructuring branch of VarTagTypeRuleHelper::checkVarType() wrapped the PHPDoc-derived offset type in a plain TypeExpr, so the native-type check compared the @var type against the PHPDoc offset type: a factually wrong varTag.nativeType error (reported unconditionally) where the PHPDoc comparison should produce varTag.type (gated on reportWrongPhpDocTypeInVarTag). Carry both flavours in a NativeTypeExpr, mirroring the foreach key/value sites in WrongVariableNameInVarTagRule. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The arm comparison error for a type-check call arm was always deferred
under the raw call's expression key and dropped whenever an
ImpossibleCheckType* marker existed for that call - so for an ordinary
subject, match ($i) { is_int($y) => ... } silently lost the
"Match arm comparison between int and true is always false." error that
is an independent finding from the call's own constant truthiness.
Only for a match(true)-style subject is the arm comparison the same
fact as the call being always-true/false; the deferral (and its no-error
twin) is now gated on the subject being a constant boolean, mirroring
the pre-collector standalone-truthiness deduplication.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Non-trait entries in FunctionCallConstantConditionRule were grouped project-wide by printed expression and line only, then deduplicated by message: the same condition at the same line in two different files collapsed into a single report, and an ImpossibleCheckType* marker from one file suppressed an unrelated deferred error at the matching print+line in another file (e.g. a userland function shadowing a built-in type-check name). Non-trait bucket keys and the marker lookup now carry the collected file path. Trait entries keep merging across analysed contexts and matching markers from any context - trait names are unique project-wide. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ondrejmirtes
force-pushed
the
review-bug-fixes
branch
from
July 31, 2026 13:03
9256b08 to
46660a9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four bug fixes from the resolve-type-rewrite branch review — these are the findings that apply to mainline (pre-existing, or arrived with the progressively merged chunks). Each commit adds a test that failed before the fix:
filterByFalseyValue()calledparent::filterByTruthyValue(), so a rule filtering the scope it received saw inverted narrowing on direct state reads (getVariableType(),toMutatingScope()); chainedfilterByTruthyValue()->filterByFalseyValue()additionally dropped the truthy filter from fiber-routed type asks.TypeExpr, reporting a factually wrongvarTag.nativeTypeerror (unconditionally) instead of the flag-gatedvarTag.type.match ($i) { is_int($y) => … }silently lost the "Match arm comparison between int and true is always false." error whenever an ImpossibleCheckType marker existed for the call; only for a constant-boolean subject is the arm comparison the same fact those rules own.Full test suite and self-analysis green.
🤖 Generated with Claude Code
https://claude.ai/code/session_01JjrRao9kSNLAipk2Go5Kek