steep 1.5.0.pre.3 → 1.5.0.pre.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +1 -1
- data/lib/steep/ast/types/factory.rb +10 -5
- data/lib/steep/diagnostic/ruby.rb +17 -1
- data/lib/steep/type_construction.rb +130 -83
- data/lib/steep/type_inference/context.rb +3 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +4 -0
- data/lib/steep/version.rb +1 -1
- data/sig/shims/parser/nodes.rbs +5 -0
- data/sig/steep/diagnostic/ruby.rbs +25 -0
- data/sig/steep/type_construction.rbs +14 -2
- data/smoke/diagnostics/test_expectations.yml +0 -12
- data/smoke/type_case/test_expectations.yml +6 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed79428764aa83fbd2e7f3c5a8e52ff863b4e65bef05aae43ba9ca4b7c9d2f4e
|
4
|
+
data.tar.gz: be79772ce19f152e3048ae565802640cae96f1bfca98adf60eab47a28ab3ccad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa071be8eaf425a2a36ffed4c8d0a97446997f9cbf85c9dc4190b5bf26c9bf5f66c7106ab27b96378d05e246a6327689ef491dedbd16ad7cb9eb8d8079b3818d
|
7
|
+
data.tar.gz: d7f842d51c84a2f48bdfd79a07de3e6265dd746497aa9661871f12b062832c2a24f46b37ce1ddb614ac5ba1c65f4c408e9e1eafec27fd69d7158514fe77e0fec
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,22 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.5.0.pre.5 (2023-07-07)
|
6
|
+
|
7
|
+
### Type checker core
|
8
|
+
|
9
|
+
* Unreachability improvements ([#845](https://github.com/soutaro/steep/pull/845))
|
10
|
+
* Fix type inference problem ([#843](https://github.com/soutaro/steep/pull/843))
|
11
|
+
|
12
|
+
## 1.5.0.pre.4 (2023-07-06)
|
13
|
+
|
14
|
+
### Type checker core
|
15
|
+
|
16
|
+
* Fix unreachability test ([#842](https://github.com/soutaro/steep/pull/842))
|
17
|
+
* Make type of `case` node `untyped` rather than `nil` ([#841](https://github.com/soutaro/steep/pull/841))
|
18
|
+
* Fix `#partition_union` ([#840](https://github.com/soutaro/steep/pull/840))
|
19
|
+
* Fix type-case ([#839](https://github.com/soutaro/steep/pull/839))
|
20
|
+
|
5
21
|
## 1.5.0.pre.3 (2023-07-05)
|
6
22
|
|
7
23
|
### Type checker core
|
data/Gemfile.lock
CHANGED
@@ -204,7 +204,7 @@ module Steep
|
|
204
204
|
when Logic::Base
|
205
205
|
RBS::Types::Bases::Bool.new(location: type.location)
|
206
206
|
else
|
207
|
-
|
207
|
+
raise "Unexpected type given: #{type} (#{type.class})"
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
@@ -358,16 +358,21 @@ module Steep
|
|
358
358
|
partition_union(unfold)
|
359
359
|
end
|
360
360
|
when AST::Types::Union
|
361
|
-
|
362
|
-
|
363
|
-
|
361
|
+
truthy_types = [] #: Array[AST::Types::t]
|
362
|
+
falsy_types = [] #: Array[AST::Types::t]
|
363
|
+
|
364
|
+
type.types.each do |type|
|
365
|
+
truthy, falsy = partition_union(type)
|
366
|
+
|
367
|
+
truthy_types << truthy if truthy
|
368
|
+
falsy_types << falsy if falsy
|
364
369
|
end
|
365
370
|
|
366
371
|
[
|
367
372
|
truthy_types.empty? ? nil : AST::Types::Union.build(types: truthy_types),
|
368
373
|
falsy_types.empty? ? nil : AST::Types::Union.build(types: falsy_types)
|
369
374
|
]
|
370
|
-
when AST::Types::Any, AST::Types::Boolean
|
375
|
+
when AST::Types::Any, AST::Types::Boolean, AST::Types::Top, AST::Types::Logic::Base
|
371
376
|
[type, type]
|
372
377
|
when AST::Types::Nil
|
373
378
|
[nil, type]
|
@@ -767,6 +767,19 @@ module Steep
|
|
767
767
|
end
|
768
768
|
end
|
769
769
|
|
770
|
+
class UnreachableValueBranch < Base
|
771
|
+
attr_reader :type
|
772
|
+
|
773
|
+
def initialize(node:, type:, location: node.location.expression)
|
774
|
+
super(node: node, location: location)
|
775
|
+
@type = type
|
776
|
+
end
|
777
|
+
|
778
|
+
def header_line
|
779
|
+
"The branch may evaluate to a value of `#{type}` but unreachable"
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
770
783
|
class UnexpectedSplat < Base
|
771
784
|
attr_reader :type
|
772
785
|
|
@@ -968,7 +981,8 @@ module Steep
|
|
968
981
|
{
|
969
982
|
ImplicitBreakValueMismatch => :warning,
|
970
983
|
FallbackAny => :information,
|
971
|
-
|
984
|
+
UnreachableValueBranch => :warning,
|
985
|
+
UnreachableBranch => :information,
|
972
986
|
UnknownConstant => :warning,
|
973
987
|
MethodDefinitionMissing => :information,
|
974
988
|
FalseAssertion => :information,
|
@@ -989,6 +1003,7 @@ module Steep
|
|
989
1003
|
NoMethod => nil,
|
990
1004
|
ImplicitBreakValueMismatch => nil,
|
991
1005
|
FallbackAny => nil,
|
1006
|
+
UnreachableValueBranch => nil,
|
992
1007
|
UnreachableBranch => nil,
|
993
1008
|
UnknownConstant => nil,
|
994
1009
|
MethodDefinitionMissing => nil,
|
@@ -1006,6 +1021,7 @@ module Steep
|
|
1006
1021
|
NoMethod => nil,
|
1007
1022
|
ImplicitBreakValueMismatch => nil,
|
1008
1023
|
FallbackAny => nil,
|
1024
|
+
UnreachableValueBranch => nil,
|
1009
1025
|
UnreachableBranch => nil,
|
1010
1026
|
UnknownConstant => nil,
|
1011
1027
|
MethodDefinitionMissing => nil,
|
@@ -1398,8 +1398,11 @@ module Steep
|
|
1398
1398
|
when :true, :false
|
1399
1399
|
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1400
1400
|
|
1401
|
-
|
1401
|
+
case
|
1402
|
+
when hint && check_relation(sub_type: ty, super_type: hint).success? && !hint.is_a?(AST::Types::Any) && !hint.is_a?(AST::Types::Top)
|
1402
1403
|
add_typing(node, type: hint)
|
1404
|
+
when condition
|
1405
|
+
add_typing(node, type: ty)
|
1403
1406
|
else
|
1404
1407
|
add_typing(node, type: AST::Types::Boolean.new)
|
1405
1408
|
end
|
@@ -1880,9 +1883,25 @@ module Steep
|
|
1880
1883
|
|
1881
1884
|
if truthy.unreachable
|
1882
1885
|
if true_clause
|
1886
|
+
_, _, _, loc = deconstruct_if_node!(node)
|
1887
|
+
|
1888
|
+
if loc.respond_to?(:keyword)
|
1889
|
+
condition_loc = loc #: NodeHelper::condition_loc
|
1890
|
+
case condition_loc.keyword.source
|
1891
|
+
when "if"
|
1892
|
+
location = condition_loc.begin || condition_loc.keyword
|
1893
|
+
when "unless"
|
1894
|
+
# `else` token always exists
|
1895
|
+
location = condition_loc.else || raise
|
1896
|
+
end
|
1897
|
+
else
|
1898
|
+
location = true_clause.loc.expression
|
1899
|
+
end
|
1900
|
+
|
1883
1901
|
typing.add_error(
|
1884
1902
|
Diagnostic::Ruby::UnreachableBranch.new(
|
1885
|
-
node: true_clause
|
1903
|
+
node: true_clause,
|
1904
|
+
location: location || raise
|
1886
1905
|
)
|
1887
1906
|
)
|
1888
1907
|
end
|
@@ -1890,9 +1909,25 @@ module Steep
|
|
1890
1909
|
|
1891
1910
|
if falsy.unreachable
|
1892
1911
|
if false_clause
|
1912
|
+
_, _, _, loc = deconstruct_if_node!(node)
|
1913
|
+
|
1914
|
+
if loc.respond_to?(:keyword)
|
1915
|
+
condition_loc = loc #: NodeHelper::condition_loc
|
1916
|
+
case condition_loc.keyword.source
|
1917
|
+
when "if"
|
1918
|
+
# `else` token always exists
|
1919
|
+
location = condition_loc.else || raise
|
1920
|
+
when "unless"
|
1921
|
+
location = condition_loc.begin || condition_loc.keyword
|
1922
|
+
end
|
1923
|
+
else
|
1924
|
+
location = false_clause.loc.expression
|
1925
|
+
end
|
1926
|
+
|
1893
1927
|
typing.add_error(
|
1894
1928
|
Diagnostic::Ruby::UnreachableBranch.new(
|
1895
|
-
node: false_clause
|
1929
|
+
node: false_clause,
|
1930
|
+
location: location || raise
|
1896
1931
|
)
|
1897
1932
|
)
|
1898
1933
|
end
|
@@ -1920,18 +1955,9 @@ module Steep
|
|
1920
1955
|
cond_vars.delete(name)
|
1921
1956
|
end
|
1922
1957
|
|
1923
|
-
var_name = :"_a#{SecureRandom.alphanumeric(4)}"
|
1924
|
-
var_cond, value_node =
|
1925
|
-
|
1926
|
-
unless constr.context.type_env[value_node]
|
1927
|
-
constr = constr.update_type_env do |env|
|
1928
|
-
env.assign_local_variable(var_name, cond_type, nil)
|
1929
|
-
end
|
1930
|
-
cond = var_cond
|
1931
|
-
else
|
1932
|
-
value_node = nil
|
1933
|
-
end
|
1934
|
-
end
|
1958
|
+
var_name = :"_a[#{SecureRandom.alphanumeric(4)}]"
|
1959
|
+
var_cond, value_node = transform_condition_node(cond, var_name)
|
1960
|
+
constr = constr.update_type_env {|env| env.assign_local_variable(var_name, cond_type, nil) }
|
1935
1961
|
|
1936
1962
|
next_branch_reachable = true
|
1937
1963
|
|
@@ -1949,12 +1975,12 @@ module Steep
|
|
1949
1975
|
false_branch_reachable = false
|
1950
1976
|
|
1951
1977
|
tests.each do |test|
|
1952
|
-
test_node = test.updated(:send, [test, :===,
|
1978
|
+
test_node = test.updated(:send, [test, :===, var_cond])
|
1953
1979
|
test_type, test_constr = test_constr.synthesize(test_node, condition: true).to_ary
|
1954
1980
|
truthy, falsy = interpreter.eval(node: test_node, env: test_constr.context.type_env)
|
1955
1981
|
|
1956
|
-
truthy_env = truthy.env
|
1957
|
-
falsy_env = falsy.env
|
1982
|
+
truthy_env = propagate_type_env(var_name, value_node, truthy.env)
|
1983
|
+
falsy_env = propagate_type_env(var_name, value_node, falsy.env)
|
1958
1984
|
|
1959
1985
|
test_envs << truthy_env
|
1960
1986
|
|
@@ -1967,19 +1993,25 @@ module Steep
|
|
1967
1993
|
next_branch_reachable &&= false_branch_reachable
|
1968
1994
|
body_constr = when_constr.update_type_env {|env| env.join(*test_envs) }
|
1969
1995
|
|
1970
|
-
|
1971
|
-
|
1996
|
+
branch_result =
|
1997
|
+
if body
|
1972
1998
|
body_constr
|
1973
1999
|
.for_branch(body)
|
1974
2000
|
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1975
2001
|
.synthesize(body, hint: hint)
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
2002
|
+
else
|
2003
|
+
Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
|
2004
|
+
end
|
1979
2005
|
|
1980
|
-
|
2006
|
+
branch_results << branch_result
|
2007
|
+
|
2008
|
+
if !branch_reachable && !branch_result.type.is_a?(AST::Types::Bot)
|
1981
2009
|
typing.add_error(
|
1982
|
-
Diagnostic::Ruby::
|
2010
|
+
Diagnostic::Ruby::UnreachableValueBranch.new(
|
2011
|
+
node: clause,
|
2012
|
+
type: branch_result.type,
|
2013
|
+
location: clause.location.keyword
|
2014
|
+
)
|
1983
2015
|
)
|
1984
2016
|
end
|
1985
2017
|
|
@@ -2003,11 +2035,6 @@ module Steep
|
|
2003
2035
|
types = branch_results.map(&:type)
|
2004
2036
|
constrs = branch_results.map(&:constr)
|
2005
2037
|
|
2006
|
-
cond_type = when_constr.context.type_env[var_name]
|
2007
|
-
cond_type ||= when_constr.context.type_env[cond_vars.first || raise] unless cond_vars.empty?
|
2008
|
-
cond_type ||= when_constr.context.type_env[value_node] if value_node
|
2009
|
-
cond_type ||= typing.type_of(node: node.children[0])
|
2010
|
-
|
2011
2038
|
if !next_branch_reachable
|
2012
2039
|
# Exhaustive
|
2013
2040
|
_, _, _, loc = deconstruct_case_node!(node)
|
@@ -2015,9 +2042,14 @@ module Steep
|
|
2015
2042
|
# `else` may present even if it's empty
|
2016
2043
|
if loc.else
|
2017
2044
|
if els
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2045
|
+
else_result or raise
|
2046
|
+
unless else_result.type.is_a?(AST::Types::Bot)
|
2047
|
+
typing.add_error Diagnostic::Ruby::UnreachableValueBranch.new(
|
2048
|
+
node: els,
|
2049
|
+
type: else_result.type,
|
2050
|
+
location: node.loc.else || raise
|
2051
|
+
)
|
2052
|
+
end
|
2021
2053
|
end
|
2022
2054
|
end
|
2023
2055
|
else
|
@@ -2030,9 +2062,6 @@ module Steep
|
|
2030
2062
|
branch_results = [] #: Array[Pair]
|
2031
2063
|
|
2032
2064
|
condition_constr = constr
|
2033
|
-
clause_constr = constr
|
2034
|
-
|
2035
|
-
next_branch_reachable = true
|
2036
2065
|
|
2037
2066
|
whens.each do |when_clause|
|
2038
2067
|
when_clause_constr = condition_constr
|
@@ -2043,7 +2072,6 @@ module Steep
|
|
2043
2072
|
*tests, body = when_clause.children
|
2044
2073
|
|
2045
2074
|
branch_reachable = false
|
2046
|
-
false_branch_reachable = false
|
2047
2075
|
|
2048
2076
|
tests.each do |test|
|
2049
2077
|
test_type, condition_constr = condition_constr.synthesize(test, condition: true)
|
@@ -2054,27 +2082,32 @@ module Steep
|
|
2054
2082
|
condition_constr = condition_constr.update_type_env { falsy_env }
|
2055
2083
|
body_envs << truthy_env
|
2056
2084
|
|
2057
|
-
branch_reachable ||=
|
2058
|
-
false_branch_reachable ||= !falsy.unreachable
|
2085
|
+
branch_reachable ||= !truthy.unreachable
|
2059
2086
|
end
|
2060
2087
|
|
2061
|
-
|
2062
|
-
|
2063
|
-
if body
|
2064
|
-
branch_results <<
|
2088
|
+
branch_result =
|
2089
|
+
if body
|
2065
2090
|
when_clause_constr
|
2066
2091
|
.for_branch(body)
|
2067
2092
|
.update_type_env {|env| env.join(*body_envs) }
|
2068
2093
|
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
2069
2094
|
.synthesize(body, hint: hint)
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2095
|
+
else
|
2096
|
+
Pair.new(type: AST::Builtin.nil_type, constr: when_clause_constr)
|
2097
|
+
end
|
2098
|
+
|
2099
|
+
branch_results << branch_result
|
2073
2100
|
|
2074
2101
|
unless branch_reachable
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2102
|
+
unless branch_result.type.is_a?(AST::Types::Bot)
|
2103
|
+
typing.add_error(
|
2104
|
+
Diagnostic::Ruby::UnreachableValueBranch.new(
|
2105
|
+
node: when_clause,
|
2106
|
+
type: branch_result.type,
|
2107
|
+
location: when_clause.location.keyword || raise
|
2108
|
+
)
|
2109
|
+
)
|
2110
|
+
end
|
2078
2111
|
end
|
2079
2112
|
end
|
2080
2113
|
|
@@ -3931,13 +3964,15 @@ module Steep
|
|
3931
3964
|
end
|
3932
3965
|
|
3933
3966
|
if hint && !fvs.empty?
|
3934
|
-
if
|
3935
|
-
|
3936
|
-
|
3967
|
+
if hint.free_variables.subset?(self_type.free_variables)
|
3968
|
+
if check_relation(sub_type: method_type.type.return_type, super_type: hint, constraints: constraints).success?
|
3969
|
+
method_type, solved, s = apply_solution(errors, node: node, method_type: method_type) do
|
3970
|
+
constraints.solution(checker, variables: fvs, context: ccontext)
|
3971
|
+
end
|
3937
3972
|
end
|
3938
|
-
end
|
3939
3973
|
|
3940
|
-
|
3974
|
+
method_type.block or raise
|
3975
|
+
end
|
3941
3976
|
end
|
3942
3977
|
|
3943
3978
|
# Method accepts block
|
@@ -4490,16 +4525,27 @@ module Steep
|
|
4490
4525
|
end
|
4491
4526
|
|
4492
4527
|
def union_type_unify(*types)
|
4493
|
-
types.
|
4494
|
-
unless no_subtyping?(sub_type: type1, super_type: type2)
|
4495
|
-
next type2
|
4496
|
-
end
|
4528
|
+
types = types.reject {|t| t.is_a?(AST::Types::Bot) }
|
4497
4529
|
|
4498
|
-
|
4499
|
-
|
4500
|
-
|
4530
|
+
if types.empty?
|
4531
|
+
AST::Types::Bot.new
|
4532
|
+
else
|
4533
|
+
types.inject do |type1, type2|
|
4534
|
+
next type2 if type1.is_a?(AST::Types::Any)
|
4535
|
+
next type1 if type2.is_a?(AST::Types::Any)
|
4536
|
+
|
4537
|
+
unless no_subtyping?(sub_type: type1, super_type: type2)
|
4538
|
+
# type1 <: type2
|
4539
|
+
next type2
|
4540
|
+
end
|
4541
|
+
|
4542
|
+
unless no_subtyping?(sub_type: type2, super_type: type1)
|
4543
|
+
# type2 <: type1
|
4544
|
+
next type1
|
4545
|
+
end
|
4501
4546
|
|
4502
|
-
|
4547
|
+
union_type(type1, type2)
|
4548
|
+
end
|
4503
4549
|
end
|
4504
4550
|
end
|
4505
4551
|
|
@@ -5029,33 +5075,19 @@ module Steep
|
|
5029
5075
|
with_new_typing(typing.parent || raise)
|
5030
5076
|
end
|
5031
5077
|
|
5032
|
-
def
|
5078
|
+
def transform_condition_node(node, var_name)
|
5033
5079
|
case node.type
|
5034
5080
|
when :lvasgn
|
5035
5081
|
name, rhs = node.children
|
5036
|
-
rhs, value_node =
|
5037
|
-
|
5038
|
-
[node.updated(nil, [name, rhs]), value_node]
|
5039
|
-
else
|
5040
|
-
[node, value_node]
|
5041
|
-
end
|
5082
|
+
rhs, value_node = transform_condition_node(rhs, var_name)
|
5083
|
+
[node.updated(nil, [name, rhs]), value_node]
|
5042
5084
|
when :begin
|
5043
5085
|
*children, last = node.children
|
5044
|
-
last, value_node =
|
5045
|
-
|
5046
|
-
[node.updated(nil, children.push(last)), value_node]
|
5047
|
-
else
|
5048
|
-
[node, value_node]
|
5049
|
-
end
|
5050
|
-
when :lvar
|
5051
|
-
[node, nil]
|
5086
|
+
last, value_node = transform_condition_node(last, var_name)
|
5087
|
+
[node.updated(nil, children.push(last)), value_node]
|
5052
5088
|
else
|
5053
|
-
|
5054
|
-
|
5055
|
-
else
|
5056
|
-
var_node = node.updated(:lvar, [var_name])
|
5057
|
-
[var_node, node]
|
5058
|
-
end
|
5089
|
+
var_node = node.updated(:lvar, [var_name])
|
5090
|
+
[var_node, node]
|
5059
5091
|
end
|
5060
5092
|
end
|
5061
5093
|
|
@@ -5109,5 +5141,20 @@ module Steep
|
|
5109
5141
|
end
|
5110
5142
|
end
|
5111
5143
|
end
|
5144
|
+
|
5145
|
+
def propagate_type_env(source, dest, env)
|
5146
|
+
source_type = env[source] or raise
|
5147
|
+
|
5148
|
+
if dest.type == :lvar
|
5149
|
+
var_name = dest.children[0] #: Symbol
|
5150
|
+
env.assign_local_variable(var_name, source_type, nil)
|
5151
|
+
else
|
5152
|
+
if env[dest]
|
5153
|
+
env.replace_pure_call_type(dest, source_type)
|
5154
|
+
else
|
5155
|
+
env
|
5156
|
+
end
|
5157
|
+
end
|
5158
|
+
end
|
5112
5159
|
end
|
5113
5160
|
end
|
@@ -126,7 +126,9 @@ module Steep
|
|
126
126
|
|
127
127
|
def upper_bounds
|
128
128
|
table.each_value.with_object({}) do |type_param, bounds|
|
129
|
-
|
129
|
+
if type_param.upper_bound
|
130
|
+
bounds[type_param.name] = type_param.upper_bound
|
131
|
+
end
|
130
132
|
end
|
131
133
|
end
|
132
134
|
|
data/lib/steep/version.rb
CHANGED
data/sig/shims/parser/nodes.rbs
CHANGED
@@ -479,6 +479,31 @@ module Steep
|
|
479
479
|
def header_line: () -> String
|
480
480
|
end
|
481
481
|
|
482
|
+
# The branch is unreachable, but not `bot` type
|
483
|
+
#
|
484
|
+
# We often have `else` branch to make the code more defensive:
|
485
|
+
#
|
486
|
+
# ```ruby
|
487
|
+
# case value
|
488
|
+
# when Integer
|
489
|
+
# # ...
|
490
|
+
# when String
|
491
|
+
# # ...
|
492
|
+
# else
|
493
|
+
# raise "Cannot happen!"
|
494
|
+
# end
|
495
|
+
# ```
|
496
|
+
#
|
497
|
+
# This diagnostic allows writing `raise` or `return`, by checking the type of the branch body is `bot` or not.
|
498
|
+
#
|
499
|
+
class UnreachableValueBranch < Base
|
500
|
+
attr_reader type: AST::Types::t
|
501
|
+
|
502
|
+
def initialize: (node: Parser::AST::Node, type: AST::Types::t, ?location: location) -> void
|
503
|
+
|
504
|
+
def header_line: () -> String
|
505
|
+
end
|
506
|
+
|
482
507
|
class UnexpectedSplat < Base
|
483
508
|
attr_reader type: untyped
|
484
509
|
|
@@ -538,18 +538,30 @@ module Steep
|
|
538
538
|
# Returns a pair of transformed node and the outer most call/non-value node if present.
|
539
539
|
#
|
540
540
|
# ```rb
|
541
|
-
# x = y = foo() # Call `#
|
541
|
+
# x = y = foo() # Call `#transform_condition_node` with the node and var_name `:__foo__`
|
542
542
|
# # => Returns [x = y = __foo__, foo()]
|
543
|
+
#
|
544
|
+
# x # Call `#transform_condition_node` with the node and var_name `:__foo__`
|
545
|
+
# # => Returns [__foo__, x]
|
543
546
|
# ```
|
544
547
|
#
|
545
548
|
# This is typically used for transforming assginment node for case condition.
|
546
549
|
#
|
547
|
-
def
|
550
|
+
def transform_condition_node: (Parser::AST::Node node, Symbol) -> [Parser::AST::Node, Parser::AST::Node]
|
548
551
|
|
549
552
|
def type_name: (AST::Types::t) -> RBS::TypeName?
|
550
553
|
|
551
554
|
def singleton_type: (AST::Types::t) -> AST::Types::t?
|
552
555
|
|
553
556
|
def instance_type: (AST::Types::t) -> AST::Types::t?
|
557
|
+
|
558
|
+
# Propagate an entry of `source` in TypeEnv to `dest`
|
559
|
+
#
|
560
|
+
# `source` is name of a local variable.
|
561
|
+
#
|
562
|
+
# If `dest` is a `lvar` node, it updates local variable entry of TypeEnv.
|
563
|
+
# Otherwise, it updates *pure* call of `dest` if it already exists.
|
564
|
+
#
|
565
|
+
def propagate_type_env: (Symbol source, Parser::AST::Node dest, TypeInference::TypeEnv) -> TypeInference::TypeEnv
|
554
566
|
end
|
555
567
|
end
|
@@ -120,18 +120,6 @@
|
|
120
120
|
message: 'The method parameter has different kind from the declaration `(name:
|
121
121
|
::String, size: ::Integer) -> void`'
|
122
122
|
code: Ruby::DifferentMethodParameterKind
|
123
|
-
- file: else_on_exhaustive_case.rb
|
124
|
-
diagnostics:
|
125
|
-
- range:
|
126
|
-
start:
|
127
|
-
line: 11
|
128
|
-
character: 2
|
129
|
-
end:
|
130
|
-
line: 11
|
131
|
-
character: 26
|
132
|
-
severity: ERROR
|
133
|
-
message: The branch is unreachable
|
134
|
-
code: Ruby::UnreachableBranch
|
135
123
|
- file: incompatible_annotation.rb
|
136
124
|
diagnostics:
|
137
125
|
- range:
|
@@ -13,14 +13,14 @@
|
|
13
13
|
code: Ruby::NoMethod
|
14
14
|
- range:
|
15
15
|
start:
|
16
|
-
line:
|
17
|
-
character:
|
16
|
+
line: 11
|
17
|
+
character: 0
|
18
18
|
end:
|
19
|
-
line:
|
20
|
-
character:
|
19
|
+
line: 11
|
20
|
+
character: 4
|
21
21
|
severity: ERROR
|
22
|
-
message: The branch
|
23
|
-
code: Ruby::
|
22
|
+
message: The branch may evaluate to a value of `untyped` but unreachable
|
23
|
+
code: Ruby::UnreachableValueBranch
|
24
24
|
- range:
|
25
25
|
start:
|
26
26
|
line: 12
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.0.pre.
|
4
|
+
version: 1.5.0.pre.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|