← All results

new $c when $c is a class string with a leading backslash

Group: Cross-analyzer regressions · Category: regression · File: regressions_new_class_string_leading_backslash.php

"\\DateTimeImmutable" and "DateTimeImmutable" name the same class. A lookup that keeps the slash misses the constructor and skips InterfaceInstantiation for "\\Countable". The slash-free string is the control: a diagnostic there means the tool does not instantiate from a string at all, not that it mishandles the slash. Source: vimeo/psalm#12039, from #5679. References: - psalm#12039

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.10Phan 6.0.10 php-ast version 1.1.3 PHP version used to run Phan: 8.5.11 Pass
regressions_new_class_string_leading_backslash.php:41: Unused result of new object creation expression in new $class() (this may be called for the side effects of the non-empty constructor or destructor) [PhanNoopNew]
regressions_new_class_string_leading_backslash.php:41: Instantiation of abstract class \Countable [PhanTypeInstantiateAbstract]
regressions_new_class_string_leading_backslash.php:47: Unused result of new object creation expression in new $class() (this may be called for the side effects of the non-empty constructor or destructor) [PhanNoopNew]
regressions_new_class_string_leading_backslash.php:47: Instantiation of abstract class \Countable [PhanTypeInstantiateAbstract]
phpstan 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Pass reported Lv.0+
regressions_new_class_string_leading_backslash.php:41: Cannot instantiate interface Countable. [reported-from-level=0]
regressions_new_class_string_leading_backslash.php:47: Cannot instantiate interface Countable. [reported-from-level=0]
With strict-rules
regressions_new_class_string_leading_backslash.php:41: Cannot instantiate interface Countable.
regressions_new_class_string_leading_backslash.php:47: Cannot instantiate interface Countable.
psalm 6.20.0Psalm 6.20.0@804f03c0c183d149fcd4b8c7c0c9b3fbf836d34c
next: 7.0.0-rc2
Pass (pzoom≠)
regressions_new_class_string_leading_backslash.php:29: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:35: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:41: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:41: Interface Countable cannot be instantiated [InterfaceInstantiation]
regressions_new_class_string_leading_backslash.php:47: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:47: Interface Countable cannot be instantiated [InterfaceInstantiation]
pzoom (Psalm port)
regressions_new_class_string_leading_backslash.php:41: Cannot instantiate interface Countable [InterfaceInstantiation]
regressions_new_class_string_leading_backslash.php:47: Cannot instantiate interface Countable [InterfaceInstantiation]
mago 1.57.0mago 1.57.0 Pass
regressions_new_class_string_leading_backslash.php:35: Class `\DateTimeImmutable` not found. [non-existent-class]
regressions_new_class_string_leading_backslash.php:35: Argument #1 passed to function `Conformance\Tests\RegressionsNewClassStringLeadingBackslash\takesImmutable` has type `never`, meaning it cannot produce a value. [no-value]
regressions_new_class_string_leading_backslash.php:41: Class `\Countable` not found. [non-existent-class]
regressions_new_class_string_leading_backslash.php:47: Interface `Countable` cannot be instantiated with `new`. [interface-instantiation]
mir 0.87.0mir 0.87.0 Fail

No diagnostics reported.

Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
phpantom 0.11.1phpantom_lsp 0.11.1 Fail

No diagnostics reported.

Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
intelephense 1.18.5intelephense 1.18.5 Fail
regressions_new_class_string_leading_backslash.php:29: Expected type 'DateTimeImmutable'. Found 'object'. [P1006]
regressions_new_class_string_leading_backslash.php:35: Expected type 'DateTimeImmutable'. Found 'object'. [P1006]
Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
phpactor 2026.10.07.0Phpactor 2026.10.07.0 Fail

No diagnostics reported.

Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
phpy 1.0.19409phpy 1.0.19409 Fail

No diagnostics reported.

Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
qodana 262.10968.76PhpStorm 262.10968.76 Fail

No diagnostics reported.

Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
noverify 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 Pass
regressions_new_class_string_leading_backslash.php:41: Expression evaluated but not used [discardExpr]
regressions_new_class_string_leading_backslash.php:47: Expression evaluated but not used [discardExpr]
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Fail

No diagnostics reported.

Expectation diff
Line 41: Expected 1 error(s)
Line 47: Expected 1 error(s)
phpstan-strict 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Pass
regressions_new_class_string_leading_backslash.php:41: Cannot instantiate interface Countable.
regressions_new_class_string_leading_backslash.php:47: Cannot instantiate interface Countable.
psalm-next 7.0.0-rc2Psalm 7.0.0-rc2@20339e3fe5b8d03bcd8061030eb2a83ad50e5783 Pass
regressions_new_class_string_leading_backslash.php:29: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:35: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:41: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:41: Interface Countable cannot be instantiated [InterfaceInstantiation]
regressions_new_class_string_leading_backslash.php:47: String cannot be used as a class [InvalidStringClass]
regressions_new_class_string_leading_backslash.php:47: Interface Countable cannot be instantiated [InterfaceInstantiation]

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\RegressionsNewClassStringLeadingBackslash;

/**
 * `new $c` when `$c` is a class string with a leading backslash.
 *
 * `"\\DateTimeImmutable"` and `"DateTimeImmutable"` name the same class. A
 * lookup that keeps the slash misses the constructor and skips
 * `InterfaceInstantiation` for `"\\Countable"`. The slash-free string is the
 * control: a diagnostic there means the tool does not instantiate from a
 * string at all, not that it mishandles the slash.
 *
 * Source: vimeo/psalm#12039, from #5679.
 *
 * References:
 * - https://github.com/vimeo/psalm/pull/12039
 */

function takesImmutable(\DateTimeImmutable $value): void
{
}

function fromPlainString(): void
{
    $class = 'DateTimeImmutable';
    takesImmutable(new $class()); // Q?: some tools ban `new $string` entirely (`InvalidStringClass`); silence here is the slash-free control
}

function fromLeadingSlash(): void
{
    $class = '\\DateTimeImmutable';
    takesImmutable(new $class()); // Q?: a leading backslash still names DateTimeImmutable when `new $string` is allowed
}

function interfaceWithSlash(): void
{
    $class = '\\Countable';
    new $class(); // E: Countable is an interface
}

function interfaceWithoutSlash(): void
{
    $class = 'Countable';
    new $class(); // E: the same without a slash, so a hit here is not the slash bug
}