Skip to content

Commit

Permalink
Fix recursive block expansion check for non ProcNotation restriction (#…
Browse files Browse the repository at this point in the history
…6932)

Fixed #6896

Temporary variable name `block_arg_type` is conflicted with the same
name variable declared above. It is the reason of this bug, so the
temporary variable is renamed.
  • Loading branch information
makenowjust authored and ysbaddaden committed Oct 12, 2018
1 parent 7639f20 commit 24f32b8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
30 changes: 30 additions & 0 deletions spec/compiler/semantic/block_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,36 @@ describe "Block inference" do
"recursive block expansion"
end

it "errors on recursive yield with non ProcNotation restriction (#6896)" do
assert_error %(
def foo(&block : -> Int32)
yield
foo do
1
end
end
foo { 1 }
),
"recursive block expansion"
end

it "errors on recursive yield with ProcNotation restriction" do
assert_error %(
def foo(&block : -> Int32)
yield
foo do
1
end
end
foo { 1 }
),
"recursive block expansion"
end

it "binds to proc, not only to its body (#1796)" do
assert_type(%(
def yielder(&block : Int32 -> U) forall U
Expand Down
10 changes: 5 additions & 5 deletions src/compiler/crystal/semantic/call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -752,16 +752,16 @@ class Crystal::Call
elsif block_arg_restriction
# Otherwise, the block spec could be something like &block : Foo, and that
# is valid too only if Foo is an alias/typedef that referes to a FunctionType
block_arg_type = lookup_node_type(match.context, block_arg_restriction).remove_typedef
unless block_arg_type.is_a?(ProcInstanceType)
block_arg_restriction.raise "expected block type to be a function type, not #{block_arg_type}"
block_arg_restriction_type = lookup_node_type(match.context, block_arg_restriction).remove_typedef
unless block_arg_restriction_type.is_a?(ProcInstanceType)
block_arg_restriction.raise "expected block type to be a function type, not #{block_arg_restriction_type}"
return nil, nil
end

yield_vars = block_arg_type.arg_types.map_with_index do |input, i|
yield_vars = block_arg_restriction_type.arg_types.map_with_index do |input, i|
Var.new("var#{i}", input)
end
output = block_arg_type.return_type
output = block_arg_restriction_type.return_type
output_type = output
output_type = program.nil if output_type.void?
end
Expand Down

0 comments on commit 24f32b8

Please sign in to comment.