steep 0.34.0 → 0.39.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 +31 -0
- data/lib/steep.rb +6 -0
- data/lib/steep/ast/types/bot.rb +1 -1
- data/lib/steep/ast/types/factory.rb +122 -53
- data/lib/steep/ast/types/logic.rb +33 -1
- data/lib/steep/ast/types/proc.rb +32 -20
- data/lib/steep/ast/types/top.rb +1 -1
- data/lib/steep/cli.rb +2 -2
- data/lib/steep/drivers/print_project.rb +11 -0
- data/lib/steep/drivers/vendor.rb +1 -20
- data/lib/steep/errors.rb +67 -38
- 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 +32 -812
- data/lib/steep/project/dsl.rb +13 -17
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/target.rb +21 -12
- data/lib/steep/server/master.rb +5 -1
- data/lib/steep/server/signature_worker.rb +63 -6
- data/lib/steep/signature/errors.rb +51 -5
- data/lib/steep/signature/validator.rb +28 -4
- data/lib/steep/subtyping/check.rb +72 -34
- data/lib/steep/subtyping/variable_occurrence.rb +2 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +308 -152
- 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/logic_type_interpreter.rb +102 -26
- data/lib/steep/typing.rb +8 -2
- data/lib/steep/version.rb +1 -1
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/smoke/type_case/a.rb +1 -1
- data/steep.gemspec +1 -1
- metadata +12 -5
@@ -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
|
|
@@ -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)
|
@@ -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
|
)
|
@@ -400,6 +399,9 @@ module Steep
|
|
400
399
|
|
401
400
|
instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
|
402
401
|
module_type = AST::Types::Name::Singleton.new(name: class_name)
|
402
|
+
else
|
403
|
+
instance_type = AST::Builtin::Object.instance_type
|
404
|
+
module_type = AST::Builtin::Object.module_type
|
403
405
|
end
|
404
406
|
|
405
407
|
if annots.instance_type
|
@@ -643,7 +645,7 @@ module Steep
|
|
643
645
|
Pair.new(type: call.return_type, constr: self)
|
644
646
|
end
|
645
647
|
|
646
|
-
def synthesize(node, hint: nil)
|
648
|
+
def synthesize(node, hint: nil, condition: false)
|
647
649
|
Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
|
648
650
|
Steep.logger.debug node.type
|
649
651
|
case node.type
|
@@ -880,9 +882,7 @@ module Steep
|
|
880
882
|
new.typing.add_context_for_node(node, context: new.context)
|
881
883
|
new.typing.add_context_for_body(node, context: new.context)
|
882
884
|
|
883
|
-
|
884
|
-
_, new = new.synthesize(arg)
|
885
|
-
end
|
885
|
+
new = new.synthesize_children(args_node)
|
886
886
|
|
887
887
|
body_pair = if body_node
|
888
888
|
return_type = expand_alias(new.method_context&.return_type)
|
@@ -937,14 +937,17 @@ module Steep
|
|
937
937
|
checker.factory.definition_builder.build_singleton(name)
|
938
938
|
end
|
939
939
|
|
940
|
+
args_node = node.children[2]
|
940
941
|
new = for_new_method(node.children[1],
|
941
942
|
node,
|
942
|
-
args:
|
943
|
+
args: args_node.children,
|
943
944
|
self_type: self_type,
|
944
945
|
definition: definition)
|
945
946
|
new.typing.add_context_for_node(node, context: new.context)
|
946
947
|
new.typing.add_context_for_body(node, context: new.context)
|
947
948
|
|
949
|
+
new = new.synthesize_children(args_node)
|
950
|
+
|
948
951
|
each_child_node(node.children[2]) do |arg|
|
949
952
|
new.synthesize(arg)
|
950
953
|
end
|
@@ -1013,22 +1016,30 @@ module Steep
|
|
1013
1016
|
value = node.children[0]
|
1014
1017
|
|
1015
1018
|
if break_context
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1019
|
+
if break_type = break_context.break_type
|
1020
|
+
if value
|
1021
|
+
check(value, break_type) do |break_type, actual_type, result|
|
1022
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1023
|
+
expected: break_type,
|
1024
|
+
actual: actual_type,
|
1025
|
+
result: result)
|
1026
|
+
end
|
1027
|
+
else
|
1028
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: break_type).else do |result|
|
1029
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1030
|
+
expected: break_type,
|
1031
|
+
actual: AST::Builtin.nil_type,
|
1032
|
+
result: result)
|
1033
|
+
end
|
1023
1034
|
end
|
1024
|
-
when !value
|
1025
|
-
# ok
|
1026
1035
|
else
|
1027
|
-
|
1028
|
-
|
1036
|
+
if value
|
1037
|
+
synthesize(value)
|
1038
|
+
typing.add_error Errors::UnexpectedJumpValue.new(node: node)
|
1039
|
+
end
|
1029
1040
|
end
|
1030
1041
|
else
|
1031
|
-
synthesize(value)
|
1042
|
+
synthesize(value) if value
|
1032
1043
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
1033
1044
|
end
|
1034
1045
|
|
@@ -1038,22 +1049,32 @@ module Steep
|
|
1038
1049
|
value = node.children[0]
|
1039
1050
|
|
1040
1051
|
if break_context
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1052
|
+
if next_type = break_context.next_type
|
1053
|
+
next_type = deep_expand_alias(next_type)
|
1054
|
+
|
1055
|
+
if value
|
1056
|
+
_, constr = check(value, next_type) do |break_type, actual_type, result|
|
1057
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1058
|
+
expected: break_type,
|
1059
|
+
actual: actual_type,
|
1060
|
+
result: result)
|
1061
|
+
end
|
1062
|
+
else
|
1063
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: next_type).else do |result|
|
1064
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
1065
|
+
expected: next_type,
|
1066
|
+
actual: AST::Builtin.nil_type,
|
1067
|
+
result: result)
|
1068
|
+
end
|
1048
1069
|
end
|
1049
|
-
when !value
|
1050
|
-
# ok
|
1051
1070
|
else
|
1052
|
-
|
1053
|
-
|
1071
|
+
if value
|
1072
|
+
synthesize(value)
|
1073
|
+
typing.add_error Errors::UnexpectedJumpValue.new(node: node)
|
1074
|
+
end
|
1054
1075
|
end
|
1055
1076
|
else
|
1056
|
-
synthesize(value)
|
1077
|
+
synthesize(value) if value
|
1057
1078
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
1058
1079
|
end
|
1059
1080
|
|
@@ -1074,10 +1095,6 @@ module Steep
|
|
1074
1095
|
add_typing(node, type: type)
|
1075
1096
|
else
|
1076
1097
|
type = AST::Builtin.any_type
|
1077
|
-
if context&.method_context&.method_type
|
1078
|
-
Steep.logger.error { "Unknown arg type: #{node}" }
|
1079
|
-
end
|
1080
|
-
|
1081
1098
|
lvasgn(node, type)
|
1082
1099
|
end
|
1083
1100
|
end
|
@@ -1251,13 +1268,32 @@ module Steep
|
|
1251
1268
|
constr = self
|
1252
1269
|
|
1253
1270
|
name, sup, _ = node.children
|
1254
|
-
|
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
|
1255
1279
|
_, constr = constr.synthesize(sup) if sup
|
1256
1280
|
|
1257
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
|
+
|
1258
1293
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1259
1294
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1260
1295
|
|
1296
|
+
constructor.synthesize(node.children[1]) if node.children[1]
|
1261
1297
|
constructor.synthesize(node.children[2]) if node.children[2]
|
1262
1298
|
|
1263
1299
|
if constructor.module_context&.implement_name && !namespace_module?(node)
|
@@ -1276,6 +1312,11 @@ module Steep
|
|
1276
1312
|
_, constr = constr.synthesize(name)
|
1277
1313
|
|
1278
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
|
+
|
1279
1320
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1280
1321
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1281
1322
|
|
@@ -1336,6 +1377,10 @@ module Steep
|
|
1336
1377
|
const_name = constr.module_name_from_node(node)
|
1337
1378
|
|
1338
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
|
+
|
1339
1384
|
type = type_env.get(const: const_name) do
|
1340
1385
|
constr.fallback_to_any(node)
|
1341
1386
|
end
|
@@ -1353,6 +1398,10 @@ module Steep
|
|
1353
1398
|
const_name = constr.module_name_from_node(node)
|
1354
1399
|
|
1355
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
|
+
|
1356
1405
|
const_type = type_env.get(const: const_name) {}
|
1357
1406
|
value_type, constr = constr.synthesize(node.children.last, hint: const_type)
|
1358
1407
|
type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
|
@@ -1404,7 +1453,7 @@ module Steep
|
|
1404
1453
|
if method_context&.method
|
1405
1454
|
if method_context.super_method
|
1406
1455
|
types = method_context.super_method.method_types.map {|method_type|
|
1407
|
-
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]).return_type
|
1456
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]).type.return_type
|
1408
1457
|
}
|
1409
1458
|
add_typing(node, type: union_type(*types))
|
1410
1459
|
else
|
@@ -1465,67 +1514,89 @@ module Steep
|
|
1465
1514
|
yield_self do
|
1466
1515
|
left, right = node.children
|
1467
1516
|
|
1468
|
-
left_type, constr = synthesize(left)
|
1517
|
+
left_type, constr = synthesize(left, hint: hint, condition: true)
|
1469
1518
|
|
1470
1519
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1471
1520
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1472
1521
|
|
1522
|
+
if left_type.is_a?(AST::Types::Logic::Env)
|
1523
|
+
left_type = left_type.type
|
1524
|
+
end
|
1525
|
+
|
1473
1526
|
right_type, constr = constr
|
1474
1527
|
.update_lvar_env { truthy_env }
|
1475
1528
|
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1476
1529
|
.for_branch(right)
|
1477
|
-
.synthesize(right)
|
1530
|
+
.synthesize(right, hint: hint, condition: true)
|
1478
1531
|
|
1479
|
-
|
1532
|
+
truthy_env, _ = interpreter.eval(env: constr.context.lvar_env, type: right_type, node: right)
|
1533
|
+
|
1534
|
+
env = if right_type.is_a?(AST::Types::Bot)
|
1535
|
+
falsey_env
|
1536
|
+
else
|
1537
|
+
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1538
|
+
end
|
1539
|
+
|
1540
|
+
type = case
|
1541
|
+
when check_relation(sub_type: left_type, super_type: AST::Types::Boolean.new).success?
|
1480
1542
|
union_type(left_type, right_type)
|
1481
1543
|
else
|
1482
1544
|
union_type(right_type, AST::Builtin.nil_type)
|
1483
1545
|
end
|
1484
1546
|
|
1547
|
+
type = AST::Types::Logic::Env.new(truthy: truthy_env, falsy: env, type: type) if condition
|
1548
|
+
|
1485
1549
|
add_typing(node,
|
1486
1550
|
type: type,
|
1487
|
-
constr: constr.update_lvar_env
|
1488
|
-
if right_type.is_a?(AST::Types::Bot)
|
1489
|
-
falsey_env
|
1490
|
-
else
|
1491
|
-
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1492
|
-
end
|
1493
|
-
end)
|
1551
|
+
constr: constr.update_lvar_env { env })
|
1494
1552
|
end
|
1495
1553
|
|
1496
1554
|
when :or
|
1497
1555
|
yield_self do
|
1498
1556
|
left, right = node.children
|
1499
1557
|
|
1500
|
-
left_type, constr = synthesize(left, hint: hint)
|
1558
|
+
left_type, constr = synthesize(left, hint: hint, condition: true)
|
1501
1559
|
|
1502
1560
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1503
1561
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1504
1562
|
|
1505
|
-
|
1563
|
+
if left_type.is_a?(AST::Types::Logic::Env)
|
1564
|
+
left_type = left_type.type
|
1565
|
+
end
|
1566
|
+
left_type, _ = checker.factory.unwrap_optional(left_type)
|
1567
|
+
|
1506
1568
|
right_type, constr = constr
|
1507
1569
|
.update_lvar_env { falsey_env }
|
1508
1570
|
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1509
1571
|
.for_branch(right)
|
1510
|
-
.synthesize(right, hint:
|
1572
|
+
.synthesize(right, hint: left_type, condition: true)
|
1511
1573
|
|
1512
|
-
|
1574
|
+
_, falsey_env = interpreter.eval(env: falsey_env, type: right_type, node: right)
|
1575
|
+
|
1576
|
+
env = if right_type.is_a?(AST::Types::Bot)
|
1577
|
+
truthy_env
|
1578
|
+
else
|
1579
|
+
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
type = case
|
1583
|
+
when check_relation(sub_type: left_type, super_type: AST::Builtin.bool_type).success?
|
1584
|
+
AST::Builtin.bool_type
|
1585
|
+
else
|
1586
|
+
union_type(left_type, right_type)
|
1587
|
+
end
|
1513
1588
|
|
1589
|
+
type = AST::Types::Logic::Env.new(truthy: env, falsy: falsey_env, type: type) if condition
|
1590
|
+
|
1514
1591
|
add_typing(node,
|
1515
1592
|
type: type,
|
1516
|
-
constr: constr.update_lvar_env
|
1517
|
-
if right_type.is_a?(AST::Types::Bot)
|
1518
|
-
truthy_env
|
1519
|
-
else
|
1520
|
-
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1521
|
-
end
|
1522
|
-
end)
|
1593
|
+
constr: constr.update_lvar_env { env })
|
1523
1594
|
end
|
1524
1595
|
|
1525
1596
|
when :if
|
1526
1597
|
cond, true_clause, false_clause = node.children
|
1527
1598
|
|
1528
|
-
cond_type, constr = synthesize(cond)
|
1599
|
+
cond_type, constr = synthesize(cond, condition: true)
|
1529
1600
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
|
1530
1601
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: cond_type, node: cond)
|
1531
1602
|
|
@@ -1584,6 +1655,18 @@ module Steep
|
|
1584
1655
|
|
1585
1656
|
cond_type, constr = constr.synthesize(cond)
|
1586
1657
|
_, cond_vars = interpreter.decompose_value(cond)
|
1658
|
+
unless cond_vars.empty?
|
1659
|
+
first_var = cond_vars.to_a[0]
|
1660
|
+
var_node = cond.updated(
|
1661
|
+
:lvar,
|
1662
|
+
[
|
1663
|
+
ASTUtils::Labeling::LabeledName.new(name: first_var, label: 0)
|
1664
|
+
]
|
1665
|
+
)
|
1666
|
+
else
|
1667
|
+
first_var = nil
|
1668
|
+
var_node = cond
|
1669
|
+
end
|
1587
1670
|
|
1588
1671
|
when_constr = constr
|
1589
1672
|
whens.each do |clause|
|
@@ -1593,9 +1676,16 @@ module Steep
|
|
1593
1676
|
test_envs = []
|
1594
1677
|
|
1595
1678
|
tests.each do |test|
|
1596
|
-
test_node = test.updated(:send, [test, :===,
|
1597
|
-
test_type, test_constr = test_constr.synthesize(test_node)
|
1679
|
+
test_node = test.updated(:send, [test, :===, var_node])
|
1680
|
+
test_type, test_constr = test_constr.synthesize(test_node, condition: true)
|
1598
1681
|
truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
|
1682
|
+
truthy_env = cond_vars.inject(truthy_env) do |env, var|
|
1683
|
+
env.assign!(var, node: test_node, type: env[first_var])
|
1684
|
+
end
|
1685
|
+
falsy_env = cond_vars.inject(falsy_env) do |env, var|
|
1686
|
+
env.assign!(var, node: test_node, type: env[first_var])
|
1687
|
+
end
|
1688
|
+
|
1599
1689
|
test_envs << truthy_env
|
1600
1690
|
test_constr = test_constr.update_lvar_env { falsy_env }
|
1601
1691
|
end
|
@@ -1625,10 +1715,6 @@ module Steep
|
|
1625
1715
|
types = branch_pairs.map(&:type)
|
1626
1716
|
constrs = branch_pairs.map(&:constr)
|
1627
1717
|
|
1628
|
-
unless els
|
1629
|
-
constrs << when_constr
|
1630
|
-
end
|
1631
|
-
|
1632
1718
|
if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
|
1633
1719
|
# Exhaustive
|
1634
1720
|
if els
|
@@ -1636,6 +1722,7 @@ module Steep
|
|
1636
1722
|
end
|
1637
1723
|
else
|
1638
1724
|
unless els
|
1725
|
+
constrs << when_constr
|
1639
1726
|
types << AST::Builtin.nil_type
|
1640
1727
|
end
|
1641
1728
|
end
|
@@ -1643,21 +1730,20 @@ module Steep
|
|
1643
1730
|
branch_pairs = []
|
1644
1731
|
|
1645
1732
|
when_constr = constr
|
1733
|
+
clause_constr = constr
|
1646
1734
|
|
1647
1735
|
whens.each do |clause|
|
1648
1736
|
*tests, body = clause.children
|
1649
1737
|
|
1650
1738
|
test_constr = when_constr
|
1651
|
-
test_envs = []
|
1652
1739
|
|
1653
1740
|
tests.each do |test|
|
1654
|
-
test_type, test_constr = test_constr.synthesize(test)
|
1741
|
+
test_type, test_constr = test_constr.synthesize(test, condition: true)
|
1655
1742
|
truthy_env, falsy_env = interpreter.eval(env: test_constr.context.lvar_env, type: test_type, node: test)
|
1656
|
-
|
1743
|
+
clause_constr = clause_constr.update_lvar_env { truthy_env }
|
1657
1744
|
test_constr = test_constr.update_lvar_env { falsy_env }
|
1658
1745
|
end
|
1659
1746
|
|
1660
|
-
clause_constr = when_constr.update_lvar_env {|env| env.join(*test_envs) }
|
1661
1747
|
when_constr = test_constr
|
1662
1748
|
|
1663
1749
|
if body
|
@@ -1831,7 +1917,7 @@ module Steep
|
|
1831
1917
|
when :while, :until
|
1832
1918
|
yield_self do
|
1833
1919
|
cond, body = node.children
|
1834
|
-
cond_type, constr = synthesize(cond)
|
1920
|
+
cond_type, constr = synthesize(cond, condition: true)
|
1835
1921
|
|
1836
1922
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1837
1923
|
truthy_env, falsy_env = interpreter.eval(env: constr.context.lvar_env, node: cond, type: cond_type)
|
@@ -1995,17 +2081,25 @@ module Steep
|
|
1995
2081
|
if hint.is_a?(AST::Types::Proc) && value.type == :sym
|
1996
2082
|
if hint.one_arg?
|
1997
2083
|
# Assumes Symbol#to_proc implementation
|
1998
|
-
param_type = hint.params.required[0]
|
2084
|
+
param_type = hint.type.params.required[0]
|
1999
2085
|
interface = checker.factory.interface(param_type, private: true)
|
2000
2086
|
method = interface.methods[value.children[0]]
|
2001
2087
|
if method
|
2002
2088
|
return_types = method.method_types.select {|method_type|
|
2003
|
-
method_type.params.
|
2004
|
-
}.map
|
2089
|
+
method_type.type.params.empty?
|
2090
|
+
}.map {|method_type|
|
2091
|
+
method_type.type.return_type
|
2092
|
+
}
|
2005
2093
|
|
2006
2094
|
unless return_types.empty?
|
2007
|
-
type = AST::Types::Proc.new(
|
2008
|
-
|
2095
|
+
type = AST::Types::Proc.new(
|
2096
|
+
type: Interface::Function.new(
|
2097
|
+
params: Interface::Function::Params.empty.update(required: [param_type]),
|
2098
|
+
return_type: AST::Types::Union.build(types: return_types),
|
2099
|
+
location: nil
|
2100
|
+
),
|
2101
|
+
block: nil
|
2102
|
+
)
|
2009
2103
|
end
|
2010
2104
|
end
|
2011
2105
|
else
|
@@ -2070,7 +2164,12 @@ module Steep
|
|
2070
2164
|
|
2071
2165
|
when :splat
|
2072
2166
|
yield_self do
|
2073
|
-
|
2167
|
+
typing.add_error(
|
2168
|
+
Errors::UnsupportedSyntax.new(
|
2169
|
+
node: node,
|
2170
|
+
message: "Unsupported splat node occurrence"
|
2171
|
+
)
|
2172
|
+
)
|
2074
2173
|
|
2075
2174
|
each_child_node node do |child|
|
2076
2175
|
synthesize(child)
|
@@ -2089,7 +2188,7 @@ module Steep
|
|
2089
2188
|
add_typing node, type: AST::Builtin.any_type, constr: constr
|
2090
2189
|
|
2091
2190
|
else
|
2092
|
-
|
2191
|
+
typing.add_error(Errors::UnsupportedSyntax.new(node: node))
|
2093
2192
|
|
2094
2193
|
end.tap do |pair|
|
2095
2194
|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
@@ -2335,13 +2434,14 @@ module Steep
|
|
2335
2434
|
|
2336
2435
|
case type_hint
|
2337
2436
|
when AST::Types::Proc
|
2338
|
-
params_hint = type_hint.params
|
2339
|
-
return_hint = type_hint.return_type
|
2437
|
+
params_hint = type_hint.type.params
|
2438
|
+
return_hint = type_hint.type.return_type
|
2340
2439
|
end
|
2341
2440
|
|
2342
2441
|
block_constr = for_block(
|
2343
2442
|
block_params: params,
|
2344
2443
|
block_param_hint: params_hint,
|
2444
|
+
block_type_hint: return_hint,
|
2345
2445
|
block_annotations: block_annotations,
|
2346
2446
|
node_type_hint: nil
|
2347
2447
|
)
|
@@ -2356,18 +2456,34 @@ module Steep
|
|
2356
2456
|
return_type = block_constr.synthesize_block(
|
2357
2457
|
node: node,
|
2358
2458
|
block_body: block_body,
|
2359
|
-
topdown_hint: true,
|
2360
2459
|
block_type_hint: return_hint
|
2361
|
-
)
|
2362
|
-
|
2460
|
+
)
|
2461
|
+
|
2462
|
+
if expected_block_type = block_constr.block_context.body_type
|
2463
|
+
check_relation(sub_type: return_type, super_type: expected_block_type).else do |result|
|
2464
|
+
block_constr.typing.add_error(
|
2465
|
+
Errors::BlockBodyTypeMismatch.new(
|
2466
|
+
node: block_body,
|
2467
|
+
expected: expected_block_type,
|
2468
|
+
actual: return_type,
|
2469
|
+
result: result
|
2470
|
+
)
|
2471
|
+
)
|
2472
|
+
|
2473
|
+
return_type = expected_block_type
|
2474
|
+
end
|
2363
2475
|
end
|
2364
2476
|
else
|
2365
2477
|
return_type = AST::Builtin.any_type
|
2366
2478
|
end
|
2367
2479
|
|
2368
2480
|
block_type = AST::Types::Proc.new(
|
2369
|
-
|
2370
|
-
|
2481
|
+
type: Interface::Function.new(
|
2482
|
+
params: params_hint || params.params_type,
|
2483
|
+
return_type: return_type,
|
2484
|
+
location: nil
|
2485
|
+
),
|
2486
|
+
block: nil
|
2371
2487
|
)
|
2372
2488
|
|
2373
2489
|
add_typing node, type: block_type
|
@@ -2423,7 +2539,10 @@ module Steep
|
|
2423
2539
|
errors: [error]
|
2424
2540
|
)
|
2425
2541
|
|
2426
|
-
|
2542
|
+
skips = [receiver]
|
2543
|
+
skips << node.children[0] if node.type == :block
|
2544
|
+
|
2545
|
+
constr = synthesize_children(node, skips: skips)
|
2427
2546
|
if block_params
|
2428
2547
|
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2429
2548
|
|
@@ -2432,15 +2551,31 @@ module Steep
|
|
2432
2551
|
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2433
2552
|
block_annotations: block_annotations,
|
2434
2553
|
block_body: block_body
|
2435
|
-
)
|
2436
|
-
errors << error
|
2437
|
-
end
|
2554
|
+
)
|
2438
2555
|
end
|
2439
2556
|
end
|
2440
2557
|
|
2441
2558
|
constr.add_call(call)
|
2442
2559
|
else
|
2443
|
-
|
2560
|
+
skips = []
|
2561
|
+
skips << receiver if receiver
|
2562
|
+
skips << node.children[0] if node.type == :block
|
2563
|
+
skips << block_params if block_params
|
2564
|
+
skips << block_body if block_body
|
2565
|
+
|
2566
|
+
constr = synthesize_children(node, skips: skips)
|
2567
|
+
if block_params
|
2568
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2569
|
+
|
2570
|
+
constr.type_block_without_hint(
|
2571
|
+
node: node,
|
2572
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2573
|
+
block_annotations: block_annotations,
|
2574
|
+
block_body: block_body
|
2575
|
+
)
|
2576
|
+
end
|
2577
|
+
|
2578
|
+
constr.add_call(
|
2444
2579
|
TypeInference::MethodCall::NoMethodError.new(
|
2445
2580
|
node: node,
|
2446
2581
|
context: context.method_context,
|
@@ -2570,7 +2705,7 @@ module Steep
|
|
2570
2705
|
|
2571
2706
|
results = method.method_types.flat_map do |method_type|
|
2572
2707
|
Steep.logger.tagged method_type.to_s do
|
2573
|
-
zips = args.zips(method_type.params, method_type.block&.type)
|
2708
|
+
zips = args.zips(method_type.type.params, method_type.block&.type)
|
2574
2709
|
|
2575
2710
|
zips.map do |arg_pairs|
|
2576
2711
|
typing.new_child(node_range) do |child_typing|
|
@@ -2602,7 +2737,7 @@ module Steep
|
|
2602
2737
|
context: context.method_context,
|
2603
2738
|
method_name: method_name,
|
2604
2739
|
receiver_type: receiver_type,
|
2605
|
-
return_type: method_type.return_type,
|
2740
|
+
return_type: method_type.type.return_type,
|
2606
2741
|
errors: [error],
|
2607
2742
|
method_decls: all_decls
|
2608
2743
|
)
|
@@ -2625,7 +2760,7 @@ module Steep
|
|
2625
2760
|
end
|
2626
2761
|
|
2627
2762
|
def check_keyword_arg(receiver_type:, node:, method_type:, constraints:)
|
2628
|
-
params = method_type.params
|
2763
|
+
params = method_type.type.params
|
2629
2764
|
|
2630
2765
|
case node.type
|
2631
2766
|
when :hash
|
@@ -2727,7 +2862,7 @@ module Steep
|
|
2727
2862
|
)
|
2728
2863
|
else
|
2729
2864
|
hash_elements = params.required_keywords.merge(
|
2730
|
-
|
2865
|
+
params.optional_keywords.transform_values do |type|
|
2731
2866
|
AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2732
2867
|
end
|
2733
2868
|
)
|
@@ -2809,8 +2944,9 @@ module Steep
|
|
2809
2944
|
block_constr = constr.for_block(
|
2810
2945
|
block_params: block_params_,
|
2811
2946
|
block_param_hint: method_type.block.type.params,
|
2947
|
+
block_type_hint: method_type.block.type.return_type,
|
2812
2948
|
block_annotations: block_annotations,
|
2813
|
-
node_type_hint: method_type.return_type
|
2949
|
+
node_type_hint: method_type.type.return_type
|
2814
2950
|
)
|
2815
2951
|
block_constr = block_constr.with_new_typing(
|
2816
2952
|
block_constr.typing.new_child(
|
@@ -2840,19 +2976,16 @@ module Steep
|
|
2840
2976
|
checker,
|
2841
2977
|
self_type: self_type,
|
2842
2978
|
variance: variance,
|
2843
|
-
variables: method_type.params.free_variables + method_type.block.type.params.free_variables
|
2979
|
+
variables: method_type.type.params.free_variables + method_type.block.type.params.free_variables
|
2844
2980
|
)
|
2845
2981
|
method_type = method_type.subst(s)
|
2846
2982
|
block_constr = block_constr.update_lvar_env {|env| env.subst(s) }
|
2847
2983
|
if block_body
|
2848
2984
|
block_body_type = block_constr.synthesize_block(
|
2849
2985
|
node: node,
|
2850
|
-
block_type_hint: method_type.block.type.return_type,
|
2851
2986
|
block_body: block_body,
|
2852
|
-
|
2853
|
-
)
|
2854
|
-
errors << error
|
2855
|
-
end
|
2987
|
+
block_type_hint: method_type.block.type.return_type
|
2988
|
+
)
|
2856
2989
|
else
|
2857
2990
|
block_body_type = AST::Builtin.nil_type
|
2858
2991
|
end
|
@@ -2866,25 +2999,40 @@ module Steep
|
|
2866
2999
|
s = constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)
|
2867
3000
|
method_type = method_type.subst(s)
|
2868
3001
|
|
2869
|
-
return_type = method_type.return_type
|
3002
|
+
return_type = method_type.type.return_type
|
2870
3003
|
if break_type = block_annotations.break_type
|
2871
3004
|
return_type = union_type(break_type, return_type)
|
2872
3005
|
end
|
2873
3006
|
|
2874
3007
|
when Subtyping::Result::Failure
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
3008
|
+
given_block_type = AST::Types::Proc.new(
|
3009
|
+
type: Interface::Function.new(
|
3010
|
+
params: method_type.block.type.params || block_params.params_type,
|
3011
|
+
return_type: block_body_type,
|
3012
|
+
location: nil
|
3013
|
+
),
|
3014
|
+
block: nil
|
3015
|
+
)
|
3016
|
+
|
3017
|
+
method_block_type = AST::Types::Proc.new(
|
3018
|
+
type: Interface::Function.new(
|
3019
|
+
params: method_type.block.type.params,
|
3020
|
+
return_type: method_type.block.type.return_type,
|
3021
|
+
location: nil
|
3022
|
+
),
|
3023
|
+
block: nil
|
2878
3024
|
)
|
3025
|
+
|
2879
3026
|
errors << Errors::BlockTypeMismatch.new(node: node,
|
2880
|
-
expected:
|
2881
|
-
actual:
|
3027
|
+
expected: method_block_type,
|
3028
|
+
actual: given_block_type,
|
2882
3029
|
result: result)
|
2883
3030
|
|
2884
|
-
return_type = method_type.return_type
|
3031
|
+
return_type = method_type.type.return_type
|
2885
3032
|
end
|
2886
3033
|
|
2887
3034
|
block_constr.typing.save!
|
3035
|
+
|
2888
3036
|
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
2889
3037
|
errors << Errors::UnsatisfiableConstraint.new(
|
2890
3038
|
node: node,
|
@@ -2955,23 +3103,24 @@ module Steep
|
|
2955
3103
|
else
|
2956
3104
|
begin
|
2957
3105
|
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params))
|
2958
|
-
|
2959
|
-
|
2960
|
-
|
2961
|
-
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
2965
|
-
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
3106
|
+
hint_type = if topdown_hint
|
3107
|
+
AST::Types::Proc.new(type: method_type.block.type, block: nil)
|
3108
|
+
end
|
3109
|
+
given_block_type, constr = constr.synthesize(args.block_pass_arg, hint: hint_type)
|
3110
|
+
method_block_type = method_type.block.yield_self {|expected_block|
|
3111
|
+
proc_type = AST::Types::Proc.new(type: expected_block.type, block: nil)
|
3112
|
+
if expected_block.optional?
|
3113
|
+
AST::Builtin.optional(proc_type)
|
3114
|
+
else
|
3115
|
+
proc_type
|
3116
|
+
end
|
3117
|
+
}
|
2970
3118
|
|
3119
|
+
result = check_relation(sub_type: given_block_type, super_type: method_block_type, constraints: constraints)
|
2971
3120
|
result.else do |result|
|
2972
3121
|
errors << Errors::BlockTypeMismatch.new(node: node,
|
2973
|
-
expected:
|
2974
|
-
actual:
|
3122
|
+
expected: method_block_type,
|
3123
|
+
actual: given_block_type,
|
2975
3124
|
result: result)
|
2976
3125
|
end
|
2977
3126
|
|
@@ -2988,7 +3137,7 @@ module Steep
|
|
2988
3137
|
receiver_type: receiver_type,
|
2989
3138
|
method_name: method_name,
|
2990
3139
|
actual_method_type: method_type,
|
2991
|
-
return_type: return_type || method_type.return_type,
|
3140
|
+
return_type: return_type || method_type.type.return_type,
|
2992
3141
|
method_decls: method_type.method_decls
|
2993
3142
|
)
|
2994
3143
|
else
|
@@ -2997,7 +3146,7 @@ module Steep
|
|
2997
3146
|
context: context.method_context,
|
2998
3147
|
receiver_type: receiver_type,
|
2999
3148
|
method_name: method_name,
|
3000
|
-
return_type: return_type || method_type.return_type,
|
3149
|
+
return_type: return_type || method_type.type.return_type,
|
3001
3150
|
method_decls: method_type.method_decls,
|
3002
3151
|
errors: errors
|
3003
3152
|
)
|
@@ -3013,8 +3162,9 @@ module Steep
|
|
3013
3162
|
block_constr = for_block(
|
3014
3163
|
block_params: block_params,
|
3015
3164
|
block_param_hint: nil,
|
3165
|
+
block_type_hint: AST::Builtin.any_type,
|
3016
3166
|
block_annotations: block_annotations,
|
3017
|
-
node_type_hint:
|
3167
|
+
node_type_hint: AST::Builtin.any_type
|
3018
3168
|
)
|
3019
3169
|
|
3020
3170
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
@@ -3023,10 +3173,23 @@ module Steep
|
|
3023
3173
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
3024
3174
|
end
|
3025
3175
|
|
3026
|
-
block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body
|
3176
|
+
block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
|
3177
|
+
|
3178
|
+
if expected_block_type = block_constr.block_context.body_type
|
3179
|
+
block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
|
3180
|
+
block_constr.typing.add_error(
|
3181
|
+
Errors::BlockBodyTypeMismatch.new(
|
3182
|
+
node: node,
|
3183
|
+
expected: expected_block_type,
|
3184
|
+
actual: block_type,
|
3185
|
+
result: result
|
3186
|
+
)
|
3187
|
+
)
|
3188
|
+
end
|
3189
|
+
end
|
3027
3190
|
end
|
3028
3191
|
|
3029
|
-
def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
|
3192
|
+
def for_block(block_params:, block_param_hint:, block_type_hint:, block_annotations:, node_type_hint:)
|
3030
3193
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
3031
3194
|
|
3032
3195
|
param_types_hash = {}
|
@@ -3058,7 +3221,7 @@ module Steep
|
|
3058
3221
|
end
|
3059
3222
|
|
3060
3223
|
block_context = TypeInference::Context::BlockContext.new(
|
3061
|
-
body_type: block_annotations.block_type
|
3224
|
+
body_type: block_annotations.block_type || block_type_hint || AST::Builtin.any_type
|
3062
3225
|
)
|
3063
3226
|
break_context = TypeInference::Context::BreakContext.new(
|
3064
3227
|
break_type: break_type,
|
@@ -3083,20 +3246,9 @@ module Steep
|
|
3083
3246
|
)
|
3084
3247
|
end
|
3085
3248
|
|
3086
|
-
def synthesize_block(node:, block_type_hint:, block_body
|
3249
|
+
def synthesize_block(node:, block_type_hint:, block_body:)
|
3087
3250
|
if block_body
|
3088
|
-
body_type, _, context =
|
3089
|
-
if (body_type = block_context.body_type)
|
3090
|
-
check(block_body, body_type) do |expected, actual, result|
|
3091
|
-
error = Errors::BlockTypeMismatch.new(node: block_body,
|
3092
|
-
expected: expected,
|
3093
|
-
actual: actual,
|
3094
|
-
result: result)
|
3095
|
-
yield(error) if block_given?
|
3096
|
-
end
|
3097
|
-
else
|
3098
|
-
synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
3099
|
-
end
|
3251
|
+
body_type, _, context = synthesize(block_body, hint: block_context.body_type || block_type_hint)
|
3100
3252
|
|
3101
3253
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
3102
3254
|
typing.add_context(range, context: context)
|
@@ -3189,7 +3341,7 @@ module Steep
|
|
3189
3341
|
if module_name.namespace.relative?
|
3190
3342
|
(current_namespace + module_name.namespace).append(module_name.name)
|
3191
3343
|
else
|
3192
|
-
module_name
|
3344
|
+
module_name.to_namespace
|
3193
3345
|
end
|
3194
3346
|
end
|
3195
3347
|
|
@@ -3224,8 +3376,10 @@ module Steep
|
|
3224
3376
|
end
|
3225
3377
|
end
|
3226
3378
|
expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
3227
|
-
if
|
3228
|
-
|
3379
|
+
if name != :new
|
3380
|
+
if method.implemented_in == module_context.module_definition.type_name
|
3381
|
+
set << name
|
3382
|
+
end
|
3229
3383
|
end
|
3230
3384
|
end
|
3231
3385
|
|
@@ -3486,6 +3640,8 @@ module Steep
|
|
3486
3640
|
end
|
3487
3641
|
|
3488
3642
|
def try_hash_type(node, hint)
|
3643
|
+
hint = expand_alias(hint)
|
3644
|
+
|
3489
3645
|
case hint
|
3490
3646
|
when AST::Types::Record
|
3491
3647
|
typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
|