From eeb98ddec990f2783d397dc8e0f3f2ff81886dfa Mon Sep 17 00:00:00 2001 From: Masataka Pocke Kuwabara Date: Fri, 1 Jan 2021 14:31:53 +0900 Subject: [PATCH] Fix error on implicit `to_proc` syntax when `untyped` is yielded --- lib/steep/type_construction.rb | 41 +++++++++++++++++++--------------- test/type_construction_test.rb | 23 +++++++++++++++++++ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/lib/steep/type_construction.rb b/lib/steep/type_construction.rb index aafc7a1c6..73703f038 100644 --- a/lib/steep/type_construction.rb +++ b/lib/steep/type_construction.rb @@ -2082,24 +2082,29 @@ def synthesize(node, hint: nil, condition: false) if hint.one_arg? # Assumes Symbol#to_proc implementation param_type = hint.type.params.required[0] - interface = checker.factory.interface(param_type, private: true) - method = interface.methods[value.children[0]] - if method - return_types = method.method_types.select {|method_type| - method_type.type.params.empty? - }.map {|method_type| - method_type.type.return_type - } - - unless return_types.empty? - type = AST::Types::Proc.new( - type: Interface::Function.new( - params: Interface::Function::Params.empty.update(required: [param_type]), - return_type: AST::Types::Union.build(types: return_types), - location: nil - ), - block: nil - ) + case param_type + when AST::Types::Any + type = AST::Types::Any.new + else + interface = checker.factory.interface(param_type, private: true) + method = interface.methods[value.children[0]] + if method + return_types = method.method_types.select {|method_type| + method_type.type.params.empty? + }.map {|method_type| + method_type.type.return_type + } + + unless return_types.empty? + type = AST::Types::Proc.new( + type: Interface::Function.new( + params: Interface::Function::Params.empty.update(required: [param_type]), + return_type: AST::Types::Union.build(types: return_types), + location: nil + ), + block: nil + ) + end end end else diff --git a/test/type_construction_test.rb b/test/type_construction_test.rb index 2c85780b8..4a9770f3a 100644 --- a/test/type_construction_test.rb +++ b/test/type_construction_test.rb @@ -6213,6 +6213,29 @@ def foo: () { (Integer) -> String }-> String end end + def test_block_pass_and_untyped + with_checker(<<-RBS) do |checker| +interface _YieldUntyped + def m: [T] () { (untyped) -> T } -> T +end + RBS + source = parse_ruby(<<-EOF) +# @type var x: _YieldUntyped +x = (_ = nil) +r = x.m(&:to_s) + EOF + + with_standard_construction(checker, source) do |construction, typing| + pair = construction.synthesize(source.node) + + assert_no_error typing + + assert_equal parse_type("::_YieldUntyped"), pair.context.lvar_env[:x] + assert_equal parse_type("untyped"), pair.context.lvar_env[:r] + end + end + end + def test_send_unsatisfiable_constraint with_checker(<