Skip to content

Commit

Permalink
Fix else clause of case-when syntax typing
Browse files Browse the repository at this point in the history
  • Loading branch information
soutaro committed Jan 20, 2025
1 parent 985568d commit 17e5e10
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 4 deletions.
10 changes: 6 additions & 4 deletions lib/steep/type_construction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2051,14 +2051,16 @@ def synthesize(node, hint: nil, condition: false)

if els
branch_results << condition_constr.synthesize(els, hint: hint)
else
branch_results << Pair.new(type: AST::Builtin.nil_type, constr: condition_constr)
end

branch_results.reject! do |result|
result.type.is_a?(AST::Types::Bot)
end

types = branch_results.map(&:type)
envs = branch_results.map {|result| result.constr.context.type_env }

unless els
types << AST::Builtin.nil_type
end
end

constr = constr.update_type_env do |env|
Expand Down
2 changes: 2 additions & 0 deletions lib/steep/type_inference/case_when.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ def result
end
end

results.reject! { _1.type.is_a?(AST::Types::Bot) }

types = results.map {|result| result.type }
envs = results.map {|result| result.env }

Expand Down
156 changes: 156 additions & 0 deletions test/type_check_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2927,4 +2927,160 @@ def test_tuple_type_assertion
YAML
)
end

def test_case_when__no_subject__assignment_in_when__raise_in_else
run_type_check_test(
signatures: {
},
code: {
"a.rb" => <<~RUBY
case
when 1
v = 1
when 2
v = 10
else
raise
end
v + 1
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics: []
YAML
)
end

def test_case_when__no_subject__assignment_in_when__no_else
run_type_check_test(
signatures: {
},
code: {
"a.rb" => <<~RUBY
case
when 1
v = 1
when 2
v = 10
else
end
v + 1
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics:
- range:
start:
line: 9
character: 2
end:
line: 9
character: 3
severity: ERROR
message: Type `(::Integer | nil)` does not have method `+`
code: Ruby::NoMethod
YAML
)
end

def test_case_when__with_subject__assignment_in_when__raise_in_else
run_type_check_test(
signatures: {
},
code: {
"a.rb" => <<~RUBY
case rand(3)
when 1
v = 1
when 2
v = 10
else
raise
end
v + 1
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics: []
YAML
)
end

def test_case_when__with_subject__assignment_in_when__empty_else
run_type_check_test(
signatures: {
},
code: {
"a.rb" => <<~RUBY
case rand(3)
when 1
v = 1
when 2
v = 10
else
end
v + 1
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics:
- range:
start:
line: 9
character: 2
end:
line: 9
character: 3
severity: ERROR
message: Type `(::Integer | nil)` does not have method `+`
code: Ruby::NoMethod
YAML
)
end

def test_case_when__with_subject__assignment_in_when__no_else
run_type_check_test(
signatures: {
},
code: {
"a.rb" => <<~RUBY
case rand(3)
when 1
v = 1
when 2
v = 10
end
v + 1
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics:
- range:
start:
line: 8
character: 2
end:
line: 8
character: 3
severity: ERROR
message: Type `(::Integer | nil)` does not have method `+`
code: Ruby::NoMethod
YAML
)
end
end

0 comments on commit 17e5e10

Please sign in to comment.