Skip to content

Check the subtracted type when a subtracted mixed accepts a value - #6167

Open
zonuexe wants to merge 1 commit into
phpstan:2.2.xfrom
zonuexe:non-empty-mixed-accepts
Open

Check the subtracted type when a subtracted mixed accepts a value#6167
zonuexe wants to merge 1 commit into
phpstan:2.2.xfrom
zonuexe:non-empty-mixed-accepts

Conversation

@zonuexe

@zonuexe zonuexe commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Closes phpstan/phpstan#15033

MixedType::accepts (and StrictMixedType, reached once RuleLevelHelper rewrites an explicit MixedType for checkExplicitMixed) accepted every value unconditionally, so a subtracted mixed like non-empty-mixed rejected nothing at argument or return boundaries, even though the same subtraction already powered narrowing and reachability (identical.alwaysFalse, if.alwaysTrue, etc.).

Acceptance now turns to No only on a definite hit (subtractedType->isSuperTypeOf($given)->yes()), so partial overlaps (e.g. a general string into non-empty-mixed, which may or may not be '') stay accepted — this preserves mixed's usual looseness and is why the fix isn't isSuperTypeOf(...)->toAcceptsResult(). NeverType is exempted, mirroring MixedType::isSuperTypeOf.

RuleLevelHelper::transformCommonType now carries the subtraction through when it converts an explicit MixedType into StrictMixedType, instead of discarding it — otherwise level max stayed silent even with MixedType fixed. VerbosityLevel::getRecommendedLevelByType escalates to precise() when a subtracted (Strict)MixedType is involved, so messages render the subtraction instead of a bare, uninformative mixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

non-empty-mixed is used for narrowing but not enforced at call/return boundaries

1 participant