steep 0.48.0 → 0.49.0
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 +8 -0
- data/Gemfile.lock +1 -1
- data/lib/steep/ast/types/any.rb +2 -0
- data/lib/steep/ast/types/boolean.rb +2 -0
- data/lib/steep/ast/types/bot.rb +2 -0
- data/lib/steep/ast/types/class.rb +2 -0
- data/lib/steep/ast/types/factory.rb +1 -1
- data/lib/steep/ast/types/helper.rb +8 -0
- data/lib/steep/ast/types/instance.rb +2 -0
- data/lib/steep/ast/types/intersection.rb +4 -0
- data/lib/steep/ast/types/literal.rb +2 -0
- data/lib/steep/ast/types/logic.rb +2 -0
- data/lib/steep/ast/types/name.rb +6 -0
- data/lib/steep/ast/types/nil.rb +2 -0
- data/lib/steep/ast/types/proc.rb +9 -0
- data/lib/steep/ast/types/record.rb +4 -0
- data/lib/steep/ast/types/self.rb +2 -0
- data/lib/steep/ast/types/top.rb +2 -0
- data/lib/steep/ast/types/tuple.rb +4 -0
- data/lib/steep/ast/types/union.rb +4 -0
- data/lib/steep/ast/types/var.rb +2 -0
- data/lib/steep/ast/types/void.rb +2 -0
- data/lib/steep/interface/function.rb +4 -0
- data/lib/steep/subtyping/check.rb +23 -2
- data/lib/steep/type_construction.rb +52 -25
- data/lib/steep/type_inference/block_params.rb +31 -3
- data/lib/steep/version.rb +1 -1
- data/smoke/tsort/a.rb +1 -1
- data/smoke/tsort/test_expectations.yml +1 -63
- 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: '0273968ec727f3b7c5c1007f9e27966c50ad7bc3128217a4ef30be4f97321037'
|
4
|
+
data.tar.gz: 195eb670673894e36af5e00ef911654f2a543c71e8de1d46c15e23035bef19c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0908edc4a3221256f450c9fd945d7127bd9ece3fa0359b7da88be8cebea30f7c766e023b84527e89e8f0c7956752310a3b0e98343b8c4808bfde518a89284456'
|
7
|
+
data.tar.gz: 4004adb0d0e8f2e0cd2629cd7e0c2bd6513a3a48bbd96d1d77621bbe0979b73686ab9c8ad718e3243081fdf492ff9728b5bf6df8e7357e1b1cf810393dad264c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.49.0 (2022-03-08)
|
6
|
+
|
7
|
+
* Better typing for `#flat_map` ([\#504](https://github.com/soutaro/steep/pull/504))
|
8
|
+
* Support lambdas (`->`) with block ([\#503](https://github.com/soutaro/steep/pull/503))
|
9
|
+
* Let proc type be `::Proc` class instance ([\#502](https://github.com/soutaro/steep/pull/502))
|
10
|
+
* Disable contextual typing on `bool` type ([\#501](https://github.com/soutaro/steep/pull/501))
|
11
|
+
* Type check `return` without value ([\#500](https://github.com/soutaro/steep/pull/500))
|
12
|
+
|
5
13
|
## 0.48.0 (2022-03-07)
|
6
14
|
|
7
15
|
Steep supports all of the new features of RBS 2. 🎉
|
data/Gemfile.lock
CHANGED
data/lib/steep/ast/types/any.rb
CHANGED
data/lib/steep/ast/types/bot.rb
CHANGED
data/lib/steep/ast/types/name.rb
CHANGED
@@ -72,6 +72,10 @@ module Steep
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
def each_child(&block)
|
76
|
+
args.each(&block)
|
77
|
+
end
|
78
|
+
|
75
79
|
include Helper::ChildrenLevel
|
76
80
|
|
77
81
|
def level
|
@@ -98,6 +102,8 @@ module Steep
|
|
98
102
|
def with_location(new_location)
|
99
103
|
self.class.new(name: name, location: new_location)
|
100
104
|
end
|
105
|
+
|
106
|
+
include Helper::NoChild
|
101
107
|
end
|
102
108
|
|
103
109
|
class Instance < Applying
|
data/lib/steep/ast/types/nil.rb
CHANGED
data/lib/steep/ast/types/proc.rb
CHANGED
@@ -90,6 +90,15 @@ module Steep
|
|
90
90
|
def block_required?
|
91
91
|
block && !block.optional?
|
92
92
|
end
|
93
|
+
|
94
|
+
def each_child(&block)
|
95
|
+
if block_given?
|
96
|
+
type.each_child(&block)
|
97
|
+
self.block&.type&.each_child(&block)
|
98
|
+
else
|
99
|
+
enum_for :each_child
|
100
|
+
end
|
101
|
+
end
|
93
102
|
end
|
94
103
|
end
|
95
104
|
end
|
data/lib/steep/ast/types/self.rb
CHANGED
data/lib/steep/ast/types/top.rb
CHANGED
data/lib/steep/ast/types/var.rb
CHANGED
data/lib/steep/ast/types/void.rb
CHANGED
@@ -347,7 +347,7 @@ module Steep
|
|
347
347
|
|
348
348
|
when relation.super_type.is_a?(AST::Types::Union)
|
349
349
|
Any(relation) do |result|
|
350
|
-
relation.super_type.types.each do |super_type|
|
350
|
+
relation.super_type.types.sort_by {|ty| (path = hole_path(ty)) ? -path.size : 1 }.each do |super_type|
|
351
351
|
rel = Relation.new(sub_type: relation.sub_type, super_type: super_type)
|
352
352
|
result.add(rel) do
|
353
353
|
check_type(rel)
|
@@ -357,7 +357,7 @@ module Steep
|
|
357
357
|
|
358
358
|
when relation.sub_type.is_a?(AST::Types::Intersection)
|
359
359
|
Any(relation) do |result|
|
360
|
-
relation.sub_type.types.each do |sub_type|
|
360
|
+
relation.sub_type.types.sort_by {|ty| (path = hole_path(ty)) ? -path.size : 1 }.each do |sub_type|
|
361
361
|
rel = Relation.new(sub_type: sub_type, super_type: relation.super_type)
|
362
362
|
result.add(rel) do
|
363
363
|
check_type(rel)
|
@@ -483,6 +483,9 @@ module Steep
|
|
483
483
|
check_interface(relation.map {|type| factory.interface(type, private: false) })
|
484
484
|
end
|
485
485
|
|
486
|
+
when relation.sub_type.is_a?(AST::Types::Proc) && AST::Builtin::Proc.instance_type?(relation.super_type)
|
487
|
+
Success(relation)
|
488
|
+
|
486
489
|
when relation.super_type.is_a?(AST::Types::Literal)
|
487
490
|
case
|
488
491
|
when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
|
@@ -971,6 +974,24 @@ module Steep
|
|
971
974
|
def expand_alias(type, &block)
|
972
975
|
factory.expand_alias(type, &block)
|
973
976
|
end
|
977
|
+
|
978
|
+
# Returns the shortest type paths for one of the _unknown_ type variables.
|
979
|
+
# Returns nil if there is no path.
|
980
|
+
def hole_path(type, path = [])
|
981
|
+
case type
|
982
|
+
when AST::Types::Var
|
983
|
+
if constraints.unknown?(type.name)
|
984
|
+
[type]
|
985
|
+
else
|
986
|
+
nil
|
987
|
+
end
|
988
|
+
else
|
989
|
+
paths = type.each_child.map do |ty|
|
990
|
+
hole_path(ty, path)&.unshift(ty)
|
991
|
+
end
|
992
|
+
paths.compact.min_by(&:size)
|
993
|
+
end
|
994
|
+
end
|
974
995
|
end
|
975
996
|
end
|
976
997
|
end
|
@@ -1005,7 +1005,7 @@ module Steep
|
|
1005
1005
|
yield_self do
|
1006
1006
|
send_node, params, body = node.children
|
1007
1007
|
if send_node.type == :lambda
|
1008
|
-
type_lambda(node,
|
1008
|
+
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
1009
1009
|
else
|
1010
1010
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
|
1011
1011
|
end
|
@@ -1024,7 +1024,7 @@ module Steep
|
|
1024
1024
|
params = Parser::AST::Node.new(:args, arg_nodes)
|
1025
1025
|
|
1026
1026
|
if send_node.type == :lambda
|
1027
|
-
type_lambda(node,
|
1027
|
+
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
1028
1028
|
else
|
1029
1029
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
|
1030
1030
|
end
|
@@ -1181,9 +1181,9 @@ module Steep
|
|
1181
1181
|
|
1182
1182
|
when :return
|
1183
1183
|
yield_self do
|
1184
|
-
|
1185
|
-
method_return_type = expand_alias(method_context&.return_type)
|
1184
|
+
method_return_type = expand_alias(method_context&.return_type)
|
1186
1185
|
|
1186
|
+
if node.children.size > 0
|
1187
1187
|
return_types = node.children.map do |value|
|
1188
1188
|
synthesize(
|
1189
1189
|
value,
|
@@ -1201,20 +1201,23 @@ module Steep
|
|
1201
1201
|
AST::Builtin::Array.instance_type(union_type(*return_types))
|
1202
1202
|
end
|
1203
1203
|
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1204
|
+
else
|
1205
|
+
value_type = AST::Builtin.nil_type
|
1206
|
+
end
|
1207
1207
|
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1208
|
+
if method_return_type
|
1209
|
+
unless method_return_type.is_a?(AST::Types::Void)
|
1210
|
+
result = check_relation(sub_type: value_type, super_type: method_return_type)
|
1211
|
+
|
1212
|
+
if result.failure?
|
1213
|
+
typing.add_error(
|
1214
|
+
Diagnostic::Ruby::ReturnTypeMismatch.new(
|
1215
|
+
node: node,
|
1216
|
+
expected: method_context&.return_type,
|
1217
|
+
actual: value_type,
|
1218
|
+
result: result
|
1216
1219
|
)
|
1217
|
-
|
1220
|
+
)
|
1218
1221
|
end
|
1219
1222
|
end
|
1220
1223
|
end
|
@@ -2724,20 +2727,22 @@ module Steep
|
|
2724
2727
|
end
|
2725
2728
|
end
|
2726
2729
|
|
2727
|
-
def type_lambda(node,
|
2730
|
+
def type_lambda(node, params_node:, body_node:, type_hint:)
|
2728
2731
|
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2729
|
-
params = TypeInference::BlockParams.from_node(
|
2732
|
+
params = TypeInference::BlockParams.from_node(params_node, annotations: block_annotations)
|
2730
2733
|
|
2731
2734
|
case type_hint
|
2732
2735
|
when AST::Types::Proc
|
2733
2736
|
params_hint = type_hint.type.params
|
2734
2737
|
return_hint = type_hint.type.return_type
|
2738
|
+
block_hint = type_hint.block
|
2735
2739
|
end
|
2736
2740
|
|
2737
2741
|
block_constr = for_block(
|
2738
2742
|
block_params: params,
|
2739
2743
|
block_param_hint: params_hint,
|
2740
2744
|
block_type_hint: return_hint,
|
2745
|
+
block_block_hint: block_hint,
|
2741
2746
|
block_annotations: block_annotations,
|
2742
2747
|
node_type_hint: nil
|
2743
2748
|
)
|
@@ -2748,10 +2753,30 @@ module Steep
|
|
2748
2753
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2749
2754
|
end
|
2750
2755
|
|
2751
|
-
|
2756
|
+
block =
|
2757
|
+
if block_param = params.block_param
|
2758
|
+
if block_param_type = block_param.type
|
2759
|
+
case block_param_type
|
2760
|
+
when AST::Types::Proc
|
2761
|
+
Interface::Block.new(type: block_param_type.type, optional: false)
|
2762
|
+
when AST::Types::Union
|
2763
|
+
if block_param_type.types.size == 2
|
2764
|
+
if block_param_type.types.find {|t| t.is_a?(AST::Types::Nil) }
|
2765
|
+
if proc_type = block_param_type.types.find {|t| t.is_a?(AST::Types::Proc) }
|
2766
|
+
Interface::Block.new(type: proc_type.type, optional: true)
|
2767
|
+
end
|
2768
|
+
end
|
2769
|
+
end
|
2770
|
+
end
|
2771
|
+
else
|
2772
|
+
type_hint.block
|
2773
|
+
end
|
2774
|
+
end
|
2775
|
+
|
2776
|
+
if body_node
|
2752
2777
|
return_type = block_constr.synthesize_block(
|
2753
2778
|
node: node,
|
2754
|
-
block_body:
|
2779
|
+
block_body: body_node,
|
2755
2780
|
block_type_hint: return_hint
|
2756
2781
|
)
|
2757
2782
|
|
@@ -2779,7 +2804,7 @@ module Steep
|
|
2779
2804
|
return_type: return_type,
|
2780
2805
|
location: nil
|
2781
2806
|
),
|
2782
|
-
block:
|
2807
|
+
block: block
|
2783
2808
|
)
|
2784
2809
|
|
2785
2810
|
add_typing node, type: block_type
|
@@ -3246,7 +3271,7 @@ module Steep
|
|
3246
3271
|
|
3247
3272
|
if method_type.block
|
3248
3273
|
# Method accepts block
|
3249
|
-
pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
|
3274
|
+
pairs = method_type.block && block_params_&.zip(method_type.block.type.params, nil)
|
3250
3275
|
|
3251
3276
|
if pairs
|
3252
3277
|
# Block parameters are compatible with the block type
|
@@ -3254,6 +3279,7 @@ module Steep
|
|
3254
3279
|
block_params: block_params_,
|
3255
3280
|
block_param_hint: method_type.block.type.params,
|
3256
3281
|
block_type_hint: method_type.block.type.return_type,
|
3282
|
+
block_block_hint: nil,
|
3257
3283
|
block_annotations: block_annotations,
|
3258
3284
|
node_type_hint: method_type.type.return_type
|
3259
3285
|
)
|
@@ -3503,13 +3529,14 @@ module Steep
|
|
3503
3529
|
message: "Unsupported block params pattern, probably masgn?"
|
3504
3530
|
)
|
3505
3531
|
)
|
3506
|
-
block_params = TypeInference::BlockParams.new(leading_params: [], optional_params: [], rest_param: nil, trailing_params: [])
|
3532
|
+
block_params = TypeInference::BlockParams.new(leading_params: [], optional_params: [], rest_param: nil, trailing_params: [], block_param: nil)
|
3507
3533
|
end
|
3508
3534
|
|
3509
3535
|
block_constr = for_block(
|
3510
3536
|
block_params: block_params,
|
3511
3537
|
block_param_hint: nil,
|
3512
3538
|
block_type_hint: AST::Builtin.any_type,
|
3539
|
+
block_block_hint: nil,
|
3513
3540
|
block_annotations: block_annotations,
|
3514
3541
|
node_type_hint: AST::Builtin.any_type
|
3515
3542
|
)
|
@@ -3536,8 +3563,8 @@ module Steep
|
|
3536
3563
|
end
|
3537
3564
|
end
|
3538
3565
|
|
3539
|
-
def for_block(block_params:, block_param_hint:, block_type_hint:, block_annotations:, node_type_hint:)
|
3540
|
-
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
3566
|
+
def for_block(block_params:, block_param_hint:, block_type_hint:, block_block_hint:, block_annotations:, node_type_hint:)
|
3567
|
+
block_param_pairs = block_param_hint && block_params.zip(block_param_hint, block_block_hint)
|
3541
3568
|
|
3542
3569
|
param_types_hash = {}
|
3543
3570
|
if block_param_pairs
|
@@ -29,12 +29,14 @@ module Steep
|
|
29
29
|
attr_reader :optional_params
|
30
30
|
attr_reader :rest_param
|
31
31
|
attr_reader :trailing_params
|
32
|
+
attr_reader :block_param
|
32
33
|
|
33
|
-
def initialize(leading_params:, optional_params:, rest_param:, trailing_params:)
|
34
|
+
def initialize(leading_params:, optional_params:, rest_param:, trailing_params:, block_param:)
|
34
35
|
@leading_params = leading_params
|
35
36
|
@optional_params = optional_params
|
36
37
|
@rest_param = rest_param
|
37
38
|
@trailing_params = trailing_params
|
39
|
+
@block_param = block_param
|
38
40
|
end
|
39
41
|
|
40
42
|
def params
|
@@ -43,6 +45,7 @@ module Steep
|
|
43
45
|
params.push(*optional_params)
|
44
46
|
params.push rest_param if rest_param
|
45
47
|
params.push(*trailing_params)
|
48
|
+
params.push(block_param) if block_param
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
@@ -51,6 +54,7 @@ module Steep
|
|
51
54
|
optional_params = []
|
52
55
|
rest_param = nil
|
53
56
|
trailing_params = []
|
57
|
+
block_param = nil
|
54
58
|
|
55
59
|
default_params = leading_params
|
56
60
|
|
@@ -72,6 +76,9 @@ module Steep
|
|
72
76
|
when :restarg
|
73
77
|
default_params = trailing_params
|
74
78
|
rest_param = Param.new(var: var, type: type, value: nil, node: arg)
|
79
|
+
when :blockarg
|
80
|
+
block_param = Param.new(var: var, type: type, value: nil, node: arg)
|
81
|
+
break
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
@@ -79,7 +86,8 @@ module Steep
|
|
79
86
|
leading_params: leading_params,
|
80
87
|
optional_params: optional_params,
|
81
88
|
rest_param: rest_param,
|
82
|
-
trailing_params: trailing_params
|
89
|
+
trailing_params: trailing_params,
|
90
|
+
block_param: block_param
|
83
91
|
)
|
84
92
|
end
|
85
93
|
|
@@ -141,7 +149,7 @@ module Steep
|
|
141
149
|
)
|
142
150
|
end
|
143
151
|
|
144
|
-
def zip(params_type)
|
152
|
+
def zip(params_type, block)
|
145
153
|
if trailing_params.any?
|
146
154
|
Steep.logger.error "Block definition with trailing required parameters are not supported yet"
|
147
155
|
end
|
@@ -204,6 +212,26 @@ module Steep
|
|
204
212
|
end
|
205
213
|
end
|
206
214
|
end
|
215
|
+
|
216
|
+
if block_param
|
217
|
+
if block
|
218
|
+
proc_type =
|
219
|
+
if block.optional?
|
220
|
+
AST::Types::Union.build(
|
221
|
+
types: [
|
222
|
+
AST::Types::Proc.new(type: block.type, block: nil),
|
223
|
+
AST::Builtin.nil_type
|
224
|
+
]
|
225
|
+
)
|
226
|
+
else
|
227
|
+
AST::Types::Proc.new(type: block.type, block: nil)
|
228
|
+
end
|
229
|
+
|
230
|
+
zip << [block_param, proc_type]
|
231
|
+
else
|
232
|
+
zip << [block_param, AST::Builtin.nil_type]
|
233
|
+
end
|
234
|
+
end
|
207
235
|
end
|
208
236
|
end
|
209
237
|
|
data/lib/steep/version.rb
CHANGED
data/smoke/tsort/a.rb
CHANGED
@@ -1,63 +1 @@
|
|
1
|
-
---
|
2
|
-
- file: a.rb
|
3
|
-
diagnostics:
|
4
|
-
- range:
|
5
|
-
start:
|
6
|
-
line: 7
|
7
|
-
character: 0
|
8
|
-
end:
|
9
|
-
line: 7
|
10
|
-
character: 38
|
11
|
-
severity: ERROR
|
12
|
-
message: |-
|
13
|
-
Cannot assign a value of type `^() -> ::Hash[::Integer, ::Array[::Integer]]` to a variable of type `^() { (::Integer) -> void } -> void`
|
14
|
-
^() -> ::Hash[::Integer, ::Array[::Integer]] <: ^() { (::Integer) -> void } -> void
|
15
|
-
code: Ruby::IncompatibleAssignment
|
16
|
-
- range:
|
17
|
-
start:
|
18
|
-
line: 7
|
19
|
-
character: 34
|
20
|
-
end:
|
21
|
-
line: 7
|
22
|
-
character: 35
|
23
|
-
severity: ERROR
|
24
|
-
message: Cannot detect the type of the expression
|
25
|
-
code: Ruby::FallbackAny
|
26
|
-
- range:
|
27
|
-
start:
|
28
|
-
line: 9
|
29
|
-
character: 0
|
30
|
-
end:
|
31
|
-
line: 9
|
32
|
-
character: 41
|
33
|
-
severity: ERROR
|
34
|
-
message: |-
|
35
|
-
Cannot assign a value of type `^(::Integer) -> ::Enumerator[::Integer, ::Array[::Integer]]` to a variable of type `^(::Integer) { (::Integer) -> void } -> void`
|
36
|
-
^(::Integer) -> ::Enumerator[::Integer, ::Array[::Integer]] <: ^(::Integer) { (::Integer) -> void } -> void
|
37
|
-
code: Ruby::IncompatibleAssignment
|
38
|
-
- range:
|
39
|
-
start:
|
40
|
-
line: 9
|
41
|
-
character: 37
|
42
|
-
end:
|
43
|
-
line: 9
|
44
|
-
character: 38
|
45
|
-
severity: ERROR
|
46
|
-
message: Cannot detect the type of the expression
|
47
|
-
code: Ruby::FallbackAny
|
48
|
-
- range:
|
49
|
-
start:
|
50
|
-
line: 12
|
51
|
-
character: 0
|
52
|
-
end:
|
53
|
-
line: 12
|
54
|
-
character: 39
|
55
|
-
severity: ERROR
|
56
|
-
message: |-
|
57
|
-
Cannot assign a value of type `::Array[::Integer]` to a variable of type `::Array[::String]`
|
58
|
-
::Array[::Integer] <: ::Array[::String]
|
59
|
-
::Integer <: ::String
|
60
|
-
::Numeric <: ::String
|
61
|
-
::Object <: ::String
|
62
|
-
::BasicObject <: ::String
|
63
|
-
code: Ruby::IncompatibleAssignment
|
1
|
+
--- []
|
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: 0.
|
4
|
+
version: 0.49.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|