Mac OS X 10.11.6 / Crystal 0.19.2 and also master (0.19.2+48)
(NOT reproducible on playground by the way.)
Code:
def foo(&block)
a = yield || return nil
# .. some code ..
end
foo { nil } # error
## -> also
def bar
a = nil || return "?"
end
bar() # error
Produces:
can't execute `a = if __temp_77 = yield
__temp_77
else
return nil
end` at ~/git/crystal/bugs/src/nil_or_return.cr:2:3 (Exception)
[4367046482] *CallStack::unwind:Array(Pointer(Void)) +82
[4367046385] *CallStack#initialize:Array(Pointer(Void)) +17
[4367046344] *CallStack::new:CallStack +40
[4367026505] *raise<Exception>:NoReturn +25
[4367026465] *raise<String>:NoReturn +17
[4367025105] __crystal_main +945
[4367038280] main +40
Work Around:
def foo(&block)
(a = yield) || return nil
# .. some code ..
end
or just use if/unless
def foo(&block)
a = yield || return nil
# .. some code ..
end
is extracted as:
def foo(&block)
a = if __tmp = yield
__tmp
else
return nil
end
# .. some code ..
end
This breaks the flow, it returned from foo method but not assignment value to a.
And,
def foo(&block)
(a = yield) || return nil
# .. some code ..
end
extract as:
def foo(&block)
if a = yield
a
else
return nil
end
# .. some code ..
end
is fine, it doesn't break the code
Hmm.. Now I see it more clearly.
Thank you for the clarification. I'm very new to this language.
Additionally, it seems the compiler breaks only when the right-hand value of if-clause is nil.
(Same thing happens when I put a variable instead of yield, or nil value itself directly.)
def foo(&block)
a = if __tmp = yield
__tmp
else
return nil
end
# .. some code ..
end
foo { "bar" } # ok
foo { nil } # error
@chaniks Thank you for reporting this!
It's still a compiler bug and should be fixed. There's a similar issue, #821, which in the comments have more or less this code, but now I know a way to fix this, I think.
@asterite Oh my God.. This fast? I couldn't even finish my reply.
The issue explained me everything. Now it's _crystal clear_. 馃憤
Most helpful comment
@chaniks Thank you for reporting this!
It's still a compiler bug and should be fixed. There's a similar issue, #821, which in the comments have more or less this code, but now I know a way to fix this, I think.