steep 1.5.0.pre.3 → 1.5.0.pre.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|