Skip to content

Commit

Permalink
Merge pull request #4602 from arichard4/ref_type
Browse files Browse the repository at this point in the history
Pass-by-ref vars don't account for early-outing; should merge types instead of overwriting
  • Loading branch information
TysonAndre committed Nov 2, 2021
2 parents 7620cf4 + 77e4430 commit 1f5ab9a
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/Phan/Language/Element/PassByReferenceVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ public function setUnionType(UnionType $type): void
);
return;
}
$this->element->setUnionType($type->eraseRealTypeSetRecursively());
$new_element_type = UnionType::merge([
$type->eraseRealTypeSetRecursively(),
$this->element->getUnionType()
]);
$this->element->setUnionType($new_element_type);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/files/expected/0383_output_reference.php.expected
Original file line number Diff line number Diff line change
@@ -1 +1 @@
%s:17 PhanTypeMismatchArgumentInternal Argument 1 ($num1) is $x of type 'value' but \intdiv() takes int
%s:17 PhanTypeMismatchArgumentInternal Argument 1 ($num1) is $x of type 'value'|string but \intdiv() takes int
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
%s:30 PhanDebugAnnotation @phan-debug-var requested for variable $x - it has union type 42|array{}|true
%s:36 PhanDebugAnnotation @phan-debug-var requested for variable $x - it has union type array{}|true
%s:36 PhanDebugAnnotation @phan-debug-var requested for variable $x - it has union type 42|array{}|true
%s:42 PhanDebugAnnotation @phan-debug-var requested for variable $x - it has union type 42
6 changes: 6 additions & 0 deletions tests/files/expected/0970_ref_param_types.php.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
%s:13 PhanDebugAnnotation @phan-debug-var requested for variable $var - it has union type 1|2|3
%s:29 PhanDebugAnnotation @phan-debug-var requested for variable $var2 - it has union type 4|5|6
%s:44 PhanDebugAnnotation @phan-debug-var requested for variable $var3 - it has union type 7|8|9
%s:60 PhanDebugAnnotation @phan-debug-var requested for variable $var4 - it has union type 10|11|12
%s:71 PhanDebugAnnotation @phan-debug-var requested for variable $var5 - it has union type 13|14
%s:95 PhanDebugAnnotation @phan-debug-var requested for variable $var6 - it has union type 15|16
96 changes: 96 additions & 0 deletions tests/files/src/0970_ref_param_types.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

function try_ref(&$var) {
try {
$var = 1;
} catch (PDOException $_) {
$var = 2;
} catch (Exception $_) {
$var = 3;
}
}

try_ref($var);
'@phan-debug-var $var';

function try_ref_ret(&$var) {
try {
$var = 4;
return;
} catch (PDOException $_) {
$var = 5;
return;
} catch (Exception $_) {
$var = 6;
return;
}
}

try_ref_ret($var2);
'@phan-debug-var $var2';

function try_ref_mixed(&$var) {
try {
$var = 7;
} catch (PDOException $_) {
$var = 8;
return;
} catch (Exception $_) {
$var = 9;
return;
}
}

try_ref_mixed($var3);
'@phan-debug-var $var3';

function if_ref(&$var) {
if (rand(0,1)) {
$var = 10;
return;
} elseif (rand(0,2)) {
$var = 11;
return;
} else {
$var = 12;
return;
}
}

if_ref($var4);
'@phan-debug-var $var4';

function early_ret(&$var) {
if (rand(0,1)) {
return;
}
$var = 14;
}

$var5 = 13;
early_ret($var5);
'@phan-debug-var $var5';

function inner() {
if (rand(0,1)) {
throw new Exception();
}
}

function middle(&$var) {
inner();
$var = 16;
}

function outer() {
$var = 15;
try {
middle($var);
return $var;
} catch (Exception $_) {
return $var;
}
}

$var6 = outer();
'@phan-debug-var $var6';
2 changes: 1 addition & 1 deletion tests/rasmus_files/expected/0022_ref_params.php.expected
Original file line number Diff line number Diff line change
@@ -1 +1 @@
%s:15 PhanTypeMismatchArgument Argument 1 ($farg2) is $arg1 of type 1.5 but \B::test2() takes int defined at %s:8
%s:15 PhanTypeMismatchArgument Argument 1 ($farg2) is $arg1 of type 1.5|array{0:1,1:2,2:3} but \B::test2() takes int defined at %s:8

0 comments on commit 1f5ab9a

Please sign in to comment.