diff --git a/src/Type/StrictMixedType.php b/src/Type/StrictMixedType.php index 7477144c93..05dee89bc5 100644 --- a/src/Type/StrictMixedType.php +++ b/src/Type/StrictMixedType.php @@ -17,6 +17,7 @@ use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Enum\EnumCaseObjectType; use PHPStan\Type\Generic\TemplateMixedType; +use PHPStan\Type\Generic\TemplateStrictMixedType; use PHPStan\Type\Generic\TemplateTypeMap; use PHPStan\Type\Generic\TemplateTypeVariance; use PHPStan\Type\Traits\NonArrayTypeTrait; @@ -61,7 +62,7 @@ public function accepts(Type $type, bool $strictTypes): AcceptsResult public function isAcceptedBy(Type $acceptingType, bool $strictTypes): AcceptsResult { - if ($acceptingType instanceof self) { + if ($acceptingType instanceof self && !$acceptingType instanceof TemplateStrictMixedType) { return AcceptsResult::createYes(); } if ($acceptingType instanceof MixedType && !$acceptingType instanceof TemplateMixedType) { @@ -78,7 +79,7 @@ public function isSuperTypeOf(Type $type): IsSuperTypeOfResult public function isSubTypeOf(Type $otherType): IsSuperTypeOfResult { - if ($otherType instanceof self) { + if ($otherType instanceof self && !$otherType instanceof TemplateStrictMixedType) { return IsSuperTypeOfResult::createYes(); } if ($otherType instanceof MixedType && !$otherType instanceof TemplateMixedType) { diff --git a/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php b/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php index d2a48d3ae6..a25023c402 100644 --- a/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php @@ -448,6 +448,10 @@ public function testBug11935WithCheckExplicitMixed(): void { $this->checkExplicitMixed = true; $this->analyse([__DIR__ . '/data/bug-11935.php'], [ + [ + 'Parameter #1 of callable callable(A): A expects A, mixed given.', + 16, + ], [ 'Parameter #1 of callable callable(Bug11935\Inv): Bug11935\Inv expects Bug11935\Inv, Bug11935\Inv given.', 34, diff --git a/tests/PHPStan/Type/StrictMixedTypeTest.php b/tests/PHPStan/Type/StrictMixedTypeTest.php new file mode 100644 index 0000000000..909c3d3183 --- /dev/null +++ b/tests/PHPStan/Type/StrictMixedTypeTest.php @@ -0,0 +1,62 @@ +isSubTypeOf($otherType); + $this->assertSame( + $expectedResult->describe(), + $actualResult->describe(), + sprintf('%s -> isSubTypeOf(%s)', $type->describe(VerbosityLevel::precise()), $otherType->describe(VerbosityLevel::precise())), + ); + } + + #[DataProvider('dataIsSubTypeOf')] + public function testIsSubTypeOfInversed(StrictMixedType $type, Type $otherType, TrinaryLogic $expectedResult): void + { + $actualResult = $otherType->isSuperTypeOf($type); + $this->assertSame( + $expectedResult->describe(), + $actualResult->describe(), + sprintf('%s -> isSuperTypeOf(%s)', $otherType->describe(VerbosityLevel::precise()), $type->describe(VerbosityLevel::precise())), + ); + } + +}