Skip to content

Report implicit mixed inside compound types as too wide at all rule levels#5608

Closed
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-8d3krxm
Closed

Report implicit mixed inside compound types as too wide at all rule levels#5608
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-8d3krxm

Conversation

@phpstan-bot
Copy link
Copy Markdown
Collaborator

Closes phpstan/phpstan#8681

Summary

Since 1.9.5, PHPStan stopped reporting that a bare array (implicit array<mixed, mixed>) is too wide for a declared @return array<string, string>. The root cause was in RuleLevelHelper::transformCommonType(): an early return checked !$this->checkExplicitMixed && !$this->checkImplicitMixed and short-circuited the entire transformation, preventing implicit mixed inside compound types from being converted to StrictMixedType.

The fix:

  • Narrows the early return to only fire when the type itself is a top-level MixedType (not a compound type containing mixed)
  • Adds a $isTopLevel tracker so that implicit mixed at non-top-level positions (array value types, array key types, callable return types, generic type parameters) is converted to StrictMixedType even when checkImplicitMixed is false
  • Guards against converting TemplateMixedType, which should remain as-is

This restores the pre-1.9.5 behavior where array is not silently accepted where array<string, string> is expected, regardless of rule level.

Scope of changes

The fix applies to all call sites of RuleLevelHelper::accepts(), meaning it affects:

  • Return type checking (methods, functions, closures) — the original issue
  • Property assignment checkingarray assigned to array<string, string> property
  • Parameter type checkingarray passed where array<string, string> parameter expected

New errors are now correctly reported for:

  • array where array<K, V> is expected (both key and value mismatch)
  • iterable where iterable<K, V> is expected
  • Closure(): mixed where callable(): int is expected (implicit mixed return type)
  • Generic<mixed> where Generic<Specific> is expected (when mixed is implicit)

Test changes

  • Added regression test data files for methods, functions, and property assignments (bug-8681.php)
  • Updated 20 existing test expectations to reflect newly-detected type mismatches
  • Updated PHPStan baseline for 49 newly-detected errors in PHPStan's own codebase
  • Fixed @return string[]@return list<string> annotations on test helper methods exposed by the change

…evels

When a variable is typed as bare `array` (i.e. `array<mixed, mixed>` with
implicit mixed), returning it from a function declared as `@return array<string, string>`
should report an error regardless of the rule level. This was a regression
introduced in 1.9.5 when the early return in `transformCommonType()` was
added — it short-circuited the entire transformation when both
`checkExplicitMixed` and `checkImplicitMixed` were false, which prevented
implicit mixed types inside compound types from being converted to
StrictMixedType.

The fix narrows the early return to only fire for top-level MixedType, and
adds a new condition that converts non-top-level implicit mixed to
StrictMixedType even when `checkImplicitMixed` is false. This means `array`,
`iterable`, and other compound types with unspecified type parameters are
now checked strictly against their expected types at all rule levels.

Closes phpstan/phpstan#8681
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.

2 participants