← All results

Result type of the pipe operator

Group: Callables · Category: language · File: callables_pipe_operator_result.php

PHP 8.5's pipe operator $value |> $callable evaluates to the callable's return value, not to the callable. With a first-class callable on the right the result is the function's return type. References: - https://wiki.php.net/rfc/pipe-operator-v3

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
callables_pipe_operator_result.php:40: Call to undeclared method \Conformance\Tests\CallablesPipeOperatorResult\Slug::missing [PhanUndeclaredMethod]
phpstan 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Pass reported Lv.2+
callables_pipe_operator_result.php:40: Call to an undefined method Conformance\Tests\CallablesPipeOperatorResult\Slug::missing(). [reported-from-level=2]
callables_pipe_operator_result.php:40: Parameter #1 (mixed) of echo cannot be converted to string. [reported-from-level=10]
With strict-rules
callables_pipe_operator_result.php:40: Call to an undefined method Conformance\Tests\CallablesPipeOperatorResult\Slug::missing().
callables_pipe_operator_result.php:40: Parameter #1 (mixed) of echo cannot be converted to string.
psalm 6.20.0Psalm 6.20.0@804f03c0c183d149fcd4b8c7c0c9b3fbf836d34c
next: 7.0.0-rc2
Fail
callables_pipe_operator_result.php:37: Unable to determine the type that $slug is being assigned to [MixedAssignment]
callables_pipe_operator_result.php:38: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
callables_pipe_operator_result.php:38: Cannot determine the type of $slug when calling method value [MixedMethodCall]
callables_pipe_operator_result.php:39: Unable to determine the type that $piped is being assigned to [MixedAssignment]
callables_pipe_operator_result.php:40: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
callables_pipe_operator_result.php:40: Cannot determine the type of $piped when calling method missing [MixedMethodCall]
callables_pipe_operator_result.php:45: Unable to determine the type that $length is being assigned to [MixedAssignment]
callables_pipe_operator_result.php:46: Left operand cannot be mixed [MixedOperand]
callables_pipe_operator_result.php:46: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
Expectation diff
Line 38: Expected valid value to be accepted, got ["Argument 1 of echo cannot be mixed, expecting string [MixedArgument]","Cannot determine the type of $slug when calling method value [MixedMethodCall]"]
Line 46: Expected valid value to be accepted, got ["Left operand cannot be mixed [MixedOperand]","Argument 1 of echo cannot be mixed, expecting string [MixedArgument]"]
Line 37: Unexpected errors ["Unable to determine the type that $slug is being assigned to [MixedAssignment]"]
Line 39: Unexpected errors ["Unable to determine the type that $piped is being assigned to [MixedAssignment]"]
Line 45: Unexpected errors ["Unable to determine the type that $length is being assigned to [MixedAssignment]"]
mago 1.57.0mago 1.57.0 Pass
callables_pipe_operator_result.php:40: Method `missing` does not exist on type `Conformance\Tests\CallablesPipeOperatorResult\Slug`. [non-existent-method]
callables_pipe_operator_result.php:40: The first value for `echo` is too general. [mixed-argument]
mir 0.87.0mir 0.87.0 Fail
callables_pipe_operator_result.php:38: UndefinedMethod: Method Closure::value() does not exist [MIR0004]
callables_pipe_operator_result.php:40: UndefinedMethod: Method Closure::missing() does not exist [MIR0004]
callables_pipe_operator_result.php:46: InvalidOperand: Operator '+' not supported between 'Closure(string): int<0, max>' and '1' [MIR0208]
Expectation diff
Line 38: Expected valid value to be accepted, got ["UndefinedMethod: Method Closure::value() does not exist [MIR0004]"]
Line 46: Expected valid value to be accepted, got ["InvalidOperand: Operator '+' not supported between 'Closure(string): int<0, max>' and '1' [MIR0208]"]
phpantom 0.11.1phpantom_lsp 0.11.1 Pass
callables_pipe_operator_result.php:40: Method 'missing' not found on class 'Conformance\Tests\CallablesPipeOperatorResult\Slug' [unknown_member]
intelephense 1.18.5intelephense 1.18.5 Pass
callables_pipe_operator_result.php:40: Expected type 'string|Stringable|null'. Found 'mixed'. [P1006]
callables_pipe_operator_result.php:40: Undefined method 'missing'. [P1013]
phpactor 2026.10.07.0Phpactor 2026.10.07.0 Pass
callables_pipe_operator_result.php:40: Method "missing" does not exist on class "Conformance\Tests\CallablesPipeOperatorResult\Slug" [missing_member]
phpy 1.0.19409phpy 1.0.19409 Pass
callables_pipe_operator_result.php:40: Call to unknown method: Conformance\Tests\CallablesPipeOperatorResult\Slug::missing()
qodana 262.10968.76PhpStorm 262.10968.76 Fail

No diagnostics reported.

Expectation diff
Line 40: 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 40: Expected 1 error(s)
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Fail

No diagnostics reported.

Expectation diff
Line 40: Expected 1 error(s)
phpstan-strict 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Pass
callables_pipe_operator_result.php:40: Call to an undefined method Conformance\Tests\CallablesPipeOperatorResult\Slug::missing().
callables_pipe_operator_result.php:40: Parameter #1 (mixed) of echo cannot be converted to string.
psalm-next 7.0.0-rc2Psalm 7.0.0-rc2@20339e3fe5b8d03bcd8061030eb2a83ad50e5783 Fail
callables_pipe_operator_result.php:37: Unable to determine the type that $slug is being assigned to [MixedAssignment]
callables_pipe_operator_result.php:38: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
callables_pipe_operator_result.php:38: Cannot determine the type of $slug when calling method value [MixedMethodCall]
callables_pipe_operator_result.php:39: Unable to determine the type that $piped is being assigned to [MixedAssignment]
callables_pipe_operator_result.php:40: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
callables_pipe_operator_result.php:40: Cannot determine the type of $piped when calling method missing [MixedMethodCall]
callables_pipe_operator_result.php:45: Unable to determine the type that $length is being assigned to [MixedAssignment]
callables_pipe_operator_result.php:46: Left operand cannot be mixed [MixedOperand]
callables_pipe_operator_result.php:46: Argument 1 of echo cannot be mixed, expecting string [MixedArgument]
Expectation diff
Line 38: Expected valid value to be accepted, got ["Argument 1 of echo cannot be mixed, expecting string [MixedArgument]","Cannot determine the type of $slug when calling method value [MixedMethodCall]"]
Line 46: Expected valid value to be accepted, got ["Left operand cannot be mixed [MixedOperand]","Argument 1 of echo cannot be mixed, expecting string [MixedArgument]"]
Line 37: Unexpected errors ["Unable to determine the type that $slug is being assigned to [MixedAssignment]"]
Line 39: Unexpected errors ["Unable to determine the type that $piped is being assigned to [MixedAssignment]"]
Line 45: Unexpected errors ["Unable to determine the type that $length is being assigned to [MixedAssignment]"]

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\CallablesPipeOperatorResult;

/**
 * Result type of the pipe operator.
 *
 * PHP 8.5's pipe operator `$value |> $callable` evaluates to the callable's
 * return value, not to the callable. With a first-class callable on the right
 * the result is the function's return type.
 *
 * References:
 * - https://wiki.php.net/rfc/pipe-operator-v3
 */

final class Slug
{
    public function __construct(private string $text)
    {
    }

    public function value(): string
    {
        return $this->text;
    }
}

function slugify(string $text): Slug
{
    return new Slug($text);
}

function pipes(): void
{
    $slug = 'Hello World' |> slugify(...);
    echo $slug->value(); // V: the pipe yields a Slug
    $piped = 'Hello World' |> slugify(...);
    echo $piped->missing(); // E: Slug has no missing()
}

function pipesThroughArrow(): void
{
    $length = 'Hello' |> (fn (string $text): int => strlen($text));
    echo $length + 1; // V: the pipe yields an int
}