From 5b8f82d3ce977d8ac6432126a32c7284bd2c7f30 Mon Sep 17 00:00:00 2001 From: Takumi Shotoku Date: Sat, 5 Sep 2026 17:47:53 +0900 Subject: [PATCH] Support an unless guard in a pattern AST.create_pattern_node routed a guard to IfPatternNode only for :if_node, so `in pat unless cond` raised "unknown pattern node type: unless_node". IfPatternNode reads only the predicate and the guarded pattern, so an unless guard needs no node of its own; only the sanity check differs, because Prism names the else slot `subsequent` on IfNode and `else_clause` on UnlessNode. --- lib/typeprof/core/ast.rb | 2 +- lib/typeprof/core/ast/pattern.rb | 3 ++- scenario/patterns/unless_pat.rb | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 scenario/patterns/unless_pat.rb diff --git a/lib/typeprof/core/ast.rb b/lib/typeprof/core/ast.rb index 8420c3881..e08a4ac87 100644 --- a/lib/typeprof/core/ast.rb +++ b/lib/typeprof/core/ast.rb @@ -362,7 +362,7 @@ def self.create_pattern_node(raw_node, lenv) when :capture_pattern_node then CapturePatternNode.new(raw_node, lenv) - when :if_node then IfPatternNode.new(raw_node, lenv) + when :if_node, :unless_node then IfPatternNode.new(raw_node, lenv) when :pinned_variable_node then PinnedPatternNode.new(raw_node, lenv) when :pinned_expression_node then PinnedPatternNode.new(raw_node, lenv) diff --git a/lib/typeprof/core/ast/pattern.rb b/lib/typeprof/core/ast/pattern.rb index 29473e3ed..eed2da948 100644 --- a/lib/typeprof/core/ast/pattern.rb +++ b/lib/typeprof/core/ast/pattern.rb @@ -144,7 +144,8 @@ def initialize(raw_node, lenv) raise if raw_node.statements.type != :statements_node raise if raw_node.statements.body.size != 1 @body = AST.create_pattern_node(raw_node.statements.body[0], lenv) - raise if raw_node.subsequent + raise if raw_node.type == :if_node && raw_node.subsequent + raise if raw_node.type == :unless_node && raw_node.else_clause end attr_reader :cond, :body diff --git a/scenario/patterns/unless_pat.rb b/scenario/patterns/unless_pat.rb new file mode 100644 index 000000000..11c0157c7 --- /dev/null +++ b/scenario/patterns/unless_pat.rb @@ -0,0 +1,17 @@ +## update: test.rb +def cond?(x) + x +end + +def check(x) + case x + in 1 unless cond?(:ok) + :ok + end +end + +## assert +class Object + def cond?: (:ok) -> :ok + def check: (untyped) -> :ok +end