steep 0.31.0 → 0.35.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 +25 -0
- data/lib/steep.rb +3 -2
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +66 -60
- 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 +19 -15
- data/lib/steep/interface/method_type.rb +12 -23
- 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/utils.rb +1 -1
- data/lib/steep/source.rb +3 -3
- data/lib/steep/subtyping/check.rb +30 -16
- data/lib/steep/subtyping/variable_occurrence.rb +2 -0
- data/lib/steep/type_construction.rb +585 -416
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/context_array.rb +1 -1
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +6 -0
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +38 -8
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/fun.rb +8 -0
- data/smoke/regression/fun.rbs +4 -0
- data/smoke/regression/range.rb +5 -0
- data/steep.gemspec +1 -1
- metadata +10 -6
- data/lib/steep/ast/buffer.rb +0 -51
- data/lib/steep/ast/location.rb +0 -86
@@ -147,7 +147,23 @@ module Steep
|
|
147
147
|
success(constraints: constraints)
|
148
148
|
|
149
149
|
when relation.super_type.is_a?(AST::Types::Boolean)
|
150
|
-
|
150
|
+
check(
|
151
|
+
Relation.new(sub_type: relation.sub_type, super_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type])),
|
152
|
+
self_type: self_type,
|
153
|
+
assumption: assumption,
|
154
|
+
trace: trace,
|
155
|
+
constraints: constraints
|
156
|
+
)
|
157
|
+
|
158
|
+
when relation.sub_type.is_a?(AST::Types::Boolean)
|
159
|
+
check(
|
160
|
+
Relation.new(sub_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type]),
|
161
|
+
super_type: relation.super_type),
|
162
|
+
self_type: self_type,
|
163
|
+
assumption: assumption,
|
164
|
+
trace: trace,
|
165
|
+
constraints: constraints
|
166
|
+
)
|
151
167
|
|
152
168
|
when relation.sub_type.is_a?(AST::Types::Self) && !self_type.is_a?(AST::Types::Self)
|
153
169
|
check(
|
@@ -326,23 +342,21 @@ module Steep
|
|
326
342
|
constraints: constraints)
|
327
343
|
|
328
344
|
when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
relation
|
334
|
-
|
335
|
-
|
336
|
-
|
345
|
+
keys = relation.super_type.elements.keys
|
346
|
+
relations = keys.map {|key|
|
347
|
+
Relation.new(
|
348
|
+
sub_type: relation.sub_type.elements[key] || AST::Builtin.nil_type,
|
349
|
+
super_type: relation.super_type.elements[key]
|
350
|
+
)
|
351
|
+
}
|
352
|
+
results = relations.map do |relation|
|
353
|
+
check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
354
|
+
end
|
337
355
|
|
338
|
-
|
339
|
-
|
340
|
-
else
|
341
|
-
results.find(&:failure?)
|
342
|
-
end
|
356
|
+
if results.all?(&:success?)
|
357
|
+
success(constraints: constraints)
|
343
358
|
else
|
344
|
-
|
345
|
-
trace: trace)
|
359
|
+
results.find(&:failure?)
|
346
360
|
end
|
347
361
|
|
348
362
|
when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Name::Base)
|
@@ -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
|
@@ -216,6 +216,21 @@ module Steep
|
|
216
216
|
|
217
217
|
lvar_env = lvar_env.annotate(annots)
|
218
218
|
|
219
|
+
call_context = case self_type
|
220
|
+
when nil
|
221
|
+
TypeInference::MethodCall::UnknownContext.new()
|
222
|
+
when AST::Types::Name::Singleton
|
223
|
+
TypeInference::MethodCall::MethodContext.new(
|
224
|
+
method_name: SingletonMethodName.new(type_name: module_context.class_name, method_name: method_name)
|
225
|
+
)
|
226
|
+
when AST::Types::Name::Instance, AST::Types::Intersection
|
227
|
+
TypeInference::MethodCall::MethodContext.new(
|
228
|
+
method_name: InstanceMethodName.new(type_name: module_context.class_name, method_name: method_name)
|
229
|
+
)
|
230
|
+
else
|
231
|
+
raise "Unexpected self_type: #{self_type}"
|
232
|
+
end
|
233
|
+
|
219
234
|
self.class.new(
|
220
235
|
checker: checker,
|
221
236
|
source: source,
|
@@ -227,7 +242,8 @@ module Steep
|
|
227
242
|
break_context: nil,
|
228
243
|
self_type: annots.self_type || self_type,
|
229
244
|
type_env: type_env,
|
230
|
-
lvar_env: lvar_env
|
245
|
+
lvar_env: lvar_env,
|
246
|
+
call_context: call_context
|
231
247
|
),
|
232
248
|
typing: typing,
|
233
249
|
)
|
@@ -355,7 +371,8 @@ module Steep
|
|
355
371
|
module_context: module_context_,
|
356
372
|
self_type: module_context_.module_type,
|
357
373
|
type_env: module_type_env,
|
358
|
-
lvar_env: lvar_env
|
374
|
+
lvar_env: lvar_env,
|
375
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context_.class_name)
|
359
376
|
)
|
360
377
|
)
|
361
378
|
end
|
@@ -424,7 +441,8 @@ module Steep
|
|
424
441
|
break_context: nil,
|
425
442
|
self_type: module_context.module_type,
|
426
443
|
type_env: class_type_env,
|
427
|
-
lvar_env: lvar_env
|
444
|
+
lvar_env: lvar_env,
|
445
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
|
428
446
|
)
|
429
447
|
|
430
448
|
self.class.new(
|
@@ -509,7 +527,8 @@ module Steep
|
|
509
527
|
break_context: nil,
|
510
528
|
self_type: module_context.module_type,
|
511
529
|
type_env: type_env,
|
512
|
-
lvar_env: lvar_env
|
530
|
+
lvar_env: lvar_env,
|
531
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
|
513
532
|
)
|
514
533
|
|
515
534
|
self.class.new(
|
@@ -608,6 +627,22 @@ module Steep
|
|
608
627
|
Pair.new(type: type, constr: constr)
|
609
628
|
end
|
610
629
|
|
630
|
+
def add_call(call)
|
631
|
+
case call
|
632
|
+
when TypeInference::MethodCall::NoMethodError
|
633
|
+
typing.add_error(call.error)
|
634
|
+
when TypeInference::MethodCall::Error
|
635
|
+
call.errors.each do |error|
|
636
|
+
typing.add_error(error)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
typing.add_typing(call.node, call.return_type, nil)
|
641
|
+
typing.add_call(call.node, call)
|
642
|
+
|
643
|
+
Pair.new(type: call.return_type, constr: self)
|
644
|
+
end
|
645
|
+
|
611
646
|
def synthesize(node, hint: nil)
|
612
647
|
Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
|
613
648
|
Steep.logger.debug node.type
|
@@ -786,28 +821,33 @@ module Steep
|
|
786
821
|
when :super
|
787
822
|
yield_self do
|
788
823
|
if self_type && method_context&.method
|
789
|
-
if method_context.super_method
|
824
|
+
if super_def = method_context.super_method
|
790
825
|
each_child_node(node) do |child|
|
791
826
|
synthesize(child)
|
792
827
|
end
|
793
828
|
|
794
829
|
super_method = Interface::Interface::Entry.new(
|
795
830
|
method_types: method_context.super_method.method_types.map {|method_type|
|
796
|
-
|
831
|
+
decl = TypeInference::MethodCall::MethodDecl.new(
|
832
|
+
method_name: InstanceMethodName.new(type_name: super_def.implemented_in || super_def.defined_in,
|
833
|
+
method_name: method_context.name),
|
834
|
+
method_def: super_def
|
835
|
+
)
|
836
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[decl])
|
797
837
|
}
|
798
838
|
)
|
799
839
|
args = TypeInference::SendArgs.from_nodes(node.children.dup)
|
800
840
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
841
|
+
call, constr = type_method_call(node,
|
842
|
+
receiver_type: self_type,
|
843
|
+
method_name: method_context.name,
|
844
|
+
method: super_method,
|
845
|
+
args: args,
|
846
|
+
block_params: nil,
|
847
|
+
block_body: nil,
|
848
|
+
topdown_hint: true)
|
809
849
|
|
810
|
-
|
850
|
+
constr.add_call(call)
|
811
851
|
else
|
812
852
|
fallback_to_any node do
|
813
853
|
Errors::UnexpectedSuper.new(node: node, method: method_context.name)
|
@@ -1208,7 +1248,13 @@ module Steep
|
|
1208
1248
|
|
1209
1249
|
when :class
|
1210
1250
|
yield_self do
|
1211
|
-
|
1251
|
+
constr = self
|
1252
|
+
|
1253
|
+
name, sup, _ = node.children
|
1254
|
+
_, constr = constr.synthesize(name)
|
1255
|
+
_, constr = constr.synthesize(sup) if sup
|
1256
|
+
|
1257
|
+
constr.for_class(node).tap do |constructor|
|
1212
1258
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1213
1259
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1214
1260
|
|
@@ -1224,6 +1270,11 @@ module Steep
|
|
1224
1270
|
|
1225
1271
|
when :module
|
1226
1272
|
yield_self do
|
1273
|
+
constr = self
|
1274
|
+
|
1275
|
+
name, _ = node.children
|
1276
|
+
_, constr = constr.synthesize(name)
|
1277
|
+
|
1227
1278
|
for_module(node).yield_self do |constructor|
|
1228
1279
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1229
1280
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
@@ -1271,24 +1322,39 @@ module Steep
|
|
1271
1322
|
when :self
|
1272
1323
|
add_typing node, type: AST::Types::Self.new
|
1273
1324
|
|
1325
|
+
when :cbase
|
1326
|
+
add_typing node, type: AST::Types::Void.new
|
1327
|
+
|
1274
1328
|
when :const
|
1275
|
-
|
1329
|
+
parent = node.children[0]
|
1330
|
+
if parent
|
1331
|
+
_, constr = synthesize(parent)
|
1332
|
+
else
|
1333
|
+
constr = self
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
const_name = constr.module_name_from_node(node)
|
1276
1337
|
|
1277
1338
|
if const_name
|
1278
1339
|
type = type_env.get(const: const_name) do
|
1279
|
-
fallback_to_any
|
1340
|
+
constr.fallback_to_any(node)
|
1280
1341
|
end
|
1281
|
-
add_typing
|
1342
|
+
constr.add_typing(node, type: type)
|
1282
1343
|
else
|
1283
|
-
fallback_to_any
|
1344
|
+
constr.fallback_to_any(node)
|
1284
1345
|
end
|
1285
1346
|
|
1286
1347
|
when :casgn
|
1287
1348
|
yield_self do
|
1288
|
-
|
1349
|
+
constr = self
|
1350
|
+
|
1351
|
+
parent = node.children[0]
|
1352
|
+
_, constr = constr.synthesize(parent) if parent
|
1353
|
+
const_name = constr.module_name_from_node(node)
|
1354
|
+
|
1289
1355
|
if const_name
|
1290
1356
|
const_type = type_env.get(const: const_name) {}
|
1291
|
-
value_type = synthesize(node.children.last, hint: const_type)
|
1357
|
+
value_type, constr = constr.synthesize(node.children.last, hint: const_type)
|
1292
1358
|
type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
|
1293
1359
|
case error
|
1294
1360
|
when Subtyping::Result::Failure
|
@@ -1302,10 +1368,10 @@ module Steep
|
|
1302
1368
|
end
|
1303
1369
|
end
|
1304
1370
|
|
1305
|
-
add_typing(node, type: type)
|
1371
|
+
constr.add_typing(node, type: type)
|
1306
1372
|
else
|
1307
|
-
synthesize(node.children.last)
|
1308
|
-
fallback_to_any(node)
|
1373
|
+
_, constr = constr.synthesize(node.children.last)
|
1374
|
+
constr.fallback_to_any(node)
|
1309
1375
|
end
|
1310
1376
|
end
|
1311
1377
|
|
@@ -1338,7 +1404,7 @@ module Steep
|
|
1338
1404
|
if method_context&.method
|
1339
1405
|
if method_context.super_method
|
1340
1406
|
types = method_context.super_method.method_types.map {|method_type|
|
1341
|
-
checker.factory.method_type(method_type, self_type: self_type).return_type
|
1407
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]).return_type
|
1342
1408
|
}
|
1343
1409
|
add_typing(node, type: union_type(*types))
|
1344
1410
|
else
|
@@ -2029,7 +2095,7 @@ module Steep
|
|
2029
2095
|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
2030
2096
|
# Steep.logger.error { "result = #{pair.inspect}" }
|
2031
2097
|
# Steep.logger.error { "node = #{node.type}" }
|
2032
|
-
raise "#synthesize should return an instance of Pair: #{pair.class}"
|
2098
|
+
raise "#synthesize should return an instance of Pair: #{pair.class}, node=#{node.inspect}"
|
2033
2099
|
end
|
2034
2100
|
end
|
2035
2101
|
end
|
@@ -2273,177 +2339,225 @@ module Steep
|
|
2273
2339
|
return_hint = type_hint.return_type
|
2274
2340
|
end
|
2275
2341
|
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
block_annotations: block_annotations,
|
2283
|
-
topdown_hint: true)
|
2342
|
+
block_constr = for_block(
|
2343
|
+
block_params: params,
|
2344
|
+
block_param_hint: params_hint,
|
2345
|
+
block_annotations: block_annotations,
|
2346
|
+
node_type_hint: nil
|
2347
|
+
)
|
2284
2348
|
|
2285
|
-
|
2286
|
-
end
|
2349
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2287
2350
|
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2351
|
+
params.params.each do |param|
|
2352
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2353
|
+
end
|
2291
2354
|
|
2292
|
-
if
|
2293
|
-
|
2355
|
+
if block_body
|
2356
|
+
return_type = block_constr.synthesize_block(
|
2357
|
+
node: node,
|
2358
|
+
block_body: block_body,
|
2359
|
+
topdown_hint: true,
|
2360
|
+
block_type_hint: return_hint
|
2361
|
+
) do |error|
|
2362
|
+
typing.add_error(error)
|
2363
|
+
end
|
2364
|
+
else
|
2365
|
+
return_type = AST::Builtin.any_type
|
2294
2366
|
end
|
2295
2367
|
|
2296
|
-
|
2368
|
+
block_type = AST::Types::Proc.new(
|
2369
|
+
params: params_hint || params.params_type,
|
2370
|
+
return_type: return_type
|
2371
|
+
)
|
2297
2372
|
|
2298
|
-
|
2299
|
-
|
2300
|
-
each_child_node(send_node) do |child|
|
2301
|
-
unless child.equal?(receiver)
|
2302
|
-
_, constr = constr.synthesize(child)
|
2303
|
-
end
|
2304
|
-
end
|
2373
|
+
add_typing node, type: block_type
|
2374
|
+
end
|
2305
2375
|
|
2306
|
-
|
2376
|
+
def synthesize_children(node, skips: [])
|
2377
|
+
skips = Set.new.compare_by_identity.merge(skips)
|
2307
2378
|
|
2308
|
-
|
2309
|
-
fallback_to_any node
|
2379
|
+
constr = self
|
2310
2380
|
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2381
|
+
each_child_node(node) do |child|
|
2382
|
+
unless skips.include?(child)
|
2383
|
+
_, constr = constr.synthesize(child)
|
2384
|
+
end
|
2385
|
+
end
|
2315
2386
|
|
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
|
2387
|
+
constr
|
2388
|
+
end
|
2355
2389
|
|
2356
|
-
|
2357
|
-
|
2358
|
-
end
|
2359
|
-
end
|
2360
|
-
end
|
2361
|
-
end
|
2390
|
+
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:)
|
2391
|
+
method = interface.methods[method_name]
|
2362
2392
|
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2393
|
+
if method
|
2394
|
+
args = TypeInference::SendArgs.from_nodes(arguments)
|
2395
|
+
call, constr = type_method_call(node,
|
2396
|
+
method: method,
|
2397
|
+
method_name: method_name,
|
2398
|
+
args: args,
|
2399
|
+
block_params: block_params,
|
2400
|
+
block_body: block_body,
|
2401
|
+
receiver_type: receiver_type,
|
2402
|
+
topdown_hint: true)
|
2403
|
+
|
2404
|
+
if call && constr
|
2405
|
+
case method_name.to_s
|
2406
|
+
when "[]=", /\w=\Z/
|
2407
|
+
if typing.has_type?(arguments.last)
|
2408
|
+
call = call.with_return_type(typing.type_of(node: arguments.last))
|
2372
2409
|
end
|
2373
2410
|
end
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2411
|
+
else
|
2412
|
+
error = Errors::UnresolvedOverloading.new(
|
2413
|
+
node: node,
|
2414
|
+
receiver_type: receiver_type,
|
2415
|
+
method_name: method_name,
|
2416
|
+
method_types: method.method_types
|
2417
|
+
)
|
2418
|
+
call = TypeInference::MethodCall::Error.new(
|
2419
|
+
node: node,
|
2420
|
+
context: context.method_context,
|
2421
|
+
method_name: method_name,
|
2422
|
+
receiver_type: receiver_type,
|
2423
|
+
errors: [error]
|
2424
|
+
)
|
2381
2425
|
|
2382
|
-
|
2383
|
-
|
2384
|
-
method_return_type: AST::Builtin.any_type,
|
2385
|
-
typing: typing)
|
2426
|
+
skips = [receiver]
|
2427
|
+
skips << node.children[0] if node.type == :block
|
2386
2428
|
|
2387
|
-
|
2429
|
+
constr = synthesize_children(node, skips: skips)
|
2430
|
+
if block_params
|
2431
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2388
2432
|
|
2389
|
-
|
2433
|
+
constr.type_block_without_hint(
|
2434
|
+
node: node,
|
2435
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2436
|
+
block_annotations: block_annotations,
|
2437
|
+
block_body: block_body
|
2438
|
+
) do |error|
|
2439
|
+
constr.typing.add_error(error)
|
2440
|
+
end
|
2390
2441
|
end
|
2391
2442
|
end
|
2443
|
+
|
2444
|
+
constr.add_call(call)
|
2392
2445
|
else
|
2393
|
-
|
2446
|
+
add_call(
|
2447
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2448
|
+
node: node,
|
2449
|
+
context: context.method_context,
|
2450
|
+
method_name: method_name,
|
2451
|
+
receiver_type: receiver_type,
|
2452
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2453
|
+
)
|
2454
|
+
)
|
2394
2455
|
end
|
2395
2456
|
end
|
2396
2457
|
|
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
|
2458
|
+
def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
|
2459
|
+
receiver, method_name, *arguments = send_node.children
|
2460
|
+
recv_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
|
2406
2461
|
|
2407
|
-
|
2408
|
-
|
2409
|
-
ivar_types: block_annotations.ivar_types,
|
2410
|
-
const_types: block_annotations.const_types,
|
2411
|
-
)
|
2462
|
+
if unwrap
|
2463
|
+
recv_type = unwrap(recv_type)
|
2412
2464
|
end
|
2413
2465
|
|
2414
|
-
|
2466
|
+
receiver_type = checker.factory.deep_expand_alias(recv_type)
|
2415
2467
|
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
method_return_type
|
2420
|
-
end
|
2421
|
-
Steep.logger.debug("return_type = #{return_type}")
|
2468
|
+
type, constr = case receiver_type
|
2469
|
+
when nil
|
2470
|
+
raise
|
2422
2471
|
|
2423
|
-
|
2424
|
-
|
2472
|
+
when AST::Types::Any
|
2473
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2474
|
+
constr.add_call(
|
2475
|
+
TypeInference::MethodCall::Untyped.new(
|
2476
|
+
node: node,
|
2477
|
+
context: context.method_context,
|
2478
|
+
method_name: method_name
|
2479
|
+
)
|
2480
|
+
)
|
2425
2481
|
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2482
|
+
when AST::Types::Void, AST::Types::Bot, AST::Types::Top, AST::Types::Var
|
2483
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2484
|
+
constr.add_call(
|
2485
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2486
|
+
node: node,
|
2487
|
+
context: context.method_context,
|
2488
|
+
method_name: method_name,
|
2489
|
+
receiver_type: receiver_type,
|
2490
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2491
|
+
)
|
2492
|
+
)
|
2431
2493
|
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
2438
|
-
|
2439
|
-
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2494
|
+
when AST::Types::Self
|
2495
|
+
expanded_self = expand_self(receiver_type)
|
2496
|
+
|
2497
|
+
if expanded_self.is_a?(AST::Types::Self)
|
2498
|
+
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2499
|
+
|
2500
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2501
|
+
constr.add_call(
|
2502
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2503
|
+
node: node,
|
2504
|
+
context: context.method_context,
|
2505
|
+
method_name: method_name,
|
2506
|
+
receiver_type: receiver_type,
|
2507
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2508
|
+
)
|
2509
|
+
)
|
2510
|
+
else
|
2511
|
+
interface = checker.factory.interface(expanded_self,
|
2512
|
+
private: !receiver,
|
2513
|
+
self_type: AST::Types::Self.new)
|
2514
|
+
|
2515
|
+
constr.type_send_interface(node,
|
2516
|
+
interface: interface,
|
2517
|
+
receiver: receiver,
|
2518
|
+
receiver_type: expanded_self,
|
2519
|
+
method_name: method_name,
|
2520
|
+
arguments: arguments,
|
2521
|
+
block_params: block_params,
|
2522
|
+
block_body: block_body)
|
2523
|
+
end
|
2524
|
+
else
|
2525
|
+
interface = checker.factory.interface(receiver_type,
|
2526
|
+
private: !receiver,
|
2527
|
+
self_type: receiver_type)
|
2528
|
+
|
2529
|
+
constr.type_send_interface(node,
|
2530
|
+
interface: interface,
|
2531
|
+
receiver: receiver,
|
2532
|
+
receiver_type: receiver_type,
|
2533
|
+
method_name: method_name,
|
2534
|
+
arguments: arguments,
|
2535
|
+
block_params: block_params,
|
2536
|
+
block_body: block_body)
|
2537
|
+
end
|
2538
|
+
|
2539
|
+
Pair.new(type: type, constr: constr)
|
2540
|
+
rescue => exn
|
2541
|
+
case exn
|
2542
|
+
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2543
|
+
# ignore known RBS errors.
|
2544
|
+
else
|
2545
|
+
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2546
|
+
end
|
2547
|
+
|
2548
|
+
error = Errors::UnexpectedError.new(node: node, error: exn)
|
2549
|
+
|
2550
|
+
type_any_rec(node)
|
2551
|
+
|
2552
|
+
add_call(
|
2553
|
+
TypeInference::MethodCall::Error.new(
|
2554
|
+
node: node,
|
2555
|
+
context: context.method_context,
|
2556
|
+
method_name: method_name,
|
2557
|
+
receiver_type: receiver_type,
|
2558
|
+
errors: [error]
|
2445
2559
|
)
|
2446
|
-
)
|
2560
|
+
)
|
2447
2561
|
end
|
2448
2562
|
|
2449
2563
|
def expand_self(type)
|
@@ -2463,63 +2577,54 @@ module Steep
|
|
2463
2577
|
|
2464
2578
|
zips.map do |arg_pairs|
|
2465
2579
|
typing.new_child(node_range) do |child_typing|
|
2466
|
-
|
2580
|
+
self.with_new_typing(child_typing).try_method_type(
|
2467
2581
|
node,
|
2468
2582
|
receiver_type: receiver_type,
|
2583
|
+
method_name: method_name,
|
2469
2584
|
method_type: method_type,
|
2470
2585
|
args: args,
|
2471
2586
|
arg_pairs: arg_pairs,
|
2472
2587
|
block_params: block_params,
|
2473
2588
|
block_body: block_body,
|
2474
|
-
child_typing: child_typing,
|
2475
2589
|
topdown_hint: topdown_hint
|
2476
2590
|
)
|
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
2591
|
end
|
2484
2592
|
end
|
2485
2593
|
end
|
2486
2594
|
end
|
2487
2595
|
|
2488
|
-
|
2489
|
-
|
2490
|
-
else
|
2596
|
+
case
|
2597
|
+
when results.empty?
|
2491
2598
|
method_type = method.method_types.last
|
2599
|
+
all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
|
2600
|
+
set.merge(method_type.method_decls)
|
2601
|
+
end
|
2602
|
+
error = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2603
|
+
call = TypeInference::MethodCall::Error.new(
|
2604
|
+
node: node,
|
2605
|
+
context: context.method_context,
|
2606
|
+
method_name: method_name,
|
2607
|
+
receiver_type: receiver_type,
|
2608
|
+
return_type: method_type.return_type,
|
2609
|
+
errors: [error],
|
2610
|
+
method_decls: all_decls
|
2611
|
+
)
|
2492
2612
|
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
|
2613
|
+
when (call, constr = results.find {|call, _| call.is_a?(TypeInference::MethodCall::Typed) })
|
2614
|
+
# Nop
|
2615
|
+
else
|
2616
|
+
if results.one?
|
2617
|
+
call, constr = results[0]
|
2507
2618
|
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
|
2619
|
+
return
|
2513
2620
|
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
2621
|
end
|
2622
|
+
constr.typing.save!
|
2623
|
+
|
2624
|
+
[
|
2625
|
+
call,
|
2626
|
+
update_lvar_env { constr.context.lvar_env }
|
2627
|
+
]
|
2523
2628
|
end
|
2524
2629
|
|
2525
2630
|
def check_keyword_arg(receiver_type:, node:, method_type:, constraints:)
|
@@ -2621,14 +2726,12 @@ module Steep
|
|
2621
2726
|
|
2622
2727
|
hash_type = AST::Builtin::Hash.instance_type(
|
2623
2728
|
AST::Builtin::Symbol.instance_type,
|
2624
|
-
AST::Types::Union.build(types: value_types
|
2625
|
-
location: method_type.location)
|
2729
|
+
AST::Types::Union.build(types: value_types)
|
2626
2730
|
)
|
2627
2731
|
else
|
2628
2732
|
hash_elements = params.required_keywords.merge(
|
2629
2733
|
method_type.params.optional_keywords.transform_values do |type|
|
2630
|
-
AST::Types::Union.build(types: [type, AST::Builtin.nil_type]
|
2631
|
-
location: method_type.location)
|
2734
|
+
AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2632
2735
|
end
|
2633
2736
|
)
|
2634
2737
|
|
@@ -2650,151 +2753,211 @@ module Steep
|
|
2650
2753
|
nil
|
2651
2754
|
end
|
2652
2755
|
|
2653
|
-
def try_method_type(node, receiver_type:, method_type:, args:, arg_pairs:, block_params:, block_body:,
|
2756
|
+
def try_method_type(node, receiver_type:, method_name:, method_type:, args:, arg_pairs:, block_params:, block_body:, topdown_hint:)
|
2654
2757
|
fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x)}
|
2655
2758
|
fresh_vars = Set.new(fresh_types.map(&:name))
|
2656
2759
|
instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
|
2657
2760
|
|
2658
|
-
|
2659
|
-
checker: checker,
|
2660
|
-
source: source,
|
2661
|
-
annotations: annotations,
|
2662
|
-
typing: child_typing,
|
2663
|
-
context: context
|
2664
|
-
)
|
2761
|
+
constr = self
|
2665
2762
|
|
2666
|
-
|
2763
|
+
method_type = method_type.instantiate(instantiation)
|
2667
2764
|
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2671
|
-
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
2765
|
+
constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
|
2766
|
+
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
2767
|
+
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
2672
2768
|
|
2673
|
-
|
2674
|
-
case pair
|
2675
|
-
when Array
|
2676
|
-
(arg_node, param_type) = pair
|
2677
|
-
param_type = param_type.subst(instantiation)
|
2769
|
+
errors = []
|
2678
2770
|
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
|
2771
|
+
arg_pairs.each do |pair|
|
2772
|
+
case pair
|
2773
|
+
when Array
|
2774
|
+
arg_node, param_type = pair
|
2775
|
+
param_type = param_type.subst(instantiation)
|
2776
|
+
|
2777
|
+
arg_type, constr = if arg_node.type == :splat
|
2778
|
+
constr.synthesize(arg_node.children[0])
|
2779
|
+
else
|
2780
|
+
constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
|
2781
|
+
end
|
2684
2782
|
|
2685
|
-
|
2686
|
-
|
2783
|
+
check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do
|
2784
|
+
errors << Errors::ArgumentTypeMismatch.new(node: arg_node,
|
2687
2785
|
receiver_type: receiver_type,
|
2688
2786
|
expected: param_type,
|
2689
|
-
actual: arg_type)
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
constraints: constraints)
|
2787
|
+
actual: arg_type)
|
2788
|
+
end
|
2789
|
+
else
|
2790
|
+
# keyword
|
2791
|
+
result = constr.check_keyword_arg(receiver_type: receiver_type,
|
2792
|
+
node: pair,
|
2793
|
+
method_type: method_type,
|
2794
|
+
constraints: constraints)
|
2698
2795
|
|
2699
|
-
|
2700
|
-
|
2701
|
-
end
|
2796
|
+
if result.is_a?(Errors::Base)
|
2797
|
+
errors << result
|
2702
2798
|
end
|
2703
2799
|
end
|
2800
|
+
end
|
2704
2801
|
|
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
|
-
|
2802
|
+
if block_params
|
2803
|
+
# block is given
|
2804
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2805
|
+
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
2806
|
+
|
2807
|
+
if method_type.block
|
2808
|
+
pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
|
2809
|
+
|
2810
|
+
if pairs
|
2811
|
+
begin
|
2812
|
+
block_constr = constr.for_block(
|
2813
|
+
block_params: block_params_,
|
2814
|
+
block_param_hint: method_type.block.type.params,
|
2815
|
+
block_annotations: block_annotations,
|
2816
|
+
node_type_hint: method_type.return_type
|
2817
|
+
)
|
2818
|
+
block_constr = block_constr.with_new_typing(
|
2819
|
+
block_constr.typing.new_child(
|
2820
|
+
range: block_constr.typing.block_range(node)
|
2821
|
+
)
|
2822
|
+
)
|
2823
|
+
|
2824
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2825
|
+
|
2826
|
+
pairs.each do |param, type|
|
2827
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
|
2828
|
+
|
2829
|
+
if param.type
|
2830
|
+
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
2831
|
+
error = Errors::IncompatibleAssignment.new(
|
2832
|
+
node: param.node,
|
2833
|
+
lhs_type: param.type,
|
2834
|
+
rhs_type: type,
|
2835
|
+
result: result
|
2836
|
+
)
|
2837
|
+
errors << error
|
2838
|
+
end
|
2839
|
+
end
|
2740
2840
|
end
|
2741
|
-
end
|
2742
|
-
end
|
2743
|
-
end
|
2744
2841
|
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2842
|
+
s = constraints.solution(
|
2843
|
+
checker,
|
2844
|
+
self_type: self_type,
|
2845
|
+
variance: variance,
|
2846
|
+
variables: method_type.params.free_variables + method_type.block.type.params.free_variables
|
2847
|
+
)
|
2848
|
+
method_type = method_type.subst(s)
|
2849
|
+
block_constr = block_constr.update_lvar_env {|env| env.subst(s) }
|
2850
|
+
if block_body
|
2851
|
+
block_body_type = block_constr.synthesize_block(
|
2852
|
+
node: node,
|
2853
|
+
block_type_hint: method_type.block.type.return_type,
|
2854
|
+
block_body: block_body,
|
2855
|
+
topdown_hint: topdown_hint
|
2856
|
+
) do |error|
|
2857
|
+
errors << error
|
2858
|
+
end
|
2859
|
+
else
|
2860
|
+
block_body_type = AST::Builtin.nil_type
|
2861
|
+
end
|
2862
|
+
|
2863
|
+
result = check_relation(sub_type: block_body_type,
|
2762
2864
|
super_type: method_type.block.type.return_type,
|
2763
2865
|
constraints: constraints)
|
2764
2866
|
|
2765
2867
|
case result
|
2766
2868
|
when Subtyping::Result::Success
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
[ty, constr]
|
2869
|
+
s = constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)
|
2870
|
+
method_type = method_type.subst(s)
|
2871
|
+
|
2872
|
+
return_type = method_type.return_type
|
2873
|
+
if break_type = block_annotations.break_type
|
2874
|
+
return_type = union_type(break_type, return_type)
|
2774
2875
|
end
|
2775
2876
|
|
2776
2877
|
when Subtyping::Result::Failure
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2878
|
+
block_type = AST::Types::Proc.new(
|
2879
|
+
params: method_type.block.type.params || block_params.params_type,
|
2880
|
+
return_type: block_body_type
|
2881
|
+
)
|
2882
|
+
errors << Errors::BlockTypeMismatch.new(node: node,
|
2883
|
+
expected: method_type.block.type,
|
2884
|
+
actual: block_type,
|
2885
|
+
result: result)
|
2886
|
+
|
2887
|
+
return_type = method_type.return_type
|
2888
|
+
end
|
2889
|
+
|
2890
|
+
block_constr.typing.save!
|
2891
|
+
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
2892
|
+
errors << Errors::UnsatisfiableConstraint.new(
|
2893
|
+
node: node,
|
2894
|
+
method_type: method_type,
|
2895
|
+
var: exn.var,
|
2896
|
+
sub_type: exn.sub_type,
|
2897
|
+
super_type: exn.super_type,
|
2898
|
+
result: exn.result
|
2899
|
+
)
|
2900
|
+
|
2901
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
2902
|
+
errors << error
|
2782
2903
|
end
|
2904
|
+
|
2905
|
+
s = Interface::Substitution.build(method_type.free_variables,
|
2906
|
+
Array.new(method_type.free_variables.size, AST::Builtin.any_type))
|
2907
|
+
method_type = method_type.subst(s)
|
2783
2908
|
end
|
2909
|
+
else
|
2910
|
+
errors << Errors::UnsupportedSyntax.new(
|
2911
|
+
node: block_params,
|
2912
|
+
message: "Unsupported block params pattern, probably masgn?"
|
2913
|
+
)
|
2914
|
+
|
2915
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2916
|
+
method_type = method_type.subst(s)
|
2917
|
+
end
|
2918
|
+
else
|
2919
|
+
# Block is given but method doesn't accept
|
2920
|
+
#
|
2921
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
2922
|
+
errors << error
|
2923
|
+
end
|
2924
|
+
|
2925
|
+
errors << Errors::UnexpectedBlockGiven.new(
|
2926
|
+
node: node,
|
2927
|
+
method_type: method_type
|
2928
|
+
)
|
2929
|
+
end
|
2930
|
+
else
|
2931
|
+
# block is not given
|
2932
|
+
if (!method_type.block || method_type.block.optional?)
|
2933
|
+
# Method call without block is allowed
|
2934
|
+
unless args.block_pass_arg
|
2935
|
+
# OK, without block
|
2936
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2937
|
+
method_type = method_type.subst(s)
|
2938
|
+
else
|
2939
|
+
# &block arg is given
|
2940
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2941
|
+
method_type = method_type.subst(s)
|
2784
2942
|
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
sub_type: exn.sub_type,
|
2790
|
-
super_type: exn.super_type,
|
2791
|
-
result: exn.result),
|
2792
|
-
constr]
|
2943
|
+
errors << Errors::UnexpectedBlockGiven.new(
|
2944
|
+
node: node,
|
2945
|
+
method_type: method_type
|
2946
|
+
)
|
2793
2947
|
end
|
2948
|
+
else
|
2949
|
+
unless args.block_pass_arg
|
2950
|
+
# Required block is missing
|
2951
|
+
errors << Errors::RequiredBlockMissing.new(
|
2952
|
+
node: node,
|
2953
|
+
method_type: method_type
|
2954
|
+
)
|
2794
2955
|
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2956
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2957
|
+
method_type = method_type.subst(s)
|
2958
|
+
else
|
2959
|
+
begin
|
2960
|
+
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params))
|
2798
2961
|
block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
|
2799
2962
|
result = check_relation(
|
2800
2963
|
sub_type: block_type,
|
@@ -2808,68 +2971,65 @@ module Steep
|
|
2808
2971
|
constraints: constraints
|
2809
2972
|
)
|
2810
2973
|
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
]
|
2817
|
-
|
2818
|
-
when Subtyping::Result::Failure
|
2819
|
-
[
|
2820
|
-
Errors::BlockTypeMismatch.new(node: node,
|
2821
|
-
expected: method_type.block.type,
|
2822
|
-
actual: block_type,
|
2823
|
-
result: result),
|
2824
|
-
constr
|
2825
|
-
]
|
2974
|
+
result.else do |result|
|
2975
|
+
errors << Errors::BlockTypeMismatch.new(node: node,
|
2976
|
+
expected: method_type.block.type,
|
2977
|
+
actual: block_type,
|
2978
|
+
result: result)
|
2826
2979
|
end
|
2980
|
+
|
2981
|
+
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: method_type.free_variables))
|
2827
2982
|
end
|
2983
|
+
end
|
2984
|
+
end
|
2985
|
+
end
|
2828
2986
|
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2987
|
+
call = if errors.empty?
|
2988
|
+
TypeInference::MethodCall::Typed.new(
|
2989
|
+
node: node,
|
2990
|
+
context: context.method_context,
|
2991
|
+
receiver_type: receiver_type,
|
2992
|
+
method_name: method_name,
|
2993
|
+
actual_method_type: method_type,
|
2994
|
+
return_type: return_type || method_type.return_type,
|
2995
|
+
method_decls: method_type.method_decls
|
2996
|
+
)
|
2997
|
+
else
|
2998
|
+
TypeInference::MethodCall::Error.new(
|
2999
|
+
node: node,
|
3000
|
+
context: context.method_context,
|
3001
|
+
receiver_type: receiver_type,
|
3002
|
+
method_name: method_name,
|
3003
|
+
return_type: return_type || method_type.return_type,
|
3004
|
+
method_decls: method_type.method_decls,
|
3005
|
+
errors: errors
|
3006
|
+
)
|
3007
|
+
end
|
3008
|
+
|
3009
|
+
[
|
3010
|
+
call,
|
3011
|
+
constr
|
3012
|
+
]
|
3013
|
+
end
|
3014
|
+
|
3015
|
+
def type_block_without_hint(node:, block_annotations:, block_params:, block_body:, &block)
|
3016
|
+
block_constr = for_block(
|
3017
|
+
block_params: block_params,
|
3018
|
+
block_param_hint: nil,
|
3019
|
+
block_annotations: block_annotations,
|
3020
|
+
node_type_hint: nil
|
3021
|
+
)
|
2856
3022
|
|
2857
|
-
|
2858
|
-
[
|
2859
|
-
Errors::RequiredBlockMissing.new(
|
2860
|
-
node: node,
|
2861
|
-
method_type: method_type
|
2862
|
-
),
|
2863
|
-
constr
|
2864
|
-
]
|
3023
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2865
3024
|
|
2866
|
-
|
2867
|
-
|
2868
|
-
end
|
3025
|
+
block_params.params.each do |param|
|
3026
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2869
3027
|
end
|
3028
|
+
|
3029
|
+
block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body, topdown_hint: false, &block)
|
2870
3030
|
end
|
2871
3031
|
|
2872
|
-
def
|
3032
|
+
def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
|
2873
3033
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
2874
3034
|
|
2875
3035
|
param_types_hash = {}
|
@@ -2885,30 +3045,30 @@ module Steep
|
|
2885
3045
|
end
|
2886
3046
|
end
|
2887
3047
|
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
3048
|
+
decls = param_types_hash.each.with_object({}) do |(name, type), hash|
|
3049
|
+
hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
|
3050
|
+
end
|
3051
|
+
lvar_env = context.lvar_env
|
3052
|
+
.pin_assignments
|
3053
|
+
.except(decls.keys)
|
3054
|
+
.update(assigned_types: decls)
|
3055
|
+
.annotate(block_annotations)
|
2894
3056
|
|
2895
3057
|
break_type = if block_annotations.break_type
|
2896
3058
|
union_type(node_type_hint, block_annotations.break_type)
|
2897
3059
|
else
|
2898
3060
|
node_type_hint
|
2899
3061
|
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
3062
|
|
3063
|
+
block_context = TypeInference::Context::BlockContext.new(
|
3064
|
+
body_type: block_annotations.block_type
|
3065
|
+
)
|
2905
3066
|
break_context = TypeInference::Context::BreakContext.new(
|
2906
3067
|
break_type: break_type,
|
2907
3068
|
next_type: block_context.body_type
|
2908
3069
|
)
|
2909
|
-
Steep.logger.debug("break_context { type: #{break_context.break_type} }")
|
2910
3070
|
|
2911
|
-
|
3071
|
+
self.class.new(
|
2912
3072
|
checker: checker,
|
2913
3073
|
source: source,
|
2914
3074
|
annotations: annotations.merge_block_annotations(block_annotations),
|
@@ -2920,37 +3080,34 @@ module Steep
|
|
2920
3080
|
break_context: break_context,
|
2921
3081
|
self_type: block_annotations.self_type || self_type,
|
2922
3082
|
type_env: type_env.dup,
|
2923
|
-
lvar_env: lvar_env
|
3083
|
+
lvar_env: lvar_env,
|
3084
|
+
call_context: self.context.call_context
|
2924
3085
|
)
|
2925
3086
|
)
|
3087
|
+
end
|
2926
3088
|
|
2927
|
-
|
2928
|
-
|
3089
|
+
def synthesize_block(node:, block_type_hint:, block_body:, topdown_hint:)
|
2929
3090
|
if block_body
|
2930
|
-
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
2936
|
-
|
2937
|
-
|
2938
|
-
|
2939
|
-
|
2940
|
-
|
3091
|
+
body_type, _, context =
|
3092
|
+
if (body_type = block_context.body_type)
|
3093
|
+
check(block_body, body_type) do |expected, actual, result|
|
3094
|
+
error = Errors::BlockTypeMismatch.new(node: block_body,
|
3095
|
+
expected: expected,
|
3096
|
+
actual: actual,
|
3097
|
+
result: result)
|
3098
|
+
yield(error) if block_given?
|
3099
|
+
end
|
3100
|
+
else
|
3101
|
+
synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
3102
|
+
end
|
2941
3103
|
|
2942
3104
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
2943
|
-
typing.add_context(range, context:
|
3105
|
+
typing.add_context(range, context: context)
|
3106
|
+
|
3107
|
+
body_type
|
2944
3108
|
else
|
2945
|
-
|
3109
|
+
AST::Builtin.nil_type
|
2946
3110
|
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
3111
|
end
|
2955
3112
|
|
2956
3113
|
def each_child_node(node)
|
@@ -3070,8 +3227,10 @@ module Steep
|
|
3070
3227
|
end
|
3071
3228
|
end
|
3072
3229
|
expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
3073
|
-
if
|
3074
|
-
|
3230
|
+
if name != :new
|
3231
|
+
if method.implemented_in == module_context.module_definition.type_name
|
3232
|
+
set << name
|
3233
|
+
end
|
3075
3234
|
end
|
3076
3235
|
end
|
3077
3236
|
|
@@ -3172,6 +3331,14 @@ module Steep
|
|
3172
3331
|
!nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
|
3173
3332
|
end
|
3174
3333
|
|
3334
|
+
def type_any_rec(node)
|
3335
|
+
add_typing node, type: AST::Builtin.any_type
|
3336
|
+
|
3337
|
+
each_child_node(node) do |child|
|
3338
|
+
type_any_rec(child)
|
3339
|
+
end
|
3340
|
+
end
|
3341
|
+
|
3175
3342
|
def fallback_any_rec(node)
|
3176
3343
|
fallback_to_any(node) unless typing.has_type?(node)
|
3177
3344
|
|
@@ -3324,6 +3491,8 @@ module Steep
|
|
3324
3491
|
end
|
3325
3492
|
|
3326
3493
|
def try_hash_type(node, hint)
|
3494
|
+
hint = expand_alias(hint)
|
3495
|
+
|
3327
3496
|
case hint
|
3328
3497
|
when AST::Types::Record
|
3329
3498
|
typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
|