crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.36k stars 1.62k forks source link

Bug when assigning variable inside block in while #15011

Open beta-ziliani opened 2 weeks ago

beta-ziliani commented 2 weeks ago

Bug Report

The following code:

def synchronize(&block)
  yield
end

while false
 begin
    synchronize { i = 1 }
  rescue
    break
  end
end

Fails with:

Missing hash key: "i" (KeyError)  
  from /Users/beta/projects/crystal/crystal/src/array.cr:1315:17 in 'visit'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/semantic/main_visitor.cr:688:11 in 'visit'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/semantic/main_visitor.cr:6:7 in 'semantic:cleanup'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/compiler.cr:210:14 in 'compile'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/command/eval.cr:30:5 in 'eval'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal/command.cr:101:7 in 'run'
  from /Users/beta/projects/crystal/crystal/src/compiler/crystal.cr:11:1 in '__crystal_main'
  from /Users/beta/projects/crystal/crystal/src/crystal/main.cr:118:5 in 'main'

Adding i = 0 at the beginning, or commenting out the rescue and/or the break makes it work.

Observed by @spuun

HertzDevil commented 1 week ago

Longer trace with a local compiler:

Missing hash key: "i" (KeyError)
  from src/hash.cr:1193:11 in '[]'
  from src/compiler/crystal/semantic/main_visitor.cr:2186:13 in 'merge_while_vars'
  from src/compiler/crystal/semantic/main_visitor.cr:2061:7 in 'visit'
  from src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from src/compiler/crystal/semantic/main_visitor.cr:688:11 in 'visit'
  from src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from src/compiler/crystal/semantic/main_visitor.cr:6:7 in 'visit_main:process_finished_hooks:cleanup:visitor'
  from src/compiler/crystal/progress_tracker.cr:22:7 in 'semantic:cleanup'
  from src/compiler/crystal/compiler.cr:210:14 in 'compile'
  from src/compiler/crystal/command.cr:362:3 in 'compile'
  from src/compiler/crystal/command.cr:242:5 in 'run_command'
  from src/compiler/crystal/command.cr:129:7 in 'run'
  from src/compiler/crystal/command.cr:55:5 in 'run'
  from src/compiler/crystal/command.cr:54:3 in 'run'
  from src/compiler/crystal.cr:11:1 in '__crystal_main'
  from src/crystal/main.cr:118:5 in 'main_user_code'
  from src/crystal/main.cr:104:7 in 'main'
  from src/crystal/main.cr:130:3 in 'main'
  from /lib/x86_64-linux-gnu/libc.so.6 in '??'
  from /lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'
  from /home/quinton/.cache/crystal/crystal-run-crystal.tmp in '_start'
  from ???