kphp icon indicating copy to clipboard operation
kphp copied to clipboard

Smart cast fails in AND-chain

Open vkaverin opened this issue 5 years ago • 3 comments

Consider following example:

<?php
main();

function main() {
  $x = null;
  if (true) {
    $x = 1;
  }

  $y = $x && foo($x);
}

function foo(int $x): bool {
  return $x > 0;
}

Code translation fails with the following:

+----------------------+
| TYPE INFERENCE ERROR |
+----------------------+
Incorrect type of the arg #0 ($x) at function: foo
Expected type:	int
Actual type:	int|null
+-------------+
| STACKTRACE: |
+-------------+
arg #0 ($x) : int|null   at function: foo
$x : int|null            at function: foo
arg #0 ($x) : int|null   at function: foo
$x : int|null            at test.php: main:10
null                     at test.php: main:5

while this snippet works just fine:

<?php

main();

function main() {
  $x = null;
  if (true) {
    $x = 1;
  }

  $y = false;
  if ($x) {
    $y = foo($x);
  }
}

function foo(int $x): bool {
  return $x > 0;
}

vkaverin avatar Dec 18 '20 15:12 vkaverin

Since && always returns boolean result, these lines are not always identical:

$y = $x && foo($x);

if ($x) { $y = foo($x); }

Unless foo() returns bool type, that is.

In your particular example, foo() returns int. The first snippet will have $y=true and the second snippet will have $y=1.

quasilyte avatar Jan 28 '21 19:01 quasilyte

Return type of the function is not the point of the issue, the point is smart cast only. But I've fixed the example to have correct types, thanks.

vkaverin avatar Jan 28 '21 19:01 vkaverin

Basically the same as #711.

vkaverin avatar Mar 09 '23 15:03 vkaverin