From 24f32b8589dcbfee74367e018c9823e89aa2e51e Mon Sep 17 00:00:00 2001 From: TSUYUSATO Kitsune Date: Sat, 13 Oct 2018 00:12:05 +0900 Subject: [PATCH] Fix recursive block expansion check for non ProcNotation restriction (#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. --- spec/compiler/semantic/block_spec.cr | 30 +++++++++++++++++++++++++++ src/compiler/crystal/semantic/call.cr | 10 ++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/spec/compiler/semantic/block_spec.cr b/spec/compiler/semantic/block_spec.cr index 3ddc08928c11..4b608f8609bf 100644 --- a/spec/compiler/semantic/block_spec.cr +++ b/spec/compiler/semantic/block_spec.cr @@ -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 diff --git a/src/compiler/crystal/semantic/call.cr b/src/compiler/crystal/semantic/call.cr index 1019dc2541b1..e931cc2bb631 100644 --- a/src/compiler/crystal/semantic/call.cr +++ b/src/compiler/crystal/semantic/call.cr @@ -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