← All results

Method declared on only one union member

Group: Union types · Category: language · File: unions_partial_member_method_call.php

Calling a method that only one member of a union declares. On User|Guest, name() exists only on User, so the call fails at runtime whenever a Guest arrives. PHPStan gates this behind level 7 (checkUnionTypes); a lenient tool resolves the call against whichever member has it. References: - PHPStan checkUnionTypes (level 7) - unions_object_member_rejection (union argument acceptance)

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.11Phan 6.0.11 php-ast version 1.1.3 PHP version used to run Phan: 8.5.11 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
phpstan 2.3.5PHPStan - PHP Static Analysis Tool 2.3.5 Pass reported Lv.7+
unions_partial_member_method_call.php:48: Call to an undefined method Conformance\Tests\UnionsPartialMemberMethodCall\Guest|Conformance\Tests\UnionsPartialMemberMethodCall\User::name(). [reported-from-level=7]
With strict-rules
unions_partial_member_method_call.php:48: Call to an undefined method Conformance\Tests\UnionsPartialMemberMethodCall\Guest|Conformance\Tests\UnionsPartialMemberMethodCall\User::name().
psalm 6.20.9Psalm 6.20.9@f67170ac3c3b931f5088681e21d6c8babc601c08
next: 7.0.4
Pass
unions_partial_member_method_call.php:48: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
unions_partial_member_method_call.php:48: Method Conformance\Tests\UnionsPartialMemberMethodCall\Guest::name does not exist [PossiblyUndefinedMethod]
mago 1.59.0mago 1.59.0 Pass
unions_partial_member_method_call.php:48: Method `name` does not exist on type `Conformance\Tests\UnionsPartialMemberMethodCall\Guest`. [non-existent-method]
mir 0.91.0mir 0.91.0 Pass
unions_partial_member_method_call.php:48: PossiblyUndefinedMethod: Method Conformance\Tests\UnionsPartialMemberMethodCall\Guest::name() might not exist [MIR0015]
phpantom 0.11.1phpantom_lsp 0.11.1 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
intelephense 1.18.5intelephense 1.18.5 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
phpactor 2026.10.07.0Phpactor 2026.10.07.0 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
phpy 1.0.19490phpy 1.0.19490 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
qodana 262.11879.104PhpStorm 262.11879.104 Fail

No diagnostics reported.

Expectation diff
Line 48: 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 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
phpstan-strict 2.3.5PHPStan - PHP Static Analysis Tool 2.3.5 Pass
unions_partial_member_method_call.php:48: Call to an undefined method Conformance\Tests\UnionsPartialMemberMethodCall\Guest|Conformance\Tests\UnionsPartialMemberMethodCall\User::name().
psalm-next 7.0.4Psalm 7.0.4@fa5b1f6e665cb743838ffd865b8fc96207f9409f Pass
unions_partial_member_method_call.php:48: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
unions_partial_member_method_call.php:48: Method Conformance\Tests\UnionsPartialMemberMethodCall\Guest::name does not exist [PossiblyUndefinedMethod]

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\UnionsPartialMemberMethodCall;

/**
 * Method declared on only one union member.
 *
 * Calling a method that only one member of a union declares. On `User|Guest`,
 * `name()` exists only on User, so the call fails at runtime whenever a Guest
 * arrives. PHPStan gates this behind level 7 (`checkUnionTypes`); a lenient
 * tool resolves the call against whichever member has it.
 *
 * References:
 * - PHPStan `checkUnionTypes` (level 7)
 * - unions_object_member_rejection (union argument acceptance)
 */

final class User
{
    public function name(): string
    {
        return 'user';
    }

    public function id(): int
    {
        return 1;
    }
}

final class Guest
{
    public function id(): int
    {
        return 0;
    }
}

function common(User|Guest $visitor): void
{
    echo $visitor->id(); // V: both members declare id()
}

function partial(User|Guest $visitor): void
{
    echo $visitor->name(); // E: Guest has no name()
}