kphp icon indicating copy to clipboard operation
kphp copied to clipboard

`match` expression

Open i582 opened this issue 3 years ago • 1 comments

RFC: https://wiki.php.net/rfc/match_expression_v2

The basis is the conversion to rvalue statements list with switch with strict comparisons. For op_switch added is_match flag.

In PHP, a regular switch uses non-strict comparison, which leads to type casts, but the match uses strict comparison, which is why we need a new is_match flag in the op_switch node.

If this flag is set, then strict comparison will be used when generating the code for the switch.

If we consider the transformation superficially, then the following will be:

For example:

$a = match($b) {
  10 => 1,
  20 => 2,
  default => 3,
}

Converts to something like this:

$a = ({
  switch ($b) {
     case 10: {
        $tmp = 1; 
        break;
     }
     case 20: {
        $tmp = 2; 
        break;
     }
     default: {
        $tmp = 3; 
        break;
     }
  };
  $tmp;
});

If there are several conditions, then the code is generated only once and all conditions fallthrough to this code:

For example:

$a = match($b) {
  10, 20 => 1,
  default => 3,
}

Converts to something like this:

$a = ({
  switch ($b) {
     case 10: {} // fallthrough
     case 20: {
        $tmp = 1; 
        break;
     }
     default: {
        $tmp = 3; 
        break;
     }
  };
  $tmp;
});

If there is no default branch, then the default version is generated. The default version always gives a warning about an unhandled value.

PHP throws an UnhandledMatchError exception if the value is not handled.

For example:

$a = match($b) {
  10 => 1,
}

Converts to something like this:

$a = ({
  switch ($b) {
     case 10: {
        $tmp = 1; 
        break;
     }
     default: {
        warning("Unhandled match value '$b'"); 
        break;
     }
  };
  $tmp;
});

Checks

  • Due to the fact that we convert to switch, we automatically get a check for a duplicate.
Repeated case [10] in switch/match
  • Also added a check for several default
Match expressions may only contain one default arm

i582 avatar Sep 06 '21 22:09 i582

Is it possible to add here some kind of annotation to force exhaustion check at compile time instead of runtime warning to cover #428?

vkaverin avatar Feb 14 '22 20:02 vkaverin