← 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.10Phan 6.0.10 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.1PHPStan - PHP Static Analysis Tool 2.3.1 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.0Psalm 6.20.0@804f03c0c183d149fcd4b8c7c0c9b3fbf836d34c
next: 7.0.0-rc2
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.57.0mago 1.57.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.87.0mir 0.87.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.19409phpy 1.0.19409 Fail

No diagnostics reported.

Expectation diff
Line 48: Expected 1 error(s)
qodana 262.10968.76PhpStorm 262.10968.76 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.1PHPStan - PHP Static Analysis Tool 2.3.1 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.0-rc2Psalm 7.0.0-rc2@20339e3fe5b8d03bcd8061030eb2a83ad50e5783 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()
}