Skip to content
8 changes: 1 addition & 7 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1473,12 +1473,6 @@ parameters:
count: 1
path: src/Type/ObjectShapeType.php

-
rawMessage: 'Doing instanceof PHPStan\Type\Enum\EnumCaseObjectType is error-prone and deprecated. Use Type::getEnumCases() instead.'
identifier: phpstanApi.instanceofType
count: 1
path: src/Type/ObjectType.php

-
rawMessage: Doing instanceof PHPStan\Type\Generic\GenericObjectType is error-prone and deprecated.
identifier: phpstanApi.instanceofType
Expand All @@ -1488,7 +1482,7 @@ parameters:
-
rawMessage: 'Doing instanceof PHPStan\Type\ObjectType is error-prone and deprecated. Use Type::isObject() or Type::getObjectClassNames() instead.'
identifier: phpstanApi.instanceofType
count: 3
count: 2
path: src/Type/ObjectType.php

-
Expand Down
7 changes: 2 additions & 5 deletions src/Type/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
use function array_map;
use function array_values;
use function count;
use function get_class;
use function implode;
use function in_array;
use function sprintf;
Expand Down Expand Up @@ -624,11 +625,7 @@ public function isSuperTypeOf(Type $type): IsSuperTypeOfResult

public function equals(Type $type): bool
{
if (!$type instanceof self) {
return false;
}

if ($type instanceof EnumCaseObjectType) {
if (get_class($type) !== static::class) {
return false;
}

Expand Down
24 changes: 24 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-14429.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php // lint >= 8.0

declare(strict_types = 1);

namespace Bug14429Nsrt;

use function PHPStan\Testing\assertType;
use function PHPStan\Testing\assertNativeType;

/**
* @param \ArrayObject<string, int> $intKeyMap
* @param \ArrayObject<string, string> $stringMap
*/
function testBoth(\ArrayObject $intKeyMap, \ArrayObject $stringMap): void
{
foreach ($intKeyMap as $intKeyMapValue) {
assertType("int", $intKeyMapValue);
assertNativeType("mixed", $intKeyMapValue);
}
foreach ($stringMap as $stringMapValue) {
assertType("string", $stringMapValue);
assertNativeType("mixed", $stringMapValue);
}
}
51 changes: 51 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-3028.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types = 1);

namespace Bug3028;

use function PHPStan\Testing\assertType;

interface Output { }
final class OutputImpl1 implements Output { }
final class OutputImpl2 implements Output { }

/** @template O of Output */
interface Format
{
/** @return O */
public function output() : Output;

/** @param O $o */
public function replace(Output $o) : void;
}

/** @implements Format<OutputImpl1> */
final class FormatImpl1 implements Format
{
public OutputImpl1 $o;

public function __construct() { $this->o = new OutputImpl1; }

public function output() : Output { return new OutputImpl1(); }

/** @param OutputImpl1 $o */
public function replace(Output $o) : void { $this->o = $o; }
}

/**
* @template O of Output
* @param Format<O> $outputFormat
* @return Format<Output>
*/
function run(Format $outputFormat) : Format {
return $outputFormat;
}

function test(): void
{
$a = new FormatImpl1;
assertType('Bug3028\FormatImpl1', $a);
assertType('Bug3028\Format<Bug3028\Output>', run($a));
assertType('Bug3028\Output', run($a)->output());
}
42 changes: 42 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-5298.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types = 1);

namespace Bug5298;

use function PHPStan\Testing\assertType;

interface WorldProvider{}
interface WritableWorldProvider extends WorldProvider{}

/**
* @phpstan-template TWorldProvider of WorldProvider
*/
class WorldProviderManagerEntry{
/** @phpstan-param TWorldProvider $provider */
public function acceptsTWorldProvider(WorldProvider $provider) : void{}
}

final class WorldProviderManager{
/** @phpstan-var array<string, WorldProviderManagerEntry<WorldProvider>> */
protected $providers = [];

/**
* @phpstan-template T of WorldProvider
* @phpstan-param WorldProviderManagerEntry<T> $providerEntry
*/
public function addProvider(WorldProviderManagerEntry $providerEntry, string $name, bool $overwrite = false) : void{
$name = strtolower($name);
if(!$overwrite and isset($this->providers[$name])){
throw new \InvalidArgumentException("Alias \"$name\" is already assigned");
}
assertType('array<string, Bug5298\WorldProviderManagerEntry<Bug5298\WorldProvider>>', $this->providers);
assertType('Bug5298\WorldProviderManagerEntry<T of Bug5298\WorldProvider (method Bug5298\WorldProviderManager::addProvider(), argument)>', $providerEntry);
$this->providers[$name] = $providerEntry;
}

public function doSomething(string $name, WorldProvider $provider) : void{
assertType('Bug5298\WorldProviderManagerEntry<Bug5298\WorldProvider>', $this->providers[$name]);
$this->providers[$name]->acceptsTWorldProvider($provider);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1207,4 +1207,11 @@ public function testBug13799(): void
]);
}

#[RequiresPhp('>= 8.0')]
public function testBug14429(): void
{
$this->treatPhpDocTypesAsCertain = false;
$this->analyse([__DIR__ . '/data/bug-14429.php'], []);
}

}
29 changes: 29 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/bug-14429.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php // lint >= 8.0

declare(strict_types = 1);

namespace Bug14429;

function throw_if(bool $condition, string $message): void
{
if ($condition) { throw new \Exception($message); }
}

class Foo
{
/**
* @param \ArrayObject<string, string> $stringMap
* @param \ArrayObject<string, int> $intKeyMap
*/
public function __construct(
public \ArrayObject $stringMap,
public \ArrayObject $intKeyMap,
) {
foreach ($stringMap as $stringMapValue) {
throw_if(!is_string($stringMapValue), 'stringMap value must be string');
}
foreach ($intKeyMap as $intKeyMapKey => $intKeyMapValue) {
throw_if(!is_int($intKeyMapValue), 'intKeyMap value must be int');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ public function testBug10130(): void
]);
}

public function testBug14429(): void
{
$this->analyse([__DIR__ . '/data/bug-14429-var-tag.php'], []);
}

public function testBug12708(): void
{
$this->analyse([__DIR__ . '/data/bug-12708.php'], [
Expand Down
29 changes: 29 additions & 0 deletions tests/PHPStan/Rules/PhpDoc/data/bug-14429-var-tag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types = 1);

namespace Bug14429VarTag;

/** @template E of IEntity */
class ICollection {}

class IEntity {
/** @return ICollection<IEntity> */
public function getCollection(): ICollection { return new ICollection(); }
}

/**
* @template E of IEntity
*/
class OneHasOne
{
/**
* @return ICollection<E>
*/
protected function createCollection(IEntity $e): ICollection
{
/** @var ICollection<E> $collection */
$collection = $e->getCollection();
return $collection;
}
}
Loading