← All results

A leading backslash on a PHPDoc keyword is not a fully-qualified name

Group: Advanced PHPDoc types · Category: ecosystem · File: phpdoc_advanced_leading_backslash_keyword.php

A slashed int keyword looks like a slashed DateTime, but int is a language keyword, not a class in the root namespace. Native PHP rejects that form on a parameter type at parse time. In a docblock the slash is spelling. mir 0.73.0 reports InvalidDocblockType (MIR1107) at the token and still type-checks the parameter as int. Other tools may strip the slash and read int, or look up a class named int. A slashed DateTime is the control: a leading backslash on a real class is a fully-qualified name and must stay valid. A tool that rejects every backslash-prefixed type fails that control. References: - mir 0.73.0 InvalidDocblockType / MIR1107 (int and non-empty-array cases)

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.7Phan 6.0.7 php-ast version 1.1.3 PHP version used to run Phan: 8.5.9 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:28: Parameter $value has undeclared type \int [PhanUndeclaredTypeParameter]
phpdoc_advanced_leading_backslash_keyword.php:48: Argument 1 ($value) is 'x' of type string but \Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt() takes int (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/phpdoc_advanced_leading_backslash_keyword.php:35 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]
phpdoc_advanced_leading_backslash_keyword.php:52: Argument 1 ($value) is 1 of type int (value: 1) but \Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt() takes \int (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/phpdoc_advanced_leading_backslash_keyword.php:28 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]
phpdoc_advanced_leading_backslash_keyword.php:55: Argument 1 ($value) is 'x' of type string but \Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt() takes \int (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/phpdoc_advanced_leading_backslash_keyword.php:28 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]
  • Recognition: spelling not resolved — reported on declaration line(s) 28
  • Enforcement: 2/2 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 52: Expected valid value to be accepted, got ["Argument 1 ($value) is 1 of type int (value: 1) but \\Conformance\\Tests\\PhpdocAdvancedLeadingBackslashKeyword\\takesBackslashInt() takes \\int (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/phpdoc_advanced_leading_backslash_keyword.php:28 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]"]
phpstan 2.2.15PHPStan - PHP Static Analysis Tool 2.2.15 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:28: Parameter $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt() has invalid type int. [reported-from-level=2]
phpdoc_advanced_leading_backslash_keyword.php:48: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt expects int, string given. [reported-from-level=5]
phpdoc_advanced_leading_backslash_keyword.php:52: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, int given. [reported-from-level=5]
phpdoc_advanced_leading_backslash_keyword.php:55: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, string given. [reported-from-level=5]
With strict-rules
phpdoc_advanced_leading_backslash_keyword.php:28: Parameter $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt() has invalid type int.
phpdoc_advanced_leading_backslash_keyword.php:48: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt expects int, string given.
phpdoc_advanced_leading_backslash_keyword.php:52: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, int given.
phpdoc_advanced_leading_backslash_keyword.php:55: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, string given.
  • Recognition: spelling not resolved — reported on declaration line(s) 28
  • Enforcement: 2/2 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 52: Expected valid value to be accepted, got ["Parameter #1 $value of function Conformance\\Tests\\PhpdocAdvancedLeadingBackslashKeyword\\takesBackslashInt expects int, int given. [reported-from-level=5]"]
psalm 6.18.0Psalm 6.18.0@536dd6236b39a5115385b0307b42d6d1ad431a02
next: 7.0.0-beta22
Enforced (pzoom≠)
phpdoc_advanced_leading_backslash_keyword.php:48: Argument 1 of Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt expects int, but 'x' provided [InvalidArgument]
phpdoc_advanced_leading_backslash_keyword.php:55: Argument 1 of Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, but 'x' provided [InvalidArgument]
pzoom (Psalm port)
phpdoc_advanced_leading_backslash_keyword.php:28: Docblock class int does not exist [UndefinedDocblockClass]
phpdoc_advanced_leading_backslash_keyword.php:48: Argument 1 of takesInt expects int, but 'x' provided [InvalidArgument]
phpdoc_advanced_leading_backslash_keyword.php:52: Argument 1 of takesBackslashInt expects int, but 1 provided [InvalidArgument]
phpdoc_advanced_leading_backslash_keyword.php:55: Argument 1 of takesBackslashInt expects int, but 'x' provided [InvalidArgument]
  • Recognition: spelling resolved
  • Enforcement: 2/2 of the expected violations reported
mago 1.50.0mago 1.50.0 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:26: Cannot find class, interface, enum, or type alias `int`. [non-existent-class-like]
phpdoc_advanced_leading_backslash_keyword.php:48: Invalid argument type for argument #1 of `Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt`: expected `int`, but found `string('x')`. [invalid-argument]
phpdoc_advanced_leading_backslash_keyword.php:52: Invalid argument type for argument #1 of `Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt`: expected `unknown-ref(int)`, but found `int(1)`. [invalid-argument]
phpdoc_advanced_leading_backslash_keyword.php:55: Invalid argument type for argument #1 of `Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt`: expected `unknown-ref(int)`, but found `string('x')`. [invalid-argument]
  • Recognition: spelling not resolved — reported on declaration line(s) 26
  • Enforcement: 2/2 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 52: Expected valid value to be accepted, got ["Invalid argument type for argument #1 of `Conformance\\Tests\\PhpdocAdvancedLeadingBackslashKeyword\\takesBackslashInt`: expected `unknown-ref(int)`, but found `int(1)`. [invalid-argument]"]
mir 0.78.0mir 0.78.0 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:26: InvalidDocblockType: Invalid docblock type: @param backslash-qualified non-class type '\int' is not a fully qualified name [MIR1107]
phpdoc_advanced_leading_backslash_keyword.php:48: InvalidArgument: Argument $value of takesInt() expects 'int', got '"x"' [MIR0201]
phpdoc_advanced_leading_backslash_keyword.php:55: InvalidArgument: Argument $value of takesBackslashInt() expects 'int', got '"x"' [MIR0201]
  • Recognition: spelling not resolved — reported on declaration line(s) 26
  • Enforcement: 2/2 of the expected violations reported — incidental, since the spelling was not resolved
phpantom 0.10.0phpantom_lsp 0.10.0 Enforced
phpdoc_advanced_leading_backslash_keyword.php:48: Argument 1 ($value) expects int, got 'x' [type_mismatch_argument]
phpdoc_advanced_leading_backslash_keyword.php:55: Argument 1 ($value) expects int, got 'x' [type_mismatch_argument]
  • Recognition: spelling resolved
  • Enforcement: 2/2 of the expected violations reported
intelephense 1.18.5intelephense 1.18.5 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:26: PHPDoc undefined type 'int'. [P1133]
  • Recognition: spelling not resolved — reported on declaration line(s) 26
  • Enforcement: 0/2 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 48: Expected 1 error(s)
Line 55: Expected 1 error(s)
phpactor 2026.06.23.0Phpactor 2026.06.23.0 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/2 of the expected violations reported
Expectation diff
Line 48: Expected 1 error(s)
Line 55: Expected 1 error(s)
phpy 1.0.19274phpy 1.0.19274 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:26: Name '{0}' can be simplified with '{1}'.
phpdoc_advanced_leading_backslash_keyword.php:48: Argument '1' passed to Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt() is expected to be of type int, string given
phpdoc_advanced_leading_backslash_keyword.php:55: Argument '1' passed to Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt() is expected to be of type int, string given
  • Recognition: spelling not resolved — reported on declaration line(s) 26
  • Enforcement: 2/2 of the expected violations reported — incidental, since the spelling was not resolved
qodana 262.9437.196Qodana 262.9437.196 Enforced
phpdoc_advanced_leading_backslash_keyword.php:48: Parameter ''x'' type is not compatible with declaration when using strict type matching [PhpParamsInspection]
phpdoc_advanced_leading_backslash_keyword.php:55: Parameter ''x'' type is not compatible with declaration when using strict type matching [PhpParamsInspection]
  • Recognition: spelling resolved
  • Enforcement: 2/2 of the expected violations reported
noverify 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 Not enforced ⚠ 1 false positive
phpdoc_advanced_leading_backslash_keyword.php:12: Class or interface named \int does not exist [undefinedClass]
  • Recognition: spelling resolved
  • Enforcement: 0/2 of the expected violations reported
  • False positives: line(s) 12
Expectation diff
Line 48: Expected 1 error(s)
Line 55: Expected 1 error(s)
Line 12: Unexpected errors ["Class or interface named \\int does not exist [undefinedClass]"]
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Enforced
phpdoc_advanced_leading_backslash_keyword.php:48: argument "x" to takesInt() violates declared @param int $value — declared contract violation [phpdoc.param-mismatch]
phpdoc_advanced_leading_backslash_keyword.php:55: argument "x" to takesBackslashInt() violates declared @param \int $value — declared contract violation [phpdoc.param-mismatch]
  • Recognition: spelling resolved
  • Enforcement: 2/2 of the expected violations reported
phpstan-strict 2.2.15PHPStan - PHP Static Analysis Tool 2.2.15 Unrecognized
phpdoc_advanced_leading_backslash_keyword.php:28: Parameter $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt() has invalid type int.
phpdoc_advanced_leading_backslash_keyword.php:48: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt expects int, string given.
phpdoc_advanced_leading_backslash_keyword.php:52: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, int given.
phpdoc_advanced_leading_backslash_keyword.php:55: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, string given.
  • Recognition: spelling not resolved — reported on declaration line(s) 28
  • Enforcement: 2/2 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 52: Expected valid value to be accepted, got ["Parameter #1 $value of function Conformance\\Tests\\PhpdocAdvancedLeadingBackslashKeyword\\takesBackslashInt expects int, int given."]
psalm-next 7.0.0-beta22Psalm 7.0.0-beta22@de27e5724ee5997a1e3baee4d394ca6f4e46eba0 Enforced
phpdoc_advanced_leading_backslash_keyword.php:48: Argument 1 of Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesInt expects int, but 'x' provided [InvalidArgument]
phpdoc_advanced_leading_backslash_keyword.php:55: Argument 1 of Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword\takesBackslashInt expects int, but 'x' provided [InvalidArgument]
  • Recognition: spelling resolved
  • Enforcement: 2/2 of the expected violations reported

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\PhpdocAdvancedLeadingBackslashKeyword;

/**
 * A leading backslash on a PHPDoc keyword is not a fully-qualified name.
 *
 * A slashed int keyword looks like a slashed DateTime, but int is a language
 * keyword, not a class in the root namespace. Native PHP rejects that form
 * on a parameter type at parse time. In a docblock the slash is spelling.
 * mir 0.73.0 reports InvalidDocblockType (MIR1107) at the token and still
 * type-checks the parameter as int. Other tools may strip the slash and
 * read int, or look up a class named int.
 *
 * A slashed DateTime is the control: a leading backslash on a real class is
 * a fully-qualified name and must stay valid. A tool that rejects every
 * backslash-prefixed type fails that control.
 *
 * References:
 * - mir 0.73.0 InvalidDocblockType / MIR1107 (int and non-empty-array cases)
 */

/**
 * @param \int $value
 */
function takesBackslashInt($value): void // T: \int
{
}

/**
 * @param int $value
 */
function takesInt($value): void
{
}

/**
 * @param \DateTime $value
 */
function takesBackslashDateTime($value): void // T: \DateTime
{
}

// Bare `int` still means int.
takesInt(1); // V
takesInt('x'); // E: string is not int

// A tool that reads `\int` as `int` admits this. A class-name fallback
// rejects it, which is over-rejection of a value the keyword admits.
takesBackslashInt(1); // V

// String is outside `int`, whether the slash was stripped or not.
takesBackslashInt('x'); // E: string is not int

// A leading backslash on a real class remains a fully-qualified name.
takesBackslashDateTime(new \DateTime()); // V