Skip to content

Commit e7890e3

Browse files
committed
Increase precedence of pipe operator.
1 parent ceb4589 commit e7890e3

File tree

5 files changed

+20
-36
lines changed

5 files changed

+20
-36
lines changed

Zend/tests/pipe_operator/precedence_addition.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function _test1(int $a): int {
99

1010
$bad_func = null;
1111

12+
// This should add 5+2 first, then pipe that to _test1.
1213
$res1 = 5 + 2 |> '_test1';
1314

1415
var_dump($res1);
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
--TEST--
2-
Pipe binds lower than coalesce
2+
Pipe binds higher than coalesce
33
--FILE--
44
<?php
55

6-
function _test1(int $a): int {
7-
return $a * 2;
6+
function get_username(int $a): string {
7+
return (string)$a;
88
}
99

10-
$bad_func = null;
10+
$user = 5
11+
|> get_username(...)
12+
?? 'default';
1113

12-
$res1 = 5 |> $bad_func ?? '_test1';
13-
14-
var_dump($res1);
14+
var_dump($user);
1515
?>
1616
--EXPECT--
17-
int(10)
17+
string(1) "5"

Zend/tests/pipe_operator/precedence_comparison.phpt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,10 @@ function _test1(int $a): int {
77
return $a * 2;
88
}
99

10-
$res1 = (5 |> _test1(...)) == 10 ;
10+
// The pipe should run before the comparison.
11+
$res1 = 5 |> _test1(...) == 10 ;
1112
var_dump($res1);
1213

13-
// This will error without the parens,
14-
// as it will try to compare a closure to an int first.
15-
try {
16-
$res1 = 5 |> _test1(...) == 10 ;
17-
}
18-
catch (Throwable $e) {
19-
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
20-
}
21-
2214
?>
2315
--EXPECTF--
2416
bool(true)
25-
26-
Notice: Object of class Closure could not be converted to int in %s line %d
27-
Error: Value of type bool is not callable
Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Pipe binds lower than ternary
2+
Pipe binds higher than ternary
33
--FILE--
44
<?php
55

@@ -15,19 +15,14 @@ function _test3(int $a): int {
1515
return $a * 100;
1616
}
1717

18-
// $config is null, so the second function gets used.
19-
$config = null;
20-
$res1 = 5 |> $config ? _test1(...) : _test2(...);
21-
var_dump($res1);
18+
function is_odd(int $a): bool {
19+
return (bool)($a % 2);
20+
}
2221

23-
// $config is truthy, so the ternary binds first
24-
// and evaluates to the first function.
25-
$config = _test3(...);
26-
$res2 = 5 |> $config ? _test1(...) : _test2(...);
27-
var_dump($res2);
22+
$res1 = 5 |> is_odd(...) ? 'odd' : 'even';
23+
var_dump($res1);
2824

29-
// Binding the ternary first doesn't make logical sense,
30-
// so the pipe runs first in this case.
25+
// The pipe binds first, resulting in bool ? int : string, which is well-understood.
3126
$x = true;
3227
$y = 'beep';
3328
$z = 'default';
@@ -37,6 +32,5 @@ var_dump($ret3);
3732

3833
?>
3934
--EXPECT--
40-
int(10)
41-
int(6)
35+
string(3) "odd"
4236
int(4)

Zend/zend_language_parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
6262
%precedence T_DOUBLE_ARROW
6363
%precedence T_YIELD_FROM
6464
%precedence '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL T_COALESCE_EQUAL
65-
%left T_PIPE
6665
%left '?' ':'
6766
%right T_COALESCE
6867
%left T_BOOLEAN_OR
@@ -72,6 +71,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
7271
%left T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
7372
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP
7473
%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
74+
%left T_PIPE
7575
%left '.'
7676
%left T_SL T_SR
7777
%left '+' '-'

0 commit comments

Comments
 (0)