Skip to content

Commit

Permalink
Showing 3 changed files with 18 additions and 7 deletions.
2 changes: 1 addition & 1 deletion spec/compiler/type_inference/block_spec.cr
Original file line number Diff line number Diff line change
@@ -940,7 +940,7 @@ describe "Block inference" do
assert_error %(
yield
),
"can't yield outside a method"
"can't use `yield` outside a method"
end

it "rebinds yield -> block arguments" do
6 changes: 5 additions & 1 deletion spec/compiler/type_inference/closure_spec.cr
Original file line number Diff line number Diff line change
@@ -2,7 +2,11 @@ require "../../spec_helper"

describe "Type inference: closure" do
it "gives error when doing yield inside fun literal" do
assert_error "-> { yield }", "can't yield from function literal"
assert_error "-> { yield }", "can't use `yield` outside a method"
end

it "gives error when doing yield inside fun literal" do
assert_error "def foo; -> { yield }; end; foo {}", "can't use `yield` inside a proc literal or captured block"
end

it "marks variable as closured in program" do
17 changes: 12 additions & 5 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -650,13 +650,20 @@ module Crystal
end

def visit(node : Yield)
if @fun_literal_context
node.raise "can't yield from function literal"
end

call = @call
unless call
node.raise "can't yield outside a method"
node.raise "can't use `yield` outside a method"
end

if ctx = @fun_literal_context
node.raise <<-MSG
can't use `yield` inside a proc literal or captured block
Make sure to read the whole docs section about blocks and procs,
including "Capturing blocks" and "Block forwarding":
http://crystal-lang.org/docs/syntax_and_semantics/blocks_and_procs.html
MSG
end

block = call.block || node.raise("no block given")

0 comments on commit a229d0b

Please sign in to comment.