Skip to content

Commit 910e8bc

Browse files
VincentLangletphpstan-bot
authored andcommitted
Mark class_exists, interface_exists, trait_exists, and enum_exists as having no side effects in function metadata
- Add `class_exists`, `interface_exists`, `trait_exists`, and `enum_exists` to `resources/functionMetadata.php` with `hasSideEffects => false`, matching the existing `function_exists` entry - When `rememberPossiblyImpureFunctionValues` was false, the type narrowing from these functions was blocked in `TypeSpecifier::createForExpr()` because they lacked metadata and defaulted to `hasSideEffects = maybe` - Update `AutoloadSourceLocatorTest` to use the return value of `class_exists()` to avoid the now-triggered `function.resultUnused` rule
1 parent 0beee48 commit 910e8bc

4 files changed

Lines changed: 40 additions & 1 deletion

File tree

resources/functionMetadata.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@
812812
'chown' => ['hasSideEffects' => true],
813813
'chr' => ['hasSideEffects' => false],
814814
'chunk_split' => ['hasSideEffects' => false],
815+
'class_exists' => ['hasSideEffects' => false],
815816
'class_implements' => ['hasSideEffects' => false],
816817
'class_parents' => ['hasSideEffects' => false],
817818
'cli_get_process_title' => ['hasSideEffects' => true],
@@ -910,6 +911,7 @@
910911
'diskfreespace' => ['hasSideEffects' => true],
911912
'dngettext' => ['hasSideEffects' => false],
912913
'doubleval' => ['hasSideEffects' => false],
914+
'enum_exists' => ['hasSideEffects' => false],
913915
'error_get_last' => ['hasSideEffects' => true],
914916
'error_log' => ['hasSideEffects' => true],
915917
'escapeshellarg' => ['hasSideEffects' => false],
@@ -1190,6 +1192,7 @@
11901192
'ini_get_all' => ['hasSideEffects' => true],
11911193
'intcal_get_maximum' => ['hasSideEffects' => false],
11921194
'intdiv' => ['hasSideEffects' => false],
1195+
'interface_exists' => ['hasSideEffects' => false],
11931196
'intl_error_name' => ['hasSideEffects' => false],
11941197
'intl_get' => ['hasSideEffects' => false],
11951198
'intl_get_error_code' => ['hasSideEffects' => true],
@@ -1723,6 +1726,7 @@
17231726
'token_get_all' => ['hasSideEffects' => false],
17241727
'token_name' => ['hasSideEffects' => false],
17251728
'touch' => ['hasSideEffects' => true],
1729+
'trait_exists' => ['hasSideEffects' => false],
17261730
'transliterator_create' => ['hasSideEffects' => false],
17271731
'transliterator_create_from_rules' => ['hasSideEffects' => false],
17281732
'transliterator_create_inverse' => ['hasSideEffects' => false],
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser;
4+
5+
use PHPStan\Testing\PHPStanTestCase;
6+
7+
class Bug8579Test extends PHPStanTestCase
8+
{
9+
10+
public function testBug8579(): void
11+
{
12+
$file = $this->getFileHelper()->normalizePath(__DIR__ . '/data/bug-8579.php');
13+
14+
$analyser = self::getContainer()->getByType(Analyser::class);
15+
$finalizer = self::getContainer()->getByType(AnalyserResultFinalizer::class);
16+
$errors = $finalizer->finalize(
17+
$analyser->analyse([$file], null, null, true),
18+
false,
19+
true,
20+
)->getErrors();
21+
$this->assertNoErrors($errors);
22+
}
23+
24+
public static function getAdditionalConfigFiles(): array
25+
{
26+
return [
27+
__DIR__ . '/do-not-remember-possibly-impure-function-values.neon',
28+
];
29+
}
30+
31+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
3+
if (!class_exists('NonexistentClassBug8579')) throw new \Exception('nonexistentclass');
4+
$x = new \NonexistentClassBug8579();

tests/PHPStan/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocatorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function testAutoloadEverythingInFile(): void
5959
$this->assertNotNull($doFooFunctionReflection->getFileName());
6060
$this->assertSame('a.php', basename($doFooFunctionReflection->getFileName()));
6161

62-
class_exists(InCondition::class);
62+
$this->assertTrue(class_exists(InCondition::class));
6363
$classInCondition = $reflector->reflectClass(InCondition::class);
6464
$classInConditionFilename = $classInCondition->getFileName();
6565
$this->assertNotNull($classInConditionFilename);

0 commit comments

Comments
 (0)