crystal icon indicating copy to clipboard operation
crystal copied to clipboard

[ICE] `x : Int32` inside block

Open z64 opened this issue 4 years ago • 8 comments

class Error < Exception
end

def yields
  yield
end

def foo
  yields do
    rescue : Error
  end
end

foo

Crashes with:

Crystal::ASTNode#dependencies cannot be nil (NilAssertionError)
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from __crystal_main
  from main
  from __libc_start_main
  from _start
  from ???
Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues

Examples that silence the error:

  1. Bind the exception to a variable
def foo
  yields do
  rescue ex : Error
  end
end
  1. Add a return expression
def foo
  yields do
    return "ok"
    rescue : Error
  end
end

Similar issue: https://github.com/crystal-lang/crystal/issues/8669

Crystal 0.34.0 (2020-04-07)

LLVM: 9.0.1
Default target: x86_64-pc-linux-gnu

z64 avatar Apr 18 '20 19:04 z64

Shouldn't that fail with syntax error?

Sija avatar Apr 19 '20 13:04 Sija

Why?

asterite avatar Apr 19 '20 13:04 asterite

I've thought that we have only rescue notations as follows:

  • rescue ex
  • rescue ex : ExceptionClass, or
  • rescue ExceptionClass (note lack of :)

Crystal reference shows only these 3 as well.

Sija avatar Apr 19 '20 13:04 Sija

Oh, you are right

asterite avatar Apr 19 '20 14:04 asterite

Oh, it parses well because rescue : Error is just declaring a variable named rescue with type Error.

Reduced:

foo do
  x : Int32
end

@z64 please write rescue Error and it will work.

Small bug, not worth spending time fixing this right now.

asterite avatar Apr 19 '20 14:04 asterite

Just a note: rescue : Error isn't parsed as rescue because one can do:

class Foo
  property rescue : Exception? = nil
end

Foo.rescue
Foo.rescue = nil
# etc.

asterite avatar Apr 19 '20 14:04 asterite

Yeah I meant to bind rescue ex : Error haha. I just ran into this because I typo'd while prototyping, and saw my terminal that runs specs when my files change suddenly get a very long output!

Thanks for clarifying the rest though :smile_cat:

z64 avatar Apr 19 '20 14:04 z64

Oh, it parses well because rescue : Error is just declaring a variable named rescue with type Error.

Reduced:

foo do
  x : Int32
end

@z64 please write rescue Error and it will work.

Small bug, not worth spending time fixing this right now.

def foo(&)
  yield
end

foo do
  x : Int32
end

I consider this issue is worth to be fixed, see my another avram example.

https://forum.crystal-lang.org/t/a-really-not-useful-backtrace-when-write-wrong-macro-code/4816

i never use rescue here, instead just some typo or misusage.

for my example, it should be add name : String, but i write name : String instead.

the backtrace really not help for this error, user (like me) probably following the habit from ActiveRecord migration, so, this error maybe happen frequently, this strange output really frustrated the user.

zw963 avatar Aug 09 '22 08:08 zw963