Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix scoping bugs with s.m. for and given.
"try { say $_ } for ..." and "try { say $_ } given ..." did not move
the blocks into the thunk generated for for/given, so we looked up the
wrong $_.
  • Loading branch information
jnthn committed Apr 28, 2015
1 parent 0ffe68f commit c5d7aa0
Showing 1 changed file with 22 additions and 15 deletions.
37 changes: 22 additions & 15 deletions src/Perl6/Actions.nqp
Expand Up @@ -826,13 +826,13 @@ Compilation unit '$file' contained the following violations:
if ~$ml<sym> eq 'given' {
$past := QAST::Op.new(
:op('call'),
block_closure(make_topic_block_ref($/, $past)),
block_closure(make_topic_block_ref($/, $past, migrate_stmt_id => $*STATEMENT_ID)),
$cond
);
}
elsif ~$ml<sym> eq 'for' {
unless $past.ann('past_block') {
$past := make_topic_block_ref($/, $past);
$past := make_topic_block_ref($/, $past, migrate_stmt_id => $*STATEMENT_ID);
}
$past := QAST::Op.new(
:op<callmethod>, :name<for>, :node($/),
Expand Down Expand Up @@ -5021,21 +5021,26 @@ Compilation unit '$file' contained the following violations:

# Some constructs are parsed and compiled with blocks inside of them, but
# then the outer block goes away (for example, when a {...} becomes a
# hash). This is used to move blocks out of the discarded inner one to
# the outer one, so they're correctly lexically scoped.
sub migrate_blocks($from, $to) {
# hash). Others get thunked and so need to have certain blocks in an
# expression moved into the thunk. This performs the migration. Takes an
# optional predicate to decide whether to move a block.
sub migrate_blocks($from, $to, $predicate?) {
my @decls := @($from[0]);
my int $n := nqp::elems(@decls);
my int $i := 0;
while $i < $n {
if nqp::istype(@decls[$i], QAST::Block) {
$to[0].push(@decls[$i]);
@decls[$i] := QAST::Op.new( :op('null') );
if !$predicate || $predicate(@decls[$i]) {
$to[0].push(@decls[$i]);
@decls[$i] := QAST::Op.new( :op('null') );
}
}
elsif (nqp::istype(@decls[$i], QAST::Stmt) || nqp::istype(@decls[$i], QAST::Stmts)) &&
nqp::istype(@decls[$i][0], QAST::Block) {
$to[0].push(@decls[$i][0]);
@decls[$i][0] := QAST::Op.new( :op('null') );
if !$predicate || $predicate(@decls[$i]) {
$to[0].push(@decls[$i][0]);
@decls[$i][0] := QAST::Op.new( :op('null') );
}
}
$i++;
}
Expand Down Expand Up @@ -6895,12 +6900,14 @@ Compilation unit '$file' contained the following violations:
$block);
}

sub make_topic_block_ref($/, $past, :$copy) {
my $block := QAST::Block.new(
QAST::Stmts.new(
QAST::Var.new( :name('$_'), :scope('lexical'), :decl('var') )
),
$past);
sub make_topic_block_ref($/, $past, :$copy, :$migrate_stmt_id) {
my $block := $*W.push_lexpad($/);
$block[0].push(QAST::Var.new( :name('$_'), :scope('lexical'), :decl('var') ));
$block.push($past);
$*W.pop_lexpad();
if nqp::defined($migrate_stmt_id) {
migrate_blocks($*W.cur_lexpad(), $block, -> $b { $b.ann('statement_id') == $migrate_stmt_id });
}
($*W.cur_lexpad())[0].push($block);
my $param := hash( :variable_name('$_'), :nominal_type($*W.find_symbol(['Mu'])));
if $copy {
Expand Down

0 comments on commit c5d7aa0

Please sign in to comment.