Skip to content

Commit 07dd3b4

Browse files
committed
Fix enclosing scopes when using references
1 parent f37388f commit 07dd3b4

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

ChangeLog.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ XP Compiler ChangeLog
33

44
## ?.?.? / ????-??-??
55

6+
* Fixed enclosing scopes when using references - @thekid
7+
68
## 9.3.0 / 2024-08-31
79

810
* Fixed checks for property hooks emulation with asymmetric visibility

src/main/php/lang/ast/emit/PHP.class.php

+8-8
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ protected function enclose($result, $node, $signature, $static, $emit) {
125125
$capture= [];
126126
foreach ($result->codegen->search($node, 'variable') as $var) {
127127
if (isset($result->locals[$var->pointer])) {
128-
$capture[$var->pointer]= true;
128+
$capture[$var->pointer]??= ($result->locals[$var->pointer] ? '&$' : '$').$var->pointer;
129129
}
130130
}
131131
unset($capture['this']);
@@ -143,9 +143,9 @@ protected function enclose($result, $node, $signature, $static, $emit) {
143143
}
144144

145145
if ($capture) {
146-
$result->out->write('use($'.implode(', $', array_keys($capture)).')');
147-
foreach ($capture as $name => $_) {
148-
$result->locals[$name]= true;
146+
$result->out->write('use('.implode(', ', $capture).')');
147+
foreach ($capture as $name => $variable) {
148+
$result->locals[$name]= '&' === $variable[0];
149149
}
150150
}
151151

@@ -298,7 +298,7 @@ protected function emitArray($result, $array) {
298298
}
299299

300300
protected function emitParameter($result, $parameter) {
301-
$result->locals[$parameter->name]= true;
301+
$result->locals[$parameter->name]= $parameter->reference;
302302
$parameter->annotations && $this->emitOne($result, $parameter->annotations);
303303

304304
// If we have a non-constant default and a type, emit a nullable type hint
@@ -340,7 +340,7 @@ protected function emitSignature($result, $signature, $use= null) {
340340
if ($use) {
341341
$result->out->write(' use('.implode(',', $use).') ');
342342
foreach ($use as $variable) {
343-
$result->locals[substr($variable, 1)]= true;
343+
$result->locals[ltrim($variable, '&$')]= '&' === $variable[0];
344344
}
345345
}
346346

@@ -675,7 +675,7 @@ protected function emitProperty($result, $property) {
675675

676676
protected function emitMethod($result, $method) {
677677
$locals= $result->locals;
678-
$result->locals= ['this' => true];
678+
$result->locals= ['this' => false];
679679
$meta= [
680680
DETAIL_RETURNS => $method->signature->returns ? $method->signature->returns->name() : 'var',
681681
DETAIL_ANNOTATIONS => $method->annotations,
@@ -798,7 +798,7 @@ protected function emitOffset($result, $offset) {
798798
protected function emitAssign($result, $target) {
799799
if ($target instanceof Variable && $target->const) {
800800
$result->out->write('$'.$target->pointer);
801-
$result->locals[$target->pointer]= true;
801+
$result->locals[$target->pointer]= false;
802802
} else if ($target instanceof ArrayLiteral) {
803803
$result->out->write('[');
804804
foreach ($target->values as $pair) {

src/test/php/lang/ast/unittest/emit/ControlStructuresTest.class.php

+20
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,24 @@ public function run() {
211211

212212
Assert::equals('one item', $r(1));
213213
}
214+
215+
#[Test]
216+
public function match_block_inside_function_using_ref() {
217+
$r= $this->run('class %T {
218+
public function run() {
219+
$test= "Original";
220+
(function() use(&$test) {
221+
match (true) {
222+
true => {
223+
$test= "Changed";
224+
return true;
225+
}
226+
};
227+
})();
228+
return $test;
229+
}
230+
}');
231+
232+
Assert::equals('Changed', $r);
233+
}
214234
}

0 commit comments

Comments
 (0)