Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/typeprof/core/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def self.create_pattern_node(raw_node, lenv)

when :array_node then ArrayNode.new(raw_node, lenv) # for %w[foo bar]
when :range_node then RangeNode.new(raw_node, lenv) # TODO: support range pattern correctly
when :lambda_node then LambdaNode.new(raw_node, lenv) # TODO: match by `===` instead of ignoring the subject
when :lambda_node then LambdaNode.new(raw_node, lenv)

else
raise "unknown pattern node type: #{ raw_node.type }"
Expand Down
12 changes: 12 additions & 0 deletions lib/typeprof/core/ast/value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,18 @@ def install0(genv)
class LambdaNode < BlockNode
def lambda? = true

# A diagnostic on the `===` call below, such as wrong arity, points at the
# whole lambda.
def mid_code_range = nil

# `in ->(x) { ... }` matches by calling the lambda with the subject.
def install_pattern0(genv, subject)
recv = install0(genv)
a_args = ActualArguments.new([subject], [false], nil, nil)
@changes.add_method_call_box(genv, recv, :===, a_args, false)
recv
end

# A lambda is entered like a method, so every parameter kind binds, not just
# the positionals a block is handed.
def build_formals(genv, blenv, f_args)
Expand Down
32 changes: 32 additions & 0 deletions scenario/patterns/lambda_pat_subject.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## update: test.rb
def pr(x)
x
end

def check(x)
case x
in ->(i) { pr(i).foo }
:a
end
end

def check_arity(x)
case x
in ->(i, j) { true }
:a
end
end

check(0)
check_arity(0)

## diagnostics
(7,19)-(7,22): undefined method: Integer#foo
(14,5)-(14,22): wrong number of arguments (1 for 2)

## assert
class Object
def pr: (Integer) -> Integer
def check: (Integer) -> :a
def check_arity: (Integer) -> :a
end
Loading