steep 0.33.0 → 0.38.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 +28 -0
- data/lib/steep.rb +9 -0
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +167 -102
- data/lib/steep/ast/types/logic.rb +20 -1
- data/lib/steep/ast/types/proc.rb +32 -20
- data/lib/steep/cli.rb +15 -2
- data/lib/steep/drivers/print_project.rb +11 -0
- data/lib/steep/drivers/stats.rb +85 -0
- data/lib/steep/drivers/vendor.rb +1 -20
- data/lib/steep/errors.rb +38 -15
- data/lib/steep/index/rbs_index.rb +334 -0
- data/lib/steep/index/signature_symbol_provider.rb +154 -0
- data/lib/steep/index/source_index.rb +100 -0
- data/lib/steep/interface/block.rb +79 -0
- data/lib/steep/interface/function.rb +770 -0
- data/lib/steep/interface/method_type.rb +41 -832
- data/lib/steep/method_name.rb +28 -0
- data/lib/steep/project/completion_provider.rb +24 -15
- data/lib/steep/project/dsl.rb +13 -17
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/source_file.rb +2 -1
- data/lib/steep/project/target.rb +19 -10
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/master.rb +5 -1
- data/lib/steep/server/signature_worker.rb +63 -6
- data/lib/steep/subtyping/check.rb +70 -32
- data/lib/steep/subtyping/variable_occurrence.rb +4 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +780 -495
- data/lib/steep/type_inference/block_params.rb +1 -1
- data/lib/steep/type_inference/constant_env.rb +5 -1
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -0
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +46 -10
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/range.rb +5 -0
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/steep.gemspec +1 -1
- metadata +17 -6
@@ -10,12 +10,12 @@ module Steep
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def add_method_type(method_type)
|
13
|
-
method_type.params.each_type do |type|
|
13
|
+
method_type.type.params.each_type do |type|
|
14
14
|
each_var(type) do |var|
|
15
15
|
params << var
|
16
16
|
end
|
17
17
|
end
|
18
|
-
each_var(method_type.return_type) do |var|
|
18
|
+
each_var(method_type.type.return_type) do |var|
|
19
19
|
returns << var
|
20
20
|
end
|
21
21
|
|
@@ -29,6 +29,8 @@ module Steep
|
|
29
29
|
returns << var
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
params.subtract(returns)
|
32
34
|
end
|
33
35
|
|
34
36
|
def each_var(type, &block)
|
@@ -25,8 +25,8 @@ module Steep
|
|
25
25
|
covariants = Set.new
|
26
26
|
contravariants = Set.new
|
27
27
|
|
28
|
-
add_params(method_type.params, block: false, contravariants: contravariants, covariants: covariants)
|
29
|
-
add_type(method_type.return_type, variance: :covariant, covariants: covariants, contravariants: contravariants)
|
28
|
+
add_params(method_type.type.params, block: false, contravariants: contravariants, covariants: covariants)
|
29
|
+
add_type(method_type.type.return_type, variance: :covariant, covariants: covariants, contravariants: contravariants)
|
30
30
|
|
31
31
|
method_type.block&.type&.yield_self do |proc|
|
32
32
|
add_params(proc.params, block: true, contravariants: contravariants, covariants: covariants)
|
@@ -131,7 +131,7 @@ module Steep
|
|
131
131
|
definition_method_type = if definition
|
132
132
|
definition.methods[method_name]&.yield_self do |method|
|
133
133
|
method.method_types
|
134
|
-
.map {|method_type| checker.factory.method_type(method_type, self_type: self_type) }
|
134
|
+
.map {|method_type| checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]) }
|
135
135
|
.select {|method_type| method_type.is_a?(Interface::MethodType) }
|
136
136
|
.inject {|t1, t2| t1 + t2}
|
137
137
|
end
|
@@ -140,10 +140,10 @@ module Steep
|
|
140
140
|
|
141
141
|
method_type = annotation_method_type || definition_method_type
|
142
142
|
|
143
|
-
if annots&.return_type && method_type&.return_type
|
144
|
-
check_relation(sub_type: annots.return_type, super_type: method_type.return_type).else do |result|
|
143
|
+
if annots&.return_type && method_type&.type&.return_type
|
144
|
+
check_relation(sub_type: annots.return_type, super_type: method_type.type.return_type).else do |result|
|
145
145
|
typing.add_error Errors::MethodReturnTypeAnnotationMismatch.new(node: node,
|
146
|
-
method_type: method_type.return_type,
|
146
|
+
method_type: method_type.type.return_type,
|
147
147
|
annotation_type: annots.return_type,
|
148
148
|
result: result)
|
149
149
|
end
|
@@ -152,19 +152,18 @@ module Steep
|
|
152
152
|
# constructor_method = method&.attributes&.include?(:constructor)
|
153
153
|
|
154
154
|
if method_type
|
155
|
-
var_types = TypeConstruction.parameter_types(args, method_type)
|
156
|
-
unless TypeConstruction.valid_parameter_env?(var_types, args.reject {|arg| arg.type == :blockarg}, method_type.params)
|
155
|
+
var_types = TypeConstruction.parameter_types(args, method_type.type)
|
156
|
+
unless TypeConstruction.valid_parameter_env?(var_types, args.reject {|arg| arg.type == :blockarg}, method_type.type.params)
|
157
157
|
typing.add_error Errors::MethodArityMismatch.new(node: node)
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
161
|
if (block_arg = args.find {|arg| arg.type == :blockarg})
|
162
162
|
if method_type&.block
|
163
|
-
block_type =
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
end
|
163
|
+
block_type = AST::Types::Proc.new(type: method_type.block.type, block: nil)
|
164
|
+
if method_type.block.optional?
|
165
|
+
block_type = AST::Types::Union.build(types: [block_type, AST::Builtin.nil_type])
|
166
|
+
end
|
168
167
|
var_types[block_arg.children[0]] = block_type
|
169
168
|
end
|
170
169
|
end
|
@@ -183,7 +182,7 @@ module Steep
|
|
183
182
|
name: method_name,
|
184
183
|
method: definition && definition.methods[method_name],
|
185
184
|
method_type: method_type,
|
186
|
-
return_type: annots.return_type || method_type&.return_type || AST::Builtin.any_type,
|
185
|
+
return_type: annots.return_type || method_type&.type&.return_type || AST::Builtin.any_type,
|
187
186
|
constructor: false,
|
188
187
|
super_method: super_method
|
189
188
|
)
|
@@ -216,6 +215,21 @@ module Steep
|
|
216
215
|
|
217
216
|
lvar_env = lvar_env.annotate(annots)
|
218
217
|
|
218
|
+
call_context = case self_type
|
219
|
+
when nil
|
220
|
+
TypeInference::MethodCall::UnknownContext.new()
|
221
|
+
when AST::Types::Name::Singleton
|
222
|
+
TypeInference::MethodCall::MethodContext.new(
|
223
|
+
method_name: SingletonMethodName.new(type_name: module_context.class_name, method_name: method_name)
|
224
|
+
)
|
225
|
+
when AST::Types::Name::Instance, AST::Types::Intersection
|
226
|
+
TypeInference::MethodCall::MethodContext.new(
|
227
|
+
method_name: InstanceMethodName.new(type_name: module_context.class_name, method_name: method_name)
|
228
|
+
)
|
229
|
+
else
|
230
|
+
raise "Unexpected self_type: #{self_type}"
|
231
|
+
end
|
232
|
+
|
219
233
|
self.class.new(
|
220
234
|
checker: checker,
|
221
235
|
source: source,
|
@@ -227,7 +241,8 @@ module Steep
|
|
227
241
|
break_context: nil,
|
228
242
|
self_type: annots.self_type || self_type,
|
229
243
|
type_env: type_env,
|
230
|
-
lvar_env: lvar_env
|
244
|
+
lvar_env: lvar_env,
|
245
|
+
call_context: call_context
|
231
246
|
),
|
232
247
|
typing: typing,
|
233
248
|
)
|
@@ -355,7 +370,8 @@ module Steep
|
|
355
370
|
module_context: module_context_,
|
356
371
|
self_type: module_context_.module_type,
|
357
372
|
type_env: module_type_env,
|
358
|
-
lvar_env: lvar_env
|
373
|
+
lvar_env: lvar_env,
|
374
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context_.class_name)
|
359
375
|
)
|
360
376
|
)
|
361
377
|
end
|
@@ -424,7 +440,8 @@ module Steep
|
|
424
440
|
break_context: nil,
|
425
441
|
self_type: module_context.module_type,
|
426
442
|
type_env: class_type_env,
|
427
|
-
lvar_env: lvar_env
|
443
|
+
lvar_env: lvar_env,
|
444
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
|
428
445
|
)
|
429
446
|
|
430
447
|
self.class.new(
|
@@ -509,7 +526,8 @@ module Steep
|
|
509
526
|
break_context: nil,
|
510
527
|
self_type: module_context.module_type,
|
511
528
|
type_env: type_env,
|
512
|
-
lvar_env: lvar_env
|
529
|
+
lvar_env: lvar_env,
|
530
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
|
513
531
|
)
|
514
532
|
|
515
533
|
self.class.new(
|
@@ -608,6 +626,22 @@ module Steep
|
|
608
626
|
Pair.new(type: type, constr: constr)
|
609
627
|
end
|
610
628
|
|
629
|
+
def add_call(call)
|
630
|
+
case call
|
631
|
+
when TypeInference::MethodCall::NoMethodError
|
632
|
+
typing.add_error(call.error)
|
633
|
+
when TypeInference::MethodCall::Error
|
634
|
+
call.errors.each do |error|
|
635
|
+
typing.add_error(error)
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
typing.add_typing(call.node, call.return_type, nil)
|
640
|
+
typing.add_call(call.node, call)
|
641
|
+
|
642
|
+
Pair.new(type: call.return_type, constr: self)
|
643
|
+
end
|
644
|
+
|
611
645
|
def synthesize(node, hint: nil)
|
612
646
|
Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
|
613
647
|
Steep.logger.debug node.type
|
@@ -786,28 +820,33 @@ module Steep
|
|
786
820
|
when :super
|
787
821
|
yield_self do
|
788
822
|
if self_type && method_context&.method
|
789
|
-
if method_context.super_method
|
823
|
+
if super_def = method_context.super_method
|
790
824
|
each_child_node(node) do |child|
|
791
825
|
synthesize(child)
|
792
826
|
end
|
793
827
|
|
794
828
|
super_method = Interface::Interface::Entry.new(
|
795
829
|
method_types: method_context.super_method.method_types.map {|method_type|
|
796
|
-
|
830
|
+
decl = TypeInference::MethodCall::MethodDecl.new(
|
831
|
+
method_name: InstanceMethodName.new(type_name: super_def.implemented_in || super_def.defined_in,
|
832
|
+
method_name: method_context.name),
|
833
|
+
method_def: super_def
|
834
|
+
)
|
835
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[decl])
|
797
836
|
}
|
798
837
|
)
|
799
838
|
args = TypeInference::SendArgs.from_nodes(node.children.dup)
|
800
839
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
840
|
+
call, constr = type_method_call(node,
|
841
|
+
receiver_type: self_type,
|
842
|
+
method_name: method_context.name,
|
843
|
+
method: super_method,
|
844
|
+
args: args,
|
845
|
+
block_params: nil,
|
846
|
+
block_body: nil,
|
847
|
+
topdown_hint: true)
|
809
848
|
|
810
|
-
|
849
|
+
constr.add_call(call)
|
811
850
|
else
|
812
851
|
fallback_to_any node do
|
813
852
|
Errors::UnexpectedSuper.new(node: node, method: method_context.name)
|
@@ -973,22 +1012,30 @@ module Steep
|
|
973
1012
|
value = node.children[0]
|
974
1013
|
|
975
1014
|
if break_context
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
1015
|
+
if break_type = break_context.break_type
|
1016
|
+
if value
|
1017
|
+
check(value, break_type) do |break_type, actual_type, result|
|
1018
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1019
|
+
expected: break_type,
|
1020
|
+
actual: actual_type,
|
1021
|
+
result: result)
|
1022
|
+
end
|
1023
|
+
else
|
1024
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: break_type).else do |result|
|
1025
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1026
|
+
expected: break_type,
|
1027
|
+
actual: AST::Builtin.nil_type,
|
1028
|
+
result: result)
|
1029
|
+
end
|
983
1030
|
end
|
984
|
-
when !value
|
985
|
-
# ok
|
986
1031
|
else
|
987
|
-
|
988
|
-
|
1032
|
+
if value
|
1033
|
+
synthesize(value)
|
1034
|
+
typing.add_error Errors::UnexpectedJumpValue.new(node: node)
|
1035
|
+
end
|
989
1036
|
end
|
990
1037
|
else
|
991
|
-
synthesize(value)
|
1038
|
+
synthesize(value) if value
|
992
1039
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
993
1040
|
end
|
994
1041
|
|
@@ -998,22 +1045,32 @@ module Steep
|
|
998
1045
|
value = node.children[0]
|
999
1046
|
|
1000
1047
|
if break_context
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1048
|
+
if next_type = break_context.next_type
|
1049
|
+
next_type = deep_expand_alias(next_type)
|
1050
|
+
|
1051
|
+
if value
|
1052
|
+
_, constr = check(value, next_type) do |break_type, actual_type, result|
|
1053
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1054
|
+
expected: break_type,
|
1055
|
+
actual: actual_type,
|
1056
|
+
result: result)
|
1057
|
+
end
|
1058
|
+
else
|
1059
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: next_type).else do |result|
|
1060
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1061
|
+
expected: next_type,
|
1062
|
+
actual: AST::Builtin.nil_type,
|
1063
|
+
result: result)
|
1064
|
+
end
|
1008
1065
|
end
|
1009
|
-
when !value
|
1010
|
-
# ok
|
1011
1066
|
else
|
1012
|
-
|
1013
|
-
|
1067
|
+
if value
|
1068
|
+
synthesize(value)
|
1069
|
+
typing.add_error Errors::UnexpectedJumpValue.new(node: node)
|
1070
|
+
end
|
1014
1071
|
end
|
1015
1072
|
else
|
1016
|
-
synthesize(value)
|
1073
|
+
synthesize(value) if value
|
1017
1074
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
1018
1075
|
end
|
1019
1076
|
|
@@ -1208,10 +1265,35 @@ module Steep
|
|
1208
1265
|
|
1209
1266
|
when :class
|
1210
1267
|
yield_self do
|
1211
|
-
|
1268
|
+
constr = self
|
1269
|
+
|
1270
|
+
name, sup, _ = node.children
|
1271
|
+
if name.type == :const
|
1272
|
+
# skip the last constant reference
|
1273
|
+
if const_parent = name.children[0]
|
1274
|
+
_, constr = constr.synthesize(const_parent)
|
1275
|
+
end
|
1276
|
+
else
|
1277
|
+
_, constr = constr.synthesize(name)
|
1278
|
+
end
|
1279
|
+
_, constr = constr.synthesize(sup) if sup
|
1280
|
+
|
1281
|
+
constr.for_class(node).tap do |constructor|
|
1282
|
+
if module_type = constructor.module_context&.module_type
|
1283
|
+
_, constructor = constructor.add_typing(name, type: module_type)
|
1284
|
+
else
|
1285
|
+
_, constructor = constructor.fallback_to_any(name)
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
constructor.typing.source_index.add_definition(
|
1289
|
+
constant: constructor.module_context.class_name,
|
1290
|
+
definition: node
|
1291
|
+
)
|
1292
|
+
|
1212
1293
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1213
1294
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1214
1295
|
|
1296
|
+
constructor.synthesize(node.children[1]) if node.children[1]
|
1215
1297
|
constructor.synthesize(node.children[2]) if node.children[2]
|
1216
1298
|
|
1217
1299
|
if constructor.module_context&.implement_name && !namespace_module?(node)
|
@@ -1224,7 +1306,17 @@ module Steep
|
|
1224
1306
|
|
1225
1307
|
when :module
|
1226
1308
|
yield_self do
|
1309
|
+
constr = self
|
1310
|
+
|
1311
|
+
name, _ = node.children
|
1312
|
+
_, constr = constr.synthesize(name)
|
1313
|
+
|
1227
1314
|
for_module(node).yield_self do |constructor|
|
1315
|
+
constructor.typing.source_index.add_definition(
|
1316
|
+
constant: constructor.module_context.class_name,
|
1317
|
+
definition: node
|
1318
|
+
)
|
1319
|
+
|
1228
1320
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1229
1321
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1230
1322
|
|
@@ -1271,24 +1363,47 @@ module Steep
|
|
1271
1363
|
when :self
|
1272
1364
|
add_typing node, type: AST::Types::Self.new
|
1273
1365
|
|
1366
|
+
when :cbase
|
1367
|
+
add_typing node, type: AST::Types::Void.new
|
1368
|
+
|
1274
1369
|
when :const
|
1275
|
-
|
1370
|
+
parent = node.children[0]
|
1371
|
+
if parent
|
1372
|
+
_, constr = synthesize(parent)
|
1373
|
+
else
|
1374
|
+
constr = self
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
const_name = constr.module_name_from_node(node)
|
1276
1378
|
|
1277
1379
|
if const_name
|
1380
|
+
if constant = module_context.const_env.lookup_constant(const_name)
|
1381
|
+
typing.source_index.add_reference(constant: constant.name, ref: node)
|
1382
|
+
end
|
1383
|
+
|
1278
1384
|
type = type_env.get(const: const_name) do
|
1279
|
-
fallback_to_any
|
1385
|
+
constr.fallback_to_any(node)
|
1280
1386
|
end
|
1281
|
-
add_typing
|
1387
|
+
constr.add_typing(node, type: type)
|
1282
1388
|
else
|
1283
|
-
fallback_to_any
|
1389
|
+
constr.fallback_to_any(node)
|
1284
1390
|
end
|
1285
1391
|
|
1286
1392
|
when :casgn
|
1287
1393
|
yield_self do
|
1288
|
-
|
1394
|
+
constr = self
|
1395
|
+
|
1396
|
+
parent = node.children[0]
|
1397
|
+
_, constr = constr.synthesize(parent) if parent
|
1398
|
+
const_name = constr.module_name_from_node(node)
|
1399
|
+
|
1289
1400
|
if const_name
|
1401
|
+
if constant = module_context.const_env.lookup_constant(const_name)
|
1402
|
+
typing.source_index.add_definition(constant: constant.name, definition: node)
|
1403
|
+
end
|
1404
|
+
|
1290
1405
|
const_type = type_env.get(const: const_name) {}
|
1291
|
-
value_type = synthesize(node.children.last, hint: const_type)
|
1406
|
+
value_type, constr = constr.synthesize(node.children.last, hint: const_type)
|
1292
1407
|
type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
|
1293
1408
|
case error
|
1294
1409
|
when Subtyping::Result::Failure
|
@@ -1302,10 +1417,10 @@ module Steep
|
|
1302
1417
|
end
|
1303
1418
|
end
|
1304
1419
|
|
1305
|
-
add_typing(node, type: type)
|
1420
|
+
constr.add_typing(node, type: type)
|
1306
1421
|
else
|
1307
|
-
synthesize(node.children.last)
|
1308
|
-
fallback_to_any(node)
|
1422
|
+
_, constr = constr.synthesize(node.children.last)
|
1423
|
+
constr.fallback_to_any(node)
|
1309
1424
|
end
|
1310
1425
|
end
|
1311
1426
|
|
@@ -1338,7 +1453,7 @@ module Steep
|
|
1338
1453
|
if method_context&.method
|
1339
1454
|
if method_context.super_method
|
1340
1455
|
types = method_context.super_method.method_types.map {|method_type|
|
1341
|
-
checker.factory.method_type(method_type, self_type: self_type).return_type
|
1456
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]).type.return_type
|
1342
1457
|
}
|
1343
1458
|
add_typing(node, type: union_type(*types))
|
1344
1459
|
else
|
@@ -1410,7 +1525,18 @@ module Steep
|
|
1410
1525
|
.for_branch(right)
|
1411
1526
|
.synthesize(right)
|
1412
1527
|
|
1413
|
-
|
1528
|
+
truthy_env, _ = interpreter.eval(env: truthy_env, type: right_type, node: right)
|
1529
|
+
|
1530
|
+
env = if right_type.is_a?(AST::Types::Bot)
|
1531
|
+
falsey_env
|
1532
|
+
else
|
1533
|
+
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1534
|
+
end
|
1535
|
+
|
1536
|
+
type = case
|
1537
|
+
when left_type.is_a?(AST::Types::Logic::Base) && right_type.is_a?(AST::Types::Logic::Base)
|
1538
|
+
AST::Types::Logic::Env.new(truthy: truthy_env, falsy: env)
|
1539
|
+
when check_relation(sub_type: left_type, super_type: AST::Types::Boolean.new).success?
|
1414
1540
|
union_type(left_type, right_type)
|
1415
1541
|
else
|
1416
1542
|
union_type(right_type, AST::Builtin.nil_type)
|
@@ -1418,13 +1544,7 @@ module Steep
|
|
1418
1544
|
|
1419
1545
|
add_typing(node,
|
1420
1546
|
type: type,
|
1421
|
-
constr: constr.update_lvar_env
|
1422
|
-
if right_type.is_a?(AST::Types::Bot)
|
1423
|
-
falsey_env
|
1424
|
-
else
|
1425
|
-
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1426
|
-
end
|
1427
|
-
end)
|
1547
|
+
constr: constr.update_lvar_env { env })
|
1428
1548
|
end
|
1429
1549
|
|
1430
1550
|
when :or
|
@@ -1436,24 +1556,31 @@ module Steep
|
|
1436
1556
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1437
1557
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1438
1558
|
|
1439
|
-
|
1559
|
+
left_type, _ = checker.factory.unwrap_optional(left_type)
|
1440
1560
|
right_type, constr = constr
|
1441
1561
|
.update_lvar_env { falsey_env }
|
1442
1562
|
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1443
1563
|
.for_branch(right)
|
1444
|
-
.synthesize(right, hint:
|
1564
|
+
.synthesize(right, hint: left_type)
|
1565
|
+
|
1566
|
+
_, falsey_env = interpreter.eval(env: falsey_env, type: right_type, node: right)
|
1567
|
+
|
1568
|
+
env = if right_type.is_a?(AST::Types::Bot)
|
1569
|
+
truthy_env
|
1570
|
+
else
|
1571
|
+
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1572
|
+
end
|
1445
1573
|
|
1446
|
-
type =
|
1574
|
+
type = case
|
1575
|
+
when left_type.is_a?(AST::Types::Logic::Base) && right_type.is_a?(AST::Types::Logic::Base)
|
1576
|
+
AST::Types::Logic::Env.new(truthy: env, falsy: falsey_env)
|
1577
|
+
else
|
1578
|
+
union_type(left_type, right_type)
|
1579
|
+
end
|
1447
1580
|
|
1448
1581
|
add_typing(node,
|
1449
1582
|
type: type,
|
1450
|
-
constr: constr.update_lvar_env
|
1451
|
-
if right_type.is_a?(AST::Types::Bot)
|
1452
|
-
truthy_env
|
1453
|
-
else
|
1454
|
-
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1455
|
-
end
|
1456
|
-
end)
|
1583
|
+
constr: constr.update_lvar_env { env })
|
1457
1584
|
end
|
1458
1585
|
|
1459
1586
|
when :if
|
@@ -1518,6 +1645,18 @@ module Steep
|
|
1518
1645
|
|
1519
1646
|
cond_type, constr = constr.synthesize(cond)
|
1520
1647
|
_, cond_vars = interpreter.decompose_value(cond)
|
1648
|
+
unless cond_vars.empty?
|
1649
|
+
first_var = cond_vars.to_a[0]
|
1650
|
+
var_node = cond.updated(
|
1651
|
+
:lvar,
|
1652
|
+
[
|
1653
|
+
ASTUtils::Labeling::LabeledName.new(name: first_var, label: 0)
|
1654
|
+
]
|
1655
|
+
)
|
1656
|
+
else
|
1657
|
+
first_var = nil
|
1658
|
+
var_node = cond
|
1659
|
+
end
|
1521
1660
|
|
1522
1661
|
when_constr = constr
|
1523
1662
|
whens.each do |clause|
|
@@ -1527,9 +1666,15 @@ module Steep
|
|
1527
1666
|
test_envs = []
|
1528
1667
|
|
1529
1668
|
tests.each do |test|
|
1530
|
-
test_node = test.updated(:send, [test, :===,
|
1669
|
+
test_node = test.updated(:send, [test, :===, var_node])
|
1531
1670
|
test_type, test_constr = test_constr.synthesize(test_node)
|
1532
1671
|
truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
|
1672
|
+
truthy_env = cond_vars.inject(truthy_env) do |env, var|
|
1673
|
+
env.assign!(var, node: test_node, type: env[first_var])
|
1674
|
+
end
|
1675
|
+
falsy_env = cond_vars.inject(falsy_env) do |env, var|
|
1676
|
+
env.assign!(var, node: test_node, type: env[first_var])
|
1677
|
+
end
|
1533
1678
|
test_envs << truthy_env
|
1534
1679
|
test_constr = test_constr.update_lvar_env { falsy_env }
|
1535
1680
|
end
|
@@ -1559,10 +1704,6 @@ module Steep
|
|
1559
1704
|
types = branch_pairs.map(&:type)
|
1560
1705
|
constrs = branch_pairs.map(&:constr)
|
1561
1706
|
|
1562
|
-
unless els
|
1563
|
-
constrs << when_constr
|
1564
|
-
end
|
1565
|
-
|
1566
1707
|
if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
|
1567
1708
|
# Exhaustive
|
1568
1709
|
if els
|
@@ -1570,6 +1711,7 @@ module Steep
|
|
1570
1711
|
end
|
1571
1712
|
else
|
1572
1713
|
unless els
|
1714
|
+
constrs << when_constr
|
1573
1715
|
types << AST::Builtin.nil_type
|
1574
1716
|
end
|
1575
1717
|
end
|
@@ -1929,17 +2071,25 @@ module Steep
|
|
1929
2071
|
if hint.is_a?(AST::Types::Proc) && value.type == :sym
|
1930
2072
|
if hint.one_arg?
|
1931
2073
|
# Assumes Symbol#to_proc implementation
|
1932
|
-
param_type = hint.params.required[0]
|
2074
|
+
param_type = hint.type.params.required[0]
|
1933
2075
|
interface = checker.factory.interface(param_type, private: true)
|
1934
2076
|
method = interface.methods[value.children[0]]
|
1935
2077
|
if method
|
1936
2078
|
return_types = method.method_types.select {|method_type|
|
1937
|
-
method_type.params.
|
1938
|
-
}.map
|
2079
|
+
method_type.type.params.empty?
|
2080
|
+
}.map {|method_type|
|
2081
|
+
method_type.type.return_type
|
2082
|
+
}
|
1939
2083
|
|
1940
2084
|
unless return_types.empty?
|
1941
|
-
type = AST::Types::Proc.new(
|
1942
|
-
|
2085
|
+
type = AST::Types::Proc.new(
|
2086
|
+
type: Interface::Function.new(
|
2087
|
+
params: Interface::Function::Params.empty.update(required: [param_type]),
|
2088
|
+
return_type: AST::Types::Union.build(types: return_types),
|
2089
|
+
location: nil
|
2090
|
+
),
|
2091
|
+
block: nil
|
2092
|
+
)
|
1943
2093
|
end
|
1944
2094
|
end
|
1945
2095
|
else
|
@@ -2029,7 +2179,7 @@ module Steep
|
|
2029
2179
|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
2030
2180
|
# Steep.logger.error { "result = #{pair.inspect}" }
|
2031
2181
|
# Steep.logger.error { "node = #{node.type}" }
|
2032
|
-
raise "#synthesize should return an instance of Pair: #{pair.class}"
|
2182
|
+
raise "#synthesize should return an instance of Pair: #{pair.class}, node=#{node.inspect}"
|
2033
2183
|
end
|
2034
2184
|
end
|
2035
2185
|
end
|
@@ -2269,181 +2419,244 @@ module Steep
|
|
2269
2419
|
|
2270
2420
|
case type_hint
|
2271
2421
|
when AST::Types::Proc
|
2272
|
-
params_hint = type_hint.params
|
2273
|
-
return_hint = type_hint.return_type
|
2422
|
+
params_hint = type_hint.type.params
|
2423
|
+
return_hint = type_hint.type.return_type
|
2274
2424
|
end
|
2275
2425
|
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2283
|
-
topdown_hint: true)
|
2426
|
+
block_constr = for_block(
|
2427
|
+
block_params: params,
|
2428
|
+
block_param_hint: params_hint,
|
2429
|
+
block_type_hint: return_hint,
|
2430
|
+
block_annotations: block_annotations,
|
2431
|
+
node_type_hint: nil
|
2432
|
+
)
|
2284
2433
|
|
2285
|
-
|
2286
|
-
end
|
2434
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2287
2435
|
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2436
|
+
params.params.each do |param|
|
2437
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2438
|
+
end
|
2291
2439
|
|
2292
|
-
if
|
2293
|
-
|
2440
|
+
if block_body
|
2441
|
+
return_type = block_constr.synthesize_block(
|
2442
|
+
node: node,
|
2443
|
+
block_body: block_body,
|
2444
|
+
block_type_hint: return_hint
|
2445
|
+
)
|
2446
|
+
|
2447
|
+
if expected_block_type = block_constr.block_context.body_type
|
2448
|
+
check_relation(sub_type: return_type, super_type: expected_block_type).else do |result|
|
2449
|
+
block_constr.typing.add_error(
|
2450
|
+
Errors::BlockBodyTypeMismatch.new(
|
2451
|
+
node: block_body,
|
2452
|
+
expected: expected_block_type,
|
2453
|
+
actual: return_type,
|
2454
|
+
result: result
|
2455
|
+
)
|
2456
|
+
)
|
2457
|
+
|
2458
|
+
return_type = expected_block_type
|
2459
|
+
end
|
2460
|
+
end
|
2461
|
+
else
|
2462
|
+
return_type = AST::Builtin.any_type
|
2294
2463
|
end
|
2295
2464
|
|
2296
|
-
|
2465
|
+
block_type = AST::Types::Proc.new(
|
2466
|
+
type: Interface::Function.new(
|
2467
|
+
params: params_hint || params.params_type,
|
2468
|
+
return_type: return_type,
|
2469
|
+
location: nil
|
2470
|
+
),
|
2471
|
+
block: nil
|
2472
|
+
)
|
2297
2473
|
|
2298
|
-
|
2299
|
-
|
2300
|
-
each_child_node(send_node) do |child|
|
2301
|
-
unless child.equal?(receiver)
|
2302
|
-
_, constr = constr.synthesize(child)
|
2303
|
-
end
|
2304
|
-
end
|
2474
|
+
add_typing node, type: block_type
|
2475
|
+
end
|
2305
2476
|
|
2306
|
-
|
2477
|
+
def synthesize_children(node, skips: [])
|
2478
|
+
skips = Set.new.compare_by_identity.merge(skips)
|
2307
2479
|
|
2308
|
-
|
2309
|
-
fallback_to_any node
|
2480
|
+
constr = self
|
2310
2481
|
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2482
|
+
each_child_node(node) do |child|
|
2483
|
+
unless skips.include?(child)
|
2484
|
+
_, constr = constr.synthesize(child)
|
2485
|
+
end
|
2486
|
+
end
|
2315
2487
|
|
2316
|
-
|
2317
|
-
|
2318
|
-
when AST::Types::Self
|
2319
|
-
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2320
|
-
fallback_to_any node do
|
2321
|
-
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2322
|
-
end
|
2323
|
-
else
|
2324
|
-
begin
|
2325
|
-
interface = checker.factory.interface(receiver_type,
|
2326
|
-
private: !receiver,
|
2327
|
-
self_type: expanded_receiver_type)
|
2328
|
-
|
2329
|
-
method = interface.methods[method_name]
|
2330
|
-
|
2331
|
-
if method
|
2332
|
-
args = TypeInference::SendArgs.from_nodes(arguments)
|
2333
|
-
return_type, constr, _ = constr.type_method_call(node,
|
2334
|
-
method: method,
|
2335
|
-
method_name: method_name,
|
2336
|
-
args: args,
|
2337
|
-
block_params: block_params,
|
2338
|
-
block_body: block_body,
|
2339
|
-
receiver_type: receiver_type,
|
2340
|
-
topdown_hint: true)
|
2341
|
-
|
2342
|
-
add_typing node, type: return_type, constr: constr
|
2343
|
-
else
|
2344
|
-
fallback_to_any node do
|
2345
|
-
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
2346
|
-
end
|
2347
|
-
end
|
2348
|
-
rescue => exn
|
2349
|
-
case exn
|
2350
|
-
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2351
|
-
# ignore known RBS errors.
|
2352
|
-
else
|
2353
|
-
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2354
|
-
end
|
2488
|
+
constr
|
2489
|
+
end
|
2355
2490
|
|
2356
|
-
|
2357
|
-
|
2358
|
-
end
|
2359
|
-
end
|
2360
|
-
end
|
2361
|
-
end
|
2491
|
+
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:)
|
2492
|
+
method = interface.methods[method_name]
|
2362
2493
|
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2494
|
+
if method
|
2495
|
+
args = TypeInference::SendArgs.from_nodes(arguments)
|
2496
|
+
call, constr = type_method_call(node,
|
2497
|
+
method: method,
|
2498
|
+
method_name: method_name,
|
2499
|
+
args: args,
|
2500
|
+
block_params: block_params,
|
2501
|
+
block_body: block_body,
|
2502
|
+
receiver_type: receiver_type,
|
2503
|
+
topdown_hint: true)
|
2504
|
+
|
2505
|
+
if call && constr
|
2506
|
+
case method_name.to_s
|
2507
|
+
when "[]=", /\w=\Z/
|
2508
|
+
if typing.has_type?(arguments.last)
|
2509
|
+
call = call.with_return_type(typing.type_of(node: arguments.last))
|
2372
2510
|
end
|
2373
2511
|
end
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2512
|
+
else
|
2513
|
+
error = Errors::UnresolvedOverloading.new(
|
2514
|
+
node: node,
|
2515
|
+
receiver_type: receiver_type,
|
2516
|
+
method_name: method_name,
|
2517
|
+
method_types: method.method_types
|
2518
|
+
)
|
2519
|
+
call = TypeInference::MethodCall::Error.new(
|
2520
|
+
node: node,
|
2521
|
+
context: context.method_context,
|
2522
|
+
method_name: method_name,
|
2523
|
+
receiver_type: receiver_type,
|
2524
|
+
errors: [error]
|
2525
|
+
)
|
2381
2526
|
|
2382
|
-
|
2383
|
-
|
2384
|
-
method_return_type: AST::Builtin.any_type,
|
2385
|
-
typing: typing)
|
2527
|
+
skips = [receiver]
|
2528
|
+
skips << node.children[0] if node.type == :block
|
2386
2529
|
|
2387
|
-
|
2530
|
+
constr = synthesize_children(node, skips: skips)
|
2531
|
+
if block_params
|
2532
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2388
2533
|
|
2389
|
-
|
2534
|
+
constr.type_block_without_hint(
|
2535
|
+
node: node,
|
2536
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2537
|
+
block_annotations: block_annotations,
|
2538
|
+
block_body: block_body
|
2539
|
+
)
|
2390
2540
|
end
|
2391
2541
|
end
|
2542
|
+
|
2543
|
+
constr.add_call(call)
|
2392
2544
|
else
|
2393
|
-
|
2545
|
+
add_call(
|
2546
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2547
|
+
node: node,
|
2548
|
+
context: context.method_context,
|
2549
|
+
method_name: method_name,
|
2550
|
+
receiver_type: receiver_type,
|
2551
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2552
|
+
)
|
2553
|
+
)
|
2394
2554
|
end
|
2395
2555
|
end
|
2396
2556
|
|
2397
|
-
def
|
2398
|
-
|
2399
|
-
|
2400
|
-
if param.type
|
2401
|
-
env.set(lvar: param.var.name, type: param.type)
|
2402
|
-
else
|
2403
|
-
env.set(lvar: param.var.name, type: type)
|
2404
|
-
end
|
2405
|
-
end
|
2557
|
+
def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
|
2558
|
+
receiver, method_name, *arguments = send_node.children
|
2559
|
+
recv_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
|
2406
2560
|
|
2407
|
-
|
2408
|
-
|
2409
|
-
ivar_types: block_annotations.ivar_types,
|
2410
|
-
const_types: block_annotations.const_types,
|
2411
|
-
)
|
2561
|
+
if unwrap
|
2562
|
+
recv_type = unwrap(recv_type)
|
2412
2563
|
end
|
2413
2564
|
|
2414
|
-
|
2565
|
+
receiver_type = checker.factory.deep_expand_alias(recv_type)
|
2415
2566
|
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
method_return_type
|
2420
|
-
end
|
2421
|
-
Steep.logger.debug("return_type = #{return_type}")
|
2567
|
+
type, constr = case receiver_type
|
2568
|
+
when nil
|
2569
|
+
raise
|
2422
2570
|
|
2423
|
-
|
2424
|
-
|
2571
|
+
when AST::Types::Any
|
2572
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2573
|
+
constr.add_call(
|
2574
|
+
TypeInference::MethodCall::Untyped.new(
|
2575
|
+
node: node,
|
2576
|
+
context: context.method_context,
|
2577
|
+
method_name: method_name
|
2578
|
+
)
|
2579
|
+
)
|
2425
2580
|
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2581
|
+
when AST::Types::Void, AST::Types::Bot, AST::Types::Top, AST::Types::Var
|
2582
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2583
|
+
constr.add_call(
|
2584
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2585
|
+
node: node,
|
2586
|
+
context: context.method_context,
|
2587
|
+
method_name: method_name,
|
2588
|
+
receiver_type: receiver_type,
|
2589
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2590
|
+
)
|
2591
|
+
)
|
2431
2592
|
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
2438
|
-
|
2439
|
-
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2593
|
+
when AST::Types::Self
|
2594
|
+
expanded_self = expand_self(receiver_type)
|
2595
|
+
|
2596
|
+
if expanded_self.is_a?(AST::Types::Self)
|
2597
|
+
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2598
|
+
|
2599
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2600
|
+
constr.add_call(
|
2601
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2602
|
+
node: node,
|
2603
|
+
context: context.method_context,
|
2604
|
+
method_name: method_name,
|
2605
|
+
receiver_type: receiver_type,
|
2606
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2607
|
+
)
|
2608
|
+
)
|
2609
|
+
else
|
2610
|
+
interface = checker.factory.interface(expanded_self,
|
2611
|
+
private: !receiver,
|
2612
|
+
self_type: AST::Types::Self.new)
|
2613
|
+
|
2614
|
+
constr.type_send_interface(node,
|
2615
|
+
interface: interface,
|
2616
|
+
receiver: receiver,
|
2617
|
+
receiver_type: expanded_self,
|
2618
|
+
method_name: method_name,
|
2619
|
+
arguments: arguments,
|
2620
|
+
block_params: block_params,
|
2621
|
+
block_body: block_body)
|
2622
|
+
end
|
2623
|
+
else
|
2624
|
+
interface = checker.factory.interface(receiver_type,
|
2625
|
+
private: !receiver,
|
2626
|
+
self_type: receiver_type)
|
2627
|
+
|
2628
|
+
constr.type_send_interface(node,
|
2629
|
+
interface: interface,
|
2630
|
+
receiver: receiver,
|
2631
|
+
receiver_type: receiver_type,
|
2632
|
+
method_name: method_name,
|
2633
|
+
arguments: arguments,
|
2634
|
+
block_params: block_params,
|
2635
|
+
block_body: block_body)
|
2636
|
+
end
|
2637
|
+
|
2638
|
+
Pair.new(type: type, constr: constr)
|
2639
|
+
rescue => exn
|
2640
|
+
case exn
|
2641
|
+
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2642
|
+
# ignore known RBS errors.
|
2643
|
+
else
|
2644
|
+
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2645
|
+
end
|
2646
|
+
|
2647
|
+
error = Errors::UnexpectedError.new(node: node, error: exn)
|
2648
|
+
|
2649
|
+
type_any_rec(node)
|
2650
|
+
|
2651
|
+
add_call(
|
2652
|
+
TypeInference::MethodCall::Error.new(
|
2653
|
+
node: node,
|
2654
|
+
context: context.method_context,
|
2655
|
+
method_name: method_name,
|
2656
|
+
receiver_type: receiver_type,
|
2657
|
+
errors: [error]
|
2445
2658
|
)
|
2446
|
-
)
|
2659
|
+
)
|
2447
2660
|
end
|
2448
2661
|
|
2449
2662
|
def expand_self(type)
|
@@ -2459,71 +2672,62 @@ module Steep
|
|
2459
2672
|
|
2460
2673
|
results = method.method_types.flat_map do |method_type|
|
2461
2674
|
Steep.logger.tagged method_type.to_s do
|
2462
|
-
zips = args.zips(method_type.params, method_type.block&.type)
|
2675
|
+
zips = args.zips(method_type.type.params, method_type.block&.type)
|
2463
2676
|
|
2464
2677
|
zips.map do |arg_pairs|
|
2465
2678
|
typing.new_child(node_range) do |child_typing|
|
2466
|
-
|
2679
|
+
self.with_new_typing(child_typing).try_method_type(
|
2467
2680
|
node,
|
2468
2681
|
receiver_type: receiver_type,
|
2682
|
+
method_name: method_name,
|
2469
2683
|
method_type: method_type,
|
2470
2684
|
args: args,
|
2471
2685
|
arg_pairs: arg_pairs,
|
2472
2686
|
block_params: block_params,
|
2473
2687
|
block_body: block_body,
|
2474
|
-
child_typing: child_typing,
|
2475
2688
|
topdown_hint: topdown_hint
|
2476
2689
|
)
|
2477
|
-
|
2478
|
-
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
2479
|
-
|
2480
|
-
result, constr = ret
|
2481
|
-
|
2482
|
-
[result, constr, method_type]
|
2483
2690
|
end
|
2484
2691
|
end
|
2485
2692
|
end
|
2486
2693
|
end
|
2487
2694
|
|
2488
|
-
|
2489
|
-
|
2490
|
-
else
|
2695
|
+
case
|
2696
|
+
when results.empty?
|
2491
2697
|
method_type = method.method_types.last
|
2698
|
+
all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
|
2699
|
+
set.merge(method_type.method_decls)
|
2700
|
+
end
|
2701
|
+
error = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2702
|
+
call = TypeInference::MethodCall::Error.new(
|
2703
|
+
node: node,
|
2704
|
+
context: context.method_context,
|
2705
|
+
method_name: method_name,
|
2706
|
+
receiver_type: receiver_type,
|
2707
|
+
return_type: method_type.type.return_type,
|
2708
|
+
errors: [error],
|
2709
|
+
method_decls: all_decls
|
2710
|
+
)
|
2492
2711
|
constr = self.with_new_typing(typing.new_child(node_range))
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
when Errors::Base
|
2499
|
-
if method.method_types.size == 1
|
2500
|
-
typing.add_error result
|
2501
|
-
type = case method_type.return_type
|
2502
|
-
when AST::Types::Var
|
2503
|
-
AST::Builtin.any_type
|
2504
|
-
else
|
2505
|
-
method_type.return_type
|
2506
|
-
end
|
2712
|
+
when (call, constr = results.find {|call, _| call.is_a?(TypeInference::MethodCall::Typed) })
|
2713
|
+
# Nop
|
2714
|
+
else
|
2715
|
+
if results.one?
|
2716
|
+
call, constr = results[0]
|
2507
2717
|
else
|
2508
|
-
|
2509
|
-
receiver_type: expand_self(receiver_type),
|
2510
|
-
method_name: method_name,
|
2511
|
-
method_types: method.method_types)
|
2512
|
-
type = AST::Builtin.any_type
|
2718
|
+
return
|
2513
2719
|
end
|
2514
|
-
|
2515
|
-
[type,
|
2516
|
-
update_lvar_env { constr.context.lvar_env },
|
2517
|
-
result]
|
2518
|
-
else # Type
|
2519
|
-
[result,
|
2520
|
-
update_lvar_env { constr.context.lvar_env },
|
2521
|
-
nil]
|
2522
2720
|
end
|
2721
|
+
constr.typing.save!
|
2722
|
+
|
2723
|
+
[
|
2724
|
+
call,
|
2725
|
+
update_lvar_env { constr.context.lvar_env }
|
2726
|
+
]
|
2523
2727
|
end
|
2524
2728
|
|
2525
2729
|
def check_keyword_arg(receiver_type:, node:, method_type:, constraints:)
|
2526
|
-
params = method_type.params
|
2730
|
+
params = method_type.type.params
|
2527
2731
|
|
2528
2732
|
case node.type
|
2529
2733
|
when :hash
|
@@ -2621,14 +2825,12 @@ module Steep
|
|
2621
2825
|
|
2622
2826
|
hash_type = AST::Builtin::Hash.instance_type(
|
2623
2827
|
AST::Builtin::Symbol.instance_type,
|
2624
|
-
AST::Types::Union.build(types: value_types
|
2625
|
-
location: method_type.location)
|
2828
|
+
AST::Types::Union.build(types: value_types)
|
2626
2829
|
)
|
2627
2830
|
else
|
2628
2831
|
hash_elements = params.required_keywords.merge(
|
2629
|
-
|
2630
|
-
AST::Types::Union.build(types: [type, AST::Builtin.nil_type]
|
2631
|
-
location: method_type.location)
|
2832
|
+
params.optional_keywords.transform_values do |type|
|
2833
|
+
AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2632
2834
|
end
|
2633
2835
|
)
|
2634
2836
|
|
@@ -2650,226 +2852,311 @@ module Steep
|
|
2650
2852
|
nil
|
2651
2853
|
end
|
2652
2854
|
|
2653
|
-
def try_method_type(node, receiver_type:, method_type:, args:, arg_pairs:, block_params:, block_body:,
|
2855
|
+
def try_method_type(node, receiver_type:, method_name:, method_type:, args:, arg_pairs:, block_params:, block_body:, topdown_hint:)
|
2654
2856
|
fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x)}
|
2655
2857
|
fresh_vars = Set.new(fresh_types.map(&:name))
|
2656
2858
|
instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
|
2657
2859
|
|
2658
|
-
|
2659
|
-
checker: checker,
|
2660
|
-
source: source,
|
2661
|
-
annotations: annotations,
|
2662
|
-
typing: child_typing,
|
2663
|
-
context: context
|
2664
|
-
)
|
2860
|
+
constr = self
|
2665
2861
|
|
2666
|
-
|
2862
|
+
method_type = method_type.instantiate(instantiation)
|
2667
2863
|
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2671
|
-
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
2864
|
+
constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
|
2865
|
+
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
2866
|
+
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
2672
2867
|
|
2673
|
-
|
2674
|
-
case pair
|
2675
|
-
when Array
|
2676
|
-
(arg_node, param_type) = pair
|
2677
|
-
param_type = param_type.subst(instantiation)
|
2868
|
+
errors = []
|
2678
2869
|
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
|
2870
|
+
arg_pairs.each do |pair|
|
2871
|
+
case pair
|
2872
|
+
when Array
|
2873
|
+
arg_node, param_type = pair
|
2874
|
+
param_type = param_type.subst(instantiation)
|
2684
2875
|
|
2685
|
-
|
2686
|
-
|
2876
|
+
arg_type, constr = if arg_node.type == :splat
|
2877
|
+
constr.synthesize(arg_node.children[0])
|
2878
|
+
else
|
2879
|
+
constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
|
2880
|
+
end
|
2881
|
+
|
2882
|
+
check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do
|
2883
|
+
errors << Errors::ArgumentTypeMismatch.new(node: arg_node,
|
2687
2884
|
receiver_type: receiver_type,
|
2688
2885
|
expected: param_type,
|
2689
|
-
actual: arg_type)
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
constraints: constraints)
|
2886
|
+
actual: arg_type)
|
2887
|
+
end
|
2888
|
+
else
|
2889
|
+
# keyword
|
2890
|
+
result = constr.check_keyword_arg(receiver_type: receiver_type,
|
2891
|
+
node: pair,
|
2892
|
+
method_type: method_type,
|
2893
|
+
constraints: constraints)
|
2698
2894
|
|
2699
|
-
|
2700
|
-
|
2701
|
-
end
|
2895
|
+
if result.is_a?(Errors::Base)
|
2896
|
+
errors << result
|
2702
2897
|
end
|
2703
2898
|
end
|
2899
|
+
end
|
2704
2900
|
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
constr
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2901
|
+
if block_params
|
2902
|
+
# block is given
|
2903
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2904
|
+
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
2905
|
+
|
2906
|
+
if method_type.block
|
2907
|
+
pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
|
2908
|
+
|
2909
|
+
if pairs
|
2910
|
+
begin
|
2911
|
+
block_constr = constr.for_block(
|
2912
|
+
block_params: block_params_,
|
2913
|
+
block_param_hint: method_type.block.type.params,
|
2914
|
+
block_type_hint: method_type.block.type.return_type,
|
2915
|
+
block_annotations: block_annotations,
|
2916
|
+
node_type_hint: method_type.type.return_type
|
2917
|
+
)
|
2918
|
+
block_constr = block_constr.with_new_typing(
|
2919
|
+
block_constr.typing.new_child(
|
2920
|
+
range: block_constr.typing.block_range(node)
|
2921
|
+
)
|
2922
|
+
)
|
2923
|
+
|
2924
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2925
|
+
|
2926
|
+
pairs.each do |param, type|
|
2927
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
|
2928
|
+
|
2929
|
+
if param.type
|
2930
|
+
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
2931
|
+
error = Errors::IncompatibleAssignment.new(
|
2932
|
+
node: param.node,
|
2933
|
+
lhs_type: param.type,
|
2934
|
+
rhs_type: type,
|
2935
|
+
result: result
|
2936
|
+
)
|
2937
|
+
errors << error
|
2938
|
+
end
|
2939
|
+
end
|
2740
2940
|
end
|
2741
|
-
end
|
2742
|
-
end
|
2743
|
-
end
|
2744
2941
|
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2942
|
+
s = constraints.solution(
|
2943
|
+
checker,
|
2944
|
+
self_type: self_type,
|
2945
|
+
variance: variance,
|
2946
|
+
variables: method_type.type.params.free_variables + method_type.block.type.params.free_variables
|
2947
|
+
)
|
2948
|
+
method_type = method_type.subst(s)
|
2949
|
+
block_constr = block_constr.update_lvar_env {|env| env.subst(s) }
|
2950
|
+
if block_body
|
2951
|
+
block_body_type = block_constr.synthesize_block(
|
2952
|
+
node: node,
|
2953
|
+
block_body: block_body,
|
2954
|
+
block_type_hint: method_type.block.type.return_type
|
2955
|
+
)
|
2956
|
+
else
|
2957
|
+
block_body_type = AST::Builtin.nil_type
|
2958
|
+
end
|
2959
|
+
|
2960
|
+
result = check_relation(sub_type: block_body_type,
|
2762
2961
|
super_type: method_type.block.type.return_type,
|
2763
2962
|
constraints: constraints)
|
2764
2963
|
|
2765
2964
|
case result
|
2766
2965
|
when Subtyping::Result::Success
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
[ty, constr]
|
2966
|
+
s = constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)
|
2967
|
+
method_type = method_type.subst(s)
|
2968
|
+
|
2969
|
+
return_type = method_type.type.return_type
|
2970
|
+
if break_type = block_annotations.break_type
|
2971
|
+
return_type = union_type(break_type, return_type)
|
2774
2972
|
end
|
2775
2973
|
|
2776
2974
|
when Subtyping::Result::Failure
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2975
|
+
given_block_type = AST::Types::Proc.new(
|
2976
|
+
type: Interface::Function.new(
|
2977
|
+
params: method_type.block.type.params || block_params.params_type,
|
2978
|
+
return_type: block_body_type,
|
2979
|
+
location: nil
|
2980
|
+
),
|
2981
|
+
block: nil
|
2982
|
+
)
|
2983
|
+
|
2984
|
+
method_block_type = AST::Types::Proc.new(
|
2985
|
+
type: Interface::Function.new(
|
2986
|
+
params: method_type.block.type.params,
|
2987
|
+
return_type: method_type.block.type.return_type,
|
2988
|
+
location: nil
|
2989
|
+
),
|
2990
|
+
block: nil
|
2991
|
+
)
|
2992
|
+
|
2993
|
+
errors << Errors::BlockTypeMismatch.new(node: node,
|
2994
|
+
expected: method_block_type,
|
2995
|
+
actual: given_block_type,
|
2996
|
+
result: result)
|
2997
|
+
|
2998
|
+
return_type = method_type.type.return_type
|
2782
2999
|
end
|
2783
|
-
end
|
2784
3000
|
|
2785
|
-
|
2786
|
-
[Errors::UnsatisfiableConstraint.new(node: node,
|
2787
|
-
method_type: method_type,
|
2788
|
-
var: exn.var,
|
2789
|
-
sub_type: exn.sub_type,
|
2790
|
-
super_type: exn.super_type,
|
2791
|
-
result: exn.result),
|
2792
|
-
constr]
|
2793
|
-
end
|
2794
|
-
|
2795
|
-
when method_type.block && args.block_pass_arg
|
2796
|
-
begin
|
2797
|
-
method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
|
2798
|
-
block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
|
2799
|
-
result = check_relation(
|
2800
|
-
sub_type: block_type,
|
2801
|
-
super_type: method_type.block.yield_self {|expected_block|
|
2802
|
-
if expected_block.optional?
|
2803
|
-
AST::Builtin.optional(expected_block.type)
|
2804
|
-
else
|
2805
|
-
expected_block.type
|
2806
|
-
end
|
2807
|
-
},
|
2808
|
-
constraints: constraints
|
2809
|
-
)
|
3001
|
+
block_constr.typing.save!
|
2810
3002
|
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
3003
|
+
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
3004
|
+
errors << Errors::UnsatisfiableConstraint.new(
|
3005
|
+
node: node,
|
3006
|
+
method_type: method_type,
|
3007
|
+
var: exn.var,
|
3008
|
+
sub_type: exn.sub_type,
|
3009
|
+
super_type: exn.super_type,
|
3010
|
+
result: exn.result
|
3011
|
+
)
|
2817
3012
|
|
2818
|
-
|
2819
|
-
|
2820
|
-
Errors::BlockTypeMismatch.new(node: node,
|
2821
|
-
expected: method_type.block.type,
|
2822
|
-
actual: block_type,
|
2823
|
-
result: result),
|
2824
|
-
constr
|
2825
|
-
]
|
3013
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
3014
|
+
errors << error
|
2826
3015
|
end
|
3016
|
+
|
3017
|
+
s = Interface::Substitution.build(method_type.free_variables,
|
3018
|
+
Array.new(method_type.free_variables.size, AST::Builtin.any_type))
|
3019
|
+
method_type = method_type.subst(s)
|
2827
3020
|
end
|
3021
|
+
else
|
3022
|
+
errors << Errors::UnsupportedSyntax.new(
|
3023
|
+
node: block_params,
|
3024
|
+
message: "Unsupported block params pattern, probably masgn?"
|
3025
|
+
)
|
2828
3026
|
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
3027
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
3028
|
+
method_type = method_type.subst(s)
|
3029
|
+
end
|
3030
|
+
else
|
3031
|
+
# Block is given but method doesn't accept
|
3032
|
+
#
|
3033
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
3034
|
+
errors << error
|
3035
|
+
end
|
3036
|
+
|
3037
|
+
errors << Errors::UnexpectedBlockGiven.new(
|
3038
|
+
node: node,
|
3039
|
+
method_type: method_type
|
3040
|
+
)
|
3041
|
+
end
|
3042
|
+
else
|
3043
|
+
# block is not given
|
3044
|
+
if (!method_type.block || method_type.block.optional?)
|
3045
|
+
# Method call without block is allowed
|
3046
|
+
unless args.block_pass_arg
|
3047
|
+
# OK, without block
|
3048
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
3049
|
+
method_type = method_type.subst(s)
|
3050
|
+
else
|
3051
|
+
# &block arg is given
|
3052
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
3053
|
+
method_type = method_type.subst(s)
|
3054
|
+
|
3055
|
+
errors << Errors::UnexpectedBlockGiven.new(
|
2851
3056
|
node: node,
|
2852
3057
|
method_type: method_type
|
2853
|
-
)
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
Errors::RequiredBlockMissing.new(
|
3058
|
+
)
|
3059
|
+
end
|
3060
|
+
else
|
3061
|
+
unless args.block_pass_arg
|
3062
|
+
# Required block is missing
|
3063
|
+
errors << Errors::RequiredBlockMissing.new(
|
2860
3064
|
node: node,
|
2861
3065
|
method_type: method_type
|
2862
|
-
)
|
2863
|
-
constr
|
2864
|
-
]
|
3066
|
+
)
|
2865
3067
|
|
2866
|
-
|
2867
|
-
|
3068
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
3069
|
+
method_type = method_type.subst(s)
|
3070
|
+
else
|
3071
|
+
begin
|
3072
|
+
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params))
|
3073
|
+
hint_type = if topdown_hint
|
3074
|
+
AST::Types::Proc.new(type: method_type.block.type, block: nil)
|
3075
|
+
end
|
3076
|
+
given_block_type, constr = constr.synthesize(args.block_pass_arg, hint: hint_type)
|
3077
|
+
method_block_type = method_type.block.yield_self {|expected_block|
|
3078
|
+
proc_type = AST::Types::Proc.new(type: expected_block.type, block: nil)
|
3079
|
+
if expected_block.optional?
|
3080
|
+
AST::Builtin.optional(proc_type)
|
3081
|
+
else
|
3082
|
+
proc_type
|
3083
|
+
end
|
3084
|
+
}
|
3085
|
+
|
3086
|
+
result = check_relation(sub_type: given_block_type, super_type: method_block_type, constraints: constraints)
|
3087
|
+
result.else do |result|
|
3088
|
+
errors << Errors::BlockTypeMismatch.new(node: node,
|
3089
|
+
expected: method_block_type,
|
3090
|
+
actual: given_block_type,
|
3091
|
+
result: result)
|
3092
|
+
end
|
3093
|
+
|
3094
|
+
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: method_type.free_variables))
|
3095
|
+
end
|
3096
|
+
end
|
3097
|
+
end
|
3098
|
+
end
|
3099
|
+
|
3100
|
+
call = if errors.empty?
|
3101
|
+
TypeInference::MethodCall::Typed.new(
|
3102
|
+
node: node,
|
3103
|
+
context: context.method_context,
|
3104
|
+
receiver_type: receiver_type,
|
3105
|
+
method_name: method_name,
|
3106
|
+
actual_method_type: method_type,
|
3107
|
+
return_type: return_type || method_type.type.return_type,
|
3108
|
+
method_decls: method_type.method_decls
|
3109
|
+
)
|
3110
|
+
else
|
3111
|
+
TypeInference::MethodCall::Error.new(
|
3112
|
+
node: node,
|
3113
|
+
context: context.method_context,
|
3114
|
+
receiver_type: receiver_type,
|
3115
|
+
method_name: method_name,
|
3116
|
+
return_type: return_type || method_type.type.return_type,
|
3117
|
+
method_decls: method_type.method_decls,
|
3118
|
+
errors: errors
|
3119
|
+
)
|
3120
|
+
end
|
3121
|
+
|
3122
|
+
[
|
3123
|
+
call,
|
3124
|
+
constr
|
3125
|
+
]
|
3126
|
+
end
|
3127
|
+
|
3128
|
+
def type_block_without_hint(node:, block_annotations:, block_params:, block_body:, &block)
|
3129
|
+
block_constr = for_block(
|
3130
|
+
block_params: block_params,
|
3131
|
+
block_param_hint: nil,
|
3132
|
+
block_type_hint: nil,
|
3133
|
+
block_annotations: block_annotations,
|
3134
|
+
node_type_hint: nil
|
3135
|
+
)
|
3136
|
+
|
3137
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
3138
|
+
|
3139
|
+
block_params.params.each do |param|
|
3140
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
3141
|
+
end
|
3142
|
+
|
3143
|
+
block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
|
3144
|
+
|
3145
|
+
if expected_block_type = block_constr.block_context.body_type
|
3146
|
+
block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
|
3147
|
+
block_constr.typing.add_error(
|
3148
|
+
Errors::BlockBodyTypeMismatch.new(
|
3149
|
+
node: node,
|
3150
|
+
expected: expected_block_type,
|
3151
|
+
actual: block_type,
|
3152
|
+
result: result
|
3153
|
+
)
|
3154
|
+
)
|
2868
3155
|
end
|
2869
3156
|
end
|
2870
3157
|
end
|
2871
3158
|
|
2872
|
-
def
|
3159
|
+
def for_block(block_params:, block_param_hint:, block_type_hint:, block_annotations:, node_type_hint:)
|
2873
3160
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
2874
3161
|
|
2875
3162
|
param_types_hash = {}
|
@@ -2885,30 +3172,30 @@ module Steep
|
|
2885
3172
|
end
|
2886
3173
|
end
|
2887
3174
|
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
3175
|
+
decls = param_types_hash.each.with_object({}) do |(name, type), hash|
|
3176
|
+
hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
|
3177
|
+
end
|
3178
|
+
lvar_env = context.lvar_env
|
3179
|
+
.pin_assignments
|
3180
|
+
.except(decls.keys)
|
3181
|
+
.update(assigned_types: decls)
|
3182
|
+
.annotate(block_annotations)
|
2894
3183
|
|
2895
3184
|
break_type = if block_annotations.break_type
|
2896
3185
|
union_type(node_type_hint, block_annotations.break_type)
|
2897
3186
|
else
|
2898
3187
|
node_type_hint
|
2899
3188
|
end
|
2900
|
-
Steep.logger.debug("return_type = #{break_type}")
|
2901
|
-
|
2902
|
-
block_context = TypeInference::Context::BlockContext.new(body_type: block_annotations.block_type)
|
2903
|
-
Steep.logger.debug("block_context { body_type: #{block_context.body_type} }")
|
2904
3189
|
|
3190
|
+
block_context = TypeInference::Context::BlockContext.new(
|
3191
|
+
body_type: block_annotations.block_type || block_type_hint || AST::Builtin.any_type
|
3192
|
+
)
|
2905
3193
|
break_context = TypeInference::Context::BreakContext.new(
|
2906
3194
|
break_type: break_type,
|
2907
3195
|
next_type: block_context.body_type
|
2908
3196
|
)
|
2909
|
-
Steep.logger.debug("break_context { type: #{break_context.break_type} }")
|
2910
3197
|
|
2911
|
-
|
3198
|
+
self.class.new(
|
2912
3199
|
checker: checker,
|
2913
3200
|
source: source,
|
2914
3201
|
annotations: annotations.merge_block_annotations(block_annotations),
|
@@ -2920,37 +3207,23 @@ module Steep
|
|
2920
3207
|
break_context: break_context,
|
2921
3208
|
self_type: block_annotations.self_type || self_type,
|
2922
3209
|
type_env: type_env.dup,
|
2923
|
-
lvar_env: lvar_env
|
3210
|
+
lvar_env: lvar_env,
|
3211
|
+
call_context: self.context.call_context
|
2924
3212
|
)
|
2925
3213
|
)
|
3214
|
+
end
|
2926
3215
|
|
2927
|
-
|
2928
|
-
|
3216
|
+
def synthesize_block(node:, block_type_hint:, block_body:)
|
2929
3217
|
if block_body
|
2930
|
-
|
2931
|
-
for_block_body.check(block_body, body_type) do |expected, actual, result|
|
2932
|
-
typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
|
2933
|
-
expected: expected,
|
2934
|
-
actual: actual,
|
2935
|
-
result: result)
|
2936
|
-
|
2937
|
-
end
|
2938
|
-
else
|
2939
|
-
for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
2940
|
-
end
|
3218
|
+
body_type, _, context = synthesize(block_body, hint: block_context.body_type || block_type_hint)
|
2941
3219
|
|
2942
3220
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
2943
|
-
typing.add_context(range, context:
|
3221
|
+
typing.add_context(range, context: context)
|
3222
|
+
|
3223
|
+
body_type
|
2944
3224
|
else
|
2945
|
-
|
3225
|
+
AST::Builtin.nil_type
|
2946
3226
|
end
|
2947
|
-
|
2948
|
-
body_pair.with(
|
2949
|
-
type: AST::Types::Proc.new(
|
2950
|
-
params: block_param_hint || block_params.params_type,
|
2951
|
-
return_type: body_pair.type
|
2952
|
-
)
|
2953
|
-
)
|
2954
3227
|
end
|
2955
3228
|
|
2956
3229
|
def each_child_node(node)
|
@@ -3035,7 +3308,7 @@ module Steep
|
|
3035
3308
|
if module_name.namespace.relative?
|
3036
3309
|
(current_namespace + module_name.namespace).append(module_name.name)
|
3037
3310
|
else
|
3038
|
-
module_name
|
3311
|
+
module_name.to_namespace
|
3039
3312
|
end
|
3040
3313
|
end
|
3041
3314
|
|
@@ -3070,8 +3343,10 @@ module Steep
|
|
3070
3343
|
end
|
3071
3344
|
end
|
3072
3345
|
expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
3073
|
-
if
|
3074
|
-
|
3346
|
+
if name != :new
|
3347
|
+
if method.implemented_in == module_context.module_definition.type_name
|
3348
|
+
set << name
|
3349
|
+
end
|
3075
3350
|
end
|
3076
3351
|
end
|
3077
3352
|
|
@@ -3172,6 +3447,14 @@ module Steep
|
|
3172
3447
|
!nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
|
3173
3448
|
end
|
3174
3449
|
|
3450
|
+
def type_any_rec(node)
|
3451
|
+
add_typing node, type: AST::Builtin.any_type
|
3452
|
+
|
3453
|
+
each_child_node(node) do |child|
|
3454
|
+
type_any_rec(child)
|
3455
|
+
end
|
3456
|
+
end
|
3457
|
+
|
3175
3458
|
def fallback_any_rec(node)
|
3176
3459
|
fallback_to_any(node) unless typing.has_type?(node)
|
3177
3460
|
|
@@ -3324,6 +3607,8 @@ module Steep
|
|
3324
3607
|
end
|
3325
3608
|
|
3326
3609
|
def try_hash_type(node, hint)
|
3610
|
+
hint = expand_alias(hint)
|
3611
|
+
|
3327
3612
|
case hint
|
3328
3613
|
when AST::Types::Record
|
3329
3614
|
typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
|