Skip to content

Commit

Permalink
Support intersection types in MutatingScope::getTypeToInstantiateForN…
Browse files Browse the repository at this point in the history
…ew()
  • Loading branch information
Richard van Velzen authored and ondrejmirtes committed Jun 2, 2022
1 parent d0a9d08 commit 911ec05
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 26 deletions.
42 changes: 16 additions & 26 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -5009,39 +5009,29 @@ private function exactInstantiation(New_ $node, string $className): ?Type

private function getTypeToInstantiateForNew(Type $type): Type
{
$decideType = static function (Type $type): ?Type {
if ($type instanceof ConstantStringType) {
return new ObjectType($type->getValue());
}
if ($type instanceof GenericClassStringType) {
return $type->getGenericType();
}
if ((new ObjectWithoutClassType())->isSuperTypeOf($type)->yes()) {
return $type;
}
return null;
};

if ($type instanceof UnionType) {
$types = [];
foreach ($type->getTypes() as $innerType) {
$decidedType = $decideType($innerType);
if ($decidedType === null) {
return new ObjectWithoutClassType();
}
$types = array_map(fn (Type $type) => $this->getTypeToInstantiateForNew($type), $type->getTypes());
return TypeCombinator::union(...$types);
}

$types[] = $decidedType;
}
if ($type instanceof IntersectionType) {
$types = array_map(fn (Type $type) => $this->getTypeToInstantiateForNew($type), $type->getTypes());
return TypeCombinator::intersect(...$types);
}

return TypeCombinator::union(...$types);
if ($type instanceof ConstantStringType) {
return new ObjectType($type->getValue());
}

if ($type instanceof GenericClassStringType) {
return $type->getGenericType();
}

$decidedType = $decideType($type);
if ($decidedType === null) {
return new ObjectWithoutClassType();
if ((new ObjectWithoutClassType())->isSuperTypeOf($type)->yes()) {
return $type;
}

return $decidedType;
return new ObjectWithoutClassType();
}

/** @api */
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-strrchr-specifying.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-strcasing-specifying.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/conditional-complex-templates.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7374.php');
}

/**
Expand Down
18 changes: 18 additions & 0 deletions tests/PHPStan/Analyser/data/bug-7374.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php declare(strict_types = 1);

namespace Bug7374;

use function PHPStan\Testing\assertType;

class HelloWorld
{
/** @return class-string<self>&literal-string */
public static function getClass(): string {
return self::class;
}

public function build(): void {
$class = self::getClass();
assertType(self::class, new $class());
}
}

0 comments on commit 911ec05

Please sign in to comment.