Skip to content

Commit

Permalink
Fix interaction between template type and intersection type
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-lb authored and ondrejmirtes committed Jan 30, 2022
1 parent 21947ff commit f8af5dc
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Type/Generic/TemplateTypeTrait.php
Expand Up @@ -121,7 +121,7 @@ public function accepts(Type $type, bool $strictTypes): TrinaryLogic

public function isSuperTypeOf(Type $type): TrinaryLogic
{
if ($type instanceof self) {
if ($type instanceof self || $type instanceof IntersectionType) {
return $type->isSubTypeOf($this);
}

Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Generics/GenericsIntegrationTest.php
Expand Up @@ -24,6 +24,7 @@ public function dataTopics(): array
['bug2620'],
['bug2622'],
['bug2627'],
['bug6210'],
];
}

Expand Down
29 changes: 29 additions & 0 deletions tests/PHPStan/Generics/data/bug6210.php
@@ -0,0 +1,29 @@
<?php

namespace Generics\Bug6210;

/**
* @template TEntityClass of object
*/
class HelloWorld
{
/**
* @phpstan-param TEntityClass $entity
*/
public function provide($entity, ?string $value): void
{
if (null !== $value) {
if (!method_exists($entity, 'getId')) {
throw new \InvalidArgumentException();
}
}
$this->show($entity);
}

/**
* @phpstan-param TEntityClass $entity
*/
private function show($entity): void
{
}
}
107 changes: 107 additions & 0 deletions tests/PHPStan/Type/TypeCombinatorTest.php
Expand Up @@ -28,6 +28,7 @@
use PHPStan\Type\Generic\GenericClassStringType;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\Generic\TemplateBenevolentUnionType;
use PHPStan\Type\Generic\TemplateMixedType;
use PHPStan\Type\Generic\TemplateObjectType;
use PHPStan\Type\Generic\TemplateObjectWithoutClassType;
use PHPStan\Type\Generic\TemplateType;
Expand Down Expand Up @@ -1204,6 +1205,112 @@ public function dataUnion(): iterable
UnionType::class,
'T of DateTime (function a(), parameter)|U of DateTime (function a(), parameter)',
],
'bug6210-1' => [
[
new ObjectWithoutClassType(),
new IntersectionType([
new ObjectWithoutClassType(),
new HasMethodType('getId'),
]),
],
ObjectWithoutClassType::class,
'object',
],
'bug6210-2' => [
[
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
null,
TemplateTypeVariance::createInvariant(),
),
new IntersectionType([
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
null,
TemplateTypeVariance::createInvariant(),
),
new HasMethodType('getId'),
]),
],
TemplateMixedType::class,
'T (function a(), parameter)=explicit',
],
'bug6210-3' => [
[
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
new ObjectWithoutClassType(),
TemplateTypeVariance::createInvariant(),
),
new IntersectionType([
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
new ObjectWithoutClassType(),
TemplateTypeVariance::createInvariant(),
),
new HasMethodType('getId'),
]),
],
TemplateObjectWithoutClassType::class,
'T of object (function a(), parameter)',
],
'bug6210-4' => [
[
new ObjectWithoutClassType(),
new IntersectionType([
new ObjectWithoutClassType(),
new HasPropertyType('getId'),
]),
],
ObjectWithoutClassType::class,
'object',
],
'bug6210-5' => [
[
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
null,
TemplateTypeVariance::createInvariant(),
),
new IntersectionType([
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
null,
TemplateTypeVariance::createInvariant(),
),
new HasPropertyType('getId'),
]),
],
TemplateMixedType::class,
'T (function a(), parameter)=explicit',
],
'bug6210-6' => [
[
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
new ObjectWithoutClassType(),
TemplateTypeVariance::createInvariant(),
),
new IntersectionType([
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('a'),
'T',
new ObjectWithoutClassType(),
TemplateTypeVariance::createInvariant(),
),
new HasPropertyType('getId'),
]),
],
TemplateObjectWithoutClassType::class,
'T of object (function a(), parameter)',
],
[
[
new BenevolentUnionType([new IntegerType(), new StringType()]),
Expand Down

0 comments on commit f8af5dc

Please sign in to comment.