steep 1.0.0 → 1.1.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-windows.yml +34 -0
- data/.github/workflows/ruby.yml +7 -2
- data/.gitignore +1 -0
- data/CHANGELOG.md +59 -0
- data/Gemfile +7 -4
- data/Gemfile.lock +17 -21
- data/Gemfile.steep +3 -0
- data/Gemfile.steep.lock +49 -0
- data/Rakefile +5 -0
- data/Steepfile +6 -1
- data/bin/setup +2 -0
- data/bin/steep +19 -0
- data/lib/steep/ast/builtin.rb +2 -2
- data/lib/steep/ast/types/factory.rb +7 -3
- data/lib/steep/ast/types/proc.rb +2 -0
- data/lib/steep/cli.rb +3 -1
- data/lib/steep/diagnostic/ruby.rb +50 -4
- data/lib/steep/diagnostic/signature.rb +18 -0
- data/lib/steep/drivers/check.rb +3 -3
- data/lib/steep/drivers/watch.rb +3 -1
- data/lib/steep/method_name.rb +9 -3
- data/lib/steep/node_helper.rb +49 -0
- data/lib/steep/path_helper.rb +22 -0
- data/lib/steep/project.rb +3 -15
- data/lib/steep/server/base_worker.rb +1 -0
- data/lib/steep/server/change_buffer.rb +1 -1
- data/lib/steep/server/interaction_worker.rb +3 -5
- data/lib/steep/server/master.rb +61 -45
- data/lib/steep/server/type_check_worker.rb +10 -25
- data/lib/steep/services/completion_provider.rb +25 -18
- data/lib/steep/services/goto_service.rb +2 -4
- data/lib/steep/services/hover_provider/rbs.rb +1 -1
- data/lib/steep/services/hover_provider/ruby.rb +30 -12
- data/lib/steep/services/stats_calculator.rb +0 -1
- data/lib/steep/services/type_check_service.rb +15 -12
- data/lib/steep/shims/symbol_start_with.rb +18 -0
- data/lib/steep/signature/validator.rb +25 -1
- data/lib/steep/source.rb +1 -1
- data/lib/steep/subtyping/check.rb +0 -3
- data/lib/steep/subtyping/constraints.rb +43 -14
- data/lib/steep/type_construction.rb +721 -764
- data/lib/steep/type_inference/constant_env.rb +0 -2
- data/lib/steep/type_inference/context.rb +23 -17
- data/lib/steep/type_inference/logic_type_interpreter.rb +210 -117
- data/lib/steep/type_inference/method_call.rb +80 -6
- data/lib/steep/type_inference/multiple_assignment.rb +189 -0
- data/lib/steep/type_inference/send_args.rb +1 -2
- data/lib/steep/type_inference/type_env.rb +273 -116
- data/lib/steep/type_inference/type_env_builder.rb +138 -0
- data/lib/steep/typing.rb +2 -0
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +7 -5
- data/rbs_collection.steep.lock.yaml +112 -0
- data/rbs_collection.steep.yaml +19 -0
- data/sample/sig/conference.rbs +8 -0
- data/sig/shims/parser/source/map.rbs +146 -0
- data/sig/shims/parser/source/range.rbs +237 -0
- data/sig/shims/parser.rbs +17 -0
- data/sig/steep/ast/annotation/collection.rbs +75 -0
- data/sig/steep/ast/annotation.rbs +126 -0
- data/sig/steep/ast/builtin.rbs +69 -0
- data/sig/steep/ast/type_params.rbs +11 -0
- data/sig/steep/ast/types/any.rbs +29 -0
- data/sig/steep/ast/types/boolean.rbs +31 -0
- data/sig/steep/ast/types/bot.rbs +29 -0
- data/sig/steep/ast/types/class.rbs +29 -0
- data/sig/steep/ast/types/factory.rbs +76 -0
- data/sig/steep/ast/types/helper.rbs +19 -0
- data/sig/steep/ast/types/instance.rbs +29 -0
- data/sig/steep/ast/types/intersection.rbs +35 -0
- data/sig/steep/ast/types/literal.rbs +33 -0
- data/sig/steep/ast/types/logic.rbs +78 -0
- data/sig/steep/ast/types/name.rbs +71 -0
- data/sig/steep/ast/types/nil.rbs +31 -0
- data/sig/steep/ast/types/proc.rbs +46 -0
- data/sig/steep/ast/types/record.rbs +38 -0
- data/sig/steep/ast/types/self.rbs +29 -0
- data/sig/steep/ast/types/top.rbs +29 -0
- data/sig/steep/ast/types/tuple.rbs +34 -0
- data/sig/steep/ast/types/union.rbs +38 -0
- data/sig/steep/ast/types/var.rbs +37 -0
- data/sig/steep/ast/types/void.rbs +29 -0
- data/sig/steep/ast/types.rbs +37 -0
- data/sig/steep/diagnostic/deprecated/unknown_constant_assigned.rbs +15 -0
- data/sig/steep/diagnostic/helper.rbs +9 -0
- data/sig/steep/diagnostic/lsp_formatter.rbs +29 -0
- data/sig/steep/diagnostic/ruby.rbs +494 -0
- data/sig/steep/diagnostic/signature.rbs +215 -0
- data/sig/steep/interface/block.rbs +35 -0
- data/sig/steep/interface/function.rbs +253 -0
- data/sig/steep/interface/interface.rbs +23 -0
- data/sig/steep/interface/method_type.rbs +55 -0
- data/sig/steep/interface/substitution.rbs +53 -0
- data/sig/steep/interface/type_param.rbs +35 -0
- data/sig/steep/method_name.rbs +26 -0
- data/sig/steep/module_helper.rbs +7 -0
- data/sig/steep/node_helper.rbs +11 -0
- data/sig/steep/project/dsl.rbs +94 -0
- data/sig/steep/project/options.rbs +15 -0
- data/sig/steep/project/pattern.rbs +25 -0
- data/sig/steep/project/target.rbs +25 -0
- data/sig/steep/project.rbs +19 -0
- data/sig/steep/services/completion_provider.rbs +123 -0
- data/sig/steep/services/content_change.rbs +35 -0
- data/sig/steep/services/file_loader.rbs +13 -0
- data/sig/steep/services/goto_service.rbs +45 -0
- data/sig/steep/services/hover_provider/rbs.rbs +21 -0
- data/sig/steep/services/hover_provider/ruby.rbs +109 -0
- data/sig/steep/services/hover_provider/singleton_methods.rbs +11 -0
- data/sig/steep/services/path_assignment.rbs +21 -0
- data/sig/steep/services/signature_service.rbs +91 -0
- data/sig/steep/services/stats_calculator.rbs +17 -0
- data/sig/steep/services/type_check_service.rbs +93 -0
- data/sig/steep/source.rbs +55 -0
- data/sig/steep/subtyping/cache.rbs +17 -0
- data/sig/steep/subtyping/check.rbs +93 -0
- data/sig/steep/subtyping/constraints.rbs +111 -0
- data/sig/steep/subtyping/relation.rbs +51 -0
- data/sig/steep/subtyping/result.rbs +157 -0
- data/sig/steep/subtyping/variable_variance.rbs +23 -0
- data/sig/steep/type_construction.rbs +285 -0
- data/sig/steep/type_inference/block_params.rbs +52 -0
- data/sig/steep/type_inference/constant_env.rbs +27 -0
- data/sig/steep/type_inference/context.rbs +137 -0
- data/sig/steep/type_inference/logic_type_interpreter.rbs +72 -0
- data/sig/steep/type_inference/method_call.rbs +124 -0
- data/sig/steep/type_inference/method_params.rbs +104 -0
- data/sig/steep/type_inference/multiple_assignment.rbs +76 -0
- data/sig/steep/type_inference/type_env.rbs +158 -0
- data/sig/steep/type_inference/type_env_builder.rbs +77 -0
- data/sig/steep/typing.rbs +68 -0
- data/sig/steep.rbs +31 -0
- data/smoke/class/f.rb +1 -0
- data/smoke/class/test_expectations.yml +2 -2
- data/smoke/diagnostics/test_expectations.yml +4 -2
- data/smoke/regression/lambda.rb +3 -0
- data/smoke/regression/test_expectations.yml +12 -0
- data/steep.gemspec +1 -1
- metadata +95 -9
- data/lib/steep/subtyping/variable_occurrence.rb +0 -51
- data/lib/steep/type_inference/local_variable_type_env.rb +0 -249
- data/lib/steep/type_inference/logic.rb +0 -161
@@ -30,6 +30,13 @@ module Steep
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
include NodeHelper
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
s = "#<%s:%#018x " % [self.class, object_id]
|
37
|
+
s + ">"
|
38
|
+
end
|
39
|
+
|
33
40
|
include ModuleHelper
|
34
41
|
|
35
42
|
attr_reader :checker
|
@@ -59,10 +66,6 @@ module Steep
|
|
59
66
|
context.self_type
|
60
67
|
end
|
61
68
|
|
62
|
-
def type_env
|
63
|
-
context.type_env
|
64
|
-
end
|
65
|
-
|
66
69
|
def variable_context
|
67
70
|
context.variable_context
|
68
71
|
end
|
@@ -85,9 +88,9 @@ module Steep
|
|
85
88
|
)
|
86
89
|
end
|
87
90
|
|
88
|
-
def with_updated_context(
|
89
|
-
|
90
|
-
with(context: self.context.with(
|
91
|
+
def with_updated_context(type_env: self.context.type_env)
|
92
|
+
unless type_env.equal?(self.context.type_env)
|
93
|
+
with(context: self.context.with(type_env: type_env))
|
91
94
|
else
|
92
95
|
self
|
93
96
|
end
|
@@ -111,8 +114,8 @@ module Steep
|
|
111
114
|
with(context: yield(self.context))
|
112
115
|
end
|
113
116
|
|
114
|
-
def
|
115
|
-
with_updated_context(
|
117
|
+
def update_type_env
|
118
|
+
with_updated_context(type_env: yield(context.type_env))
|
116
119
|
end
|
117
120
|
|
118
121
|
def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
|
@@ -129,14 +132,15 @@ module Steep
|
|
129
132
|
end
|
130
133
|
end
|
131
134
|
|
132
|
-
def
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
self.type_env.const_types.each do |name, type|
|
137
|
-
type_env.set(const: name, type: type)
|
135
|
+
def no_subtyping?(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
|
136
|
+
result = check_relation(sub_type: sub_type, super_type: super_type, constraints: constraints)
|
137
|
+
if result.failure?
|
138
|
+
result
|
138
139
|
end
|
140
|
+
end
|
139
141
|
|
142
|
+
def for_new_method(method_name, node, args:, self_type:, definition:)
|
143
|
+
annots = source.annotations(block: node, factory: checker.factory, context: nesting)
|
140
144
|
definition_method_type = if definition
|
141
145
|
definition.methods[method_name]&.yield_self do |method|
|
142
146
|
method.method_types
|
@@ -189,27 +193,6 @@ module Steep
|
|
189
193
|
super_method: super_method
|
190
194
|
)
|
191
195
|
|
192
|
-
if definition
|
193
|
-
definition.instance_variables.each do |name, decl|
|
194
|
-
type_env.set(ivar: name, type: checker.factory.type(decl.type))
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
type_env = type_env.with_annotations(
|
199
|
-
ivar_types: annots.ivar_types,
|
200
|
-
const_types: annots.const_types,
|
201
|
-
self_type: annots.self_type || self_type,
|
202
|
-
instance_type: module_context.instance_type,
|
203
|
-
class_type: module_context.module_type
|
204
|
-
)
|
205
|
-
|
206
|
-
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
207
|
-
subtyping: checker,
|
208
|
-
self_type: annots.self_type || self_type,
|
209
|
-
instance_type: module_context.instance_type,
|
210
|
-
class_type: module_context.module_type
|
211
|
-
)
|
212
|
-
|
213
196
|
method_params =
|
214
197
|
if method_type
|
215
198
|
TypeInference::MethodParams.build(node: node, method_type: method_type)
|
@@ -217,18 +200,33 @@ module Steep
|
|
217
200
|
TypeInference::MethodParams.empty(node: node)
|
218
201
|
end
|
219
202
|
|
220
|
-
method_params.each_param do |param|
|
221
|
-
|
222
|
-
|
223
|
-
|
203
|
+
local_variable_types = method_params.each_param.with_object({}) do |param, hash|
|
204
|
+
if param.name
|
205
|
+
hash[param.name] = param.var_type
|
206
|
+
end
|
224
207
|
end
|
208
|
+
type_env = context.type_env.assign_local_variables(local_variable_types)
|
209
|
+
|
210
|
+
type_env = TypeInference::TypeEnvBuilder.new(
|
211
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots).merge!.on_duplicate! do |name, original, annotated|
|
212
|
+
param = method_params.each_param.find {|param| param.name == name }
|
213
|
+
if result = no_subtyping?(sub_type: original, super_type: annotated)
|
214
|
+
typing.add_error Diagnostic::Ruby::IncompatibleAnnotation.new(
|
215
|
+
node: param.node,
|
216
|
+
var_name: name,
|
217
|
+
result: result,
|
218
|
+
relation: result.relation
|
219
|
+
)
|
220
|
+
end
|
221
|
+
end,
|
222
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(definition, checker.factory),
|
223
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableAnnotations.new(annots).merge!
|
224
|
+
).build(type_env)
|
225
225
|
|
226
226
|
method_params.errors.each do |error|
|
227
227
|
typing.add_error error
|
228
228
|
end
|
229
229
|
|
230
|
-
lvar_env = lvar_env.annotate(annots)
|
231
|
-
|
232
230
|
call_context = case self_type
|
233
231
|
when nil
|
234
232
|
TypeInference::MethodCall::UnknownContext.new()
|
@@ -255,7 +253,6 @@ module Steep
|
|
255
253
|
break_context: nil,
|
256
254
|
self_type: annots.self_type || self_type,
|
257
255
|
type_env: type_env,
|
258
|
-
lvar_env: lvar_env,
|
259
256
|
call_context: call_context,
|
260
257
|
variable_context: variable_context
|
261
258
|
),
|
@@ -295,9 +292,9 @@ module Steep
|
|
295
292
|
end
|
296
293
|
end
|
297
294
|
|
298
|
-
def default_module_context(implement_module_name,
|
295
|
+
def default_module_context(implement_module_name, nesting:)
|
299
296
|
if implement_module_name
|
300
|
-
module_name = checker.factory.absolute_type_name(implement_module_name.name, context:
|
297
|
+
module_name = checker.factory.absolute_type_name(implement_module_name.name, context: nesting)
|
301
298
|
module_args = implement_module_name.args.map {|name| AST::Types::Var.new(name: name) }
|
302
299
|
|
303
300
|
instance_def = checker.factory.definition_builder.build_instance(module_name)
|
@@ -310,7 +307,7 @@ module Steep
|
|
310
307
|
instance_type: instance_type,
|
311
308
|
module_type: module_type,
|
312
309
|
implement_name: implement_module_name,
|
313
|
-
|
310
|
+
nesting: nesting,
|
314
311
|
class_name: module_name,
|
315
312
|
instance_definition: instance_def,
|
316
313
|
module_definition: module_def
|
@@ -320,7 +317,7 @@ module Steep
|
|
320
317
|
instance_type: nil,
|
321
318
|
module_type: nil,
|
322
319
|
implement_name: nil,
|
323
|
-
|
320
|
+
nesting: nesting,
|
324
321
|
class_name: self.module_context.class_name,
|
325
322
|
module_definition: nil,
|
326
323
|
instance_definition: nil
|
@@ -331,16 +328,10 @@ module Steep
|
|
331
328
|
def for_module(node, new_module_name)
|
332
329
|
new_nesting = [nesting, new_module_name || false]
|
333
330
|
|
334
|
-
module_const_env = TypeInference::ConstantEnv.new(
|
335
|
-
factory: checker.factory,
|
336
|
-
context: new_nesting,
|
337
|
-
resolver: self.module_context.const_env.resolver
|
338
|
-
)
|
339
|
-
|
340
331
|
annots = source.annotations(block: node, factory: checker.factory, context: new_nesting)
|
341
332
|
|
342
333
|
implement_module_name = implement_module(module_name: new_module_name, annotations: annots)
|
343
|
-
module_context = default_module_context(implement_module_name,
|
334
|
+
module_context = default_module_context(implement_module_name, nesting: new_nesting)
|
344
335
|
|
345
336
|
unless implement_module_name
|
346
337
|
module_context = module_context.update(
|
@@ -391,18 +382,6 @@ module Steep
|
|
391
382
|
module_context = module_context.update(module_type: annots.self_type)
|
392
383
|
end
|
393
384
|
|
394
|
-
module_type_env = TypeInference::TypeEnv.build(annotations: annots,
|
395
|
-
subtyping: checker,
|
396
|
-
const_env: module_const_env,
|
397
|
-
signatures: checker.factory.env)
|
398
|
-
|
399
|
-
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
400
|
-
subtyping: checker,
|
401
|
-
self_type: module_context.module_type,
|
402
|
-
instance_type: module_context.instance_type,
|
403
|
-
class_type: module_context.module_type
|
404
|
-
).annotate(annots)
|
405
|
-
|
406
385
|
if implement_module_name
|
407
386
|
definition = checker.factory.definition_builder.build_instance(implement_module_name.name)
|
408
387
|
type_params = definition.type_params_decl.map do |param|
|
@@ -418,6 +397,20 @@ module Steep
|
|
418
397
|
variable_context = TypeInference::Context::TypeVariableContext.empty
|
419
398
|
end
|
420
399
|
|
400
|
+
module_const_env = TypeInference::ConstantEnv.new(
|
401
|
+
factory: checker.factory,
|
402
|
+
context: new_nesting,
|
403
|
+
resolver: context.type_env.constant_env.resolver
|
404
|
+
)
|
405
|
+
|
406
|
+
module_type_env = TypeInference::TypeEnvBuilder.new(
|
407
|
+
TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(checker.factory),
|
408
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots),
|
409
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(module_context.module_definition, checker.factory),
|
410
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableAnnotations.new(annots).merge!,
|
411
|
+
TypeInference::TypeEnvBuilder::Command::ImportConstantAnnotations.new(annots)
|
412
|
+
).build(TypeInference::TypeEnv.new(module_const_env))
|
413
|
+
|
421
414
|
self.class.new(
|
422
415
|
checker: checker,
|
423
416
|
source: source,
|
@@ -430,7 +423,6 @@ module Steep
|
|
430
423
|
module_context: module_context,
|
431
424
|
self_type: module_context.module_type,
|
432
425
|
type_env: module_type_env,
|
433
|
-
lvar_env: lvar_env,
|
434
426
|
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name),
|
435
427
|
variable_context: variable_context
|
436
428
|
)
|
@@ -451,11 +443,11 @@ module Steep
|
|
451
443
|
class_const_env = TypeInference::ConstantEnv.new(
|
452
444
|
factory: checker.factory,
|
453
445
|
context: new_nesting,
|
454
|
-
resolver:
|
446
|
+
resolver: context.type_env.constant_env.resolver
|
455
447
|
)
|
456
448
|
|
457
449
|
implement_module_name = implement_module(module_name: new_class_name, super_name: super_class_name, annotations: annots)
|
458
|
-
module_context = default_module_context(implement_module_name,
|
450
|
+
module_context = default_module_context(implement_module_name, nesting: new_nesting)
|
459
451
|
|
460
452
|
if implement_module_name
|
461
453
|
if super_class_name && implement_module_name.name == absolute_name(super_class_name)
|
@@ -492,17 +484,13 @@ module Steep
|
|
492
484
|
end
|
493
485
|
variable_context = TypeInference::Context::TypeVariableContext.new(type_params)
|
494
486
|
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
self_type: module_context.module_type,
|
503
|
-
instance_type: module_context.instance_type,
|
504
|
-
class_type: module_context.module_type
|
505
|
-
).annotate(annots)
|
487
|
+
singleton_definition = checker.factory.definition_builder.build_singleton(module_context.class_name)
|
488
|
+
class_type_env = TypeInference::TypeEnvBuilder.new(
|
489
|
+
TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(checker.factory),
|
490
|
+
TypeInference::TypeEnvBuilder::Command::ImportConstantAnnotations.new(annots),
|
491
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots),
|
492
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(singleton_definition, checker.factory),
|
493
|
+
).build(TypeInference::TypeEnv.new(class_const_env))
|
506
494
|
|
507
495
|
class_body_context = TypeInference::Context.new(
|
508
496
|
method_context: nil,
|
@@ -511,7 +499,6 @@ module Steep
|
|
511
499
|
break_context: nil,
|
512
500
|
self_type: module_context.module_type,
|
513
501
|
type_env: class_type_env,
|
514
|
-
lvar_env: lvar_env,
|
515
502
|
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name),
|
516
503
|
variable_context: variable_context
|
517
504
|
)
|
@@ -578,6 +565,8 @@ module Steep
|
|
578
565
|
when AST::Types::Name::Instance
|
579
566
|
type_name = instance_type.name
|
580
567
|
checker.factory.definition_builder.build_instance(type_name)
|
568
|
+
else
|
569
|
+
return
|
581
570
|
end
|
582
571
|
|
583
572
|
module_definition = case module_type
|
@@ -592,23 +581,20 @@ module Steep
|
|
592
581
|
instance_type: annots.instance_type || instance_type,
|
593
582
|
module_type: annots.self_type || annots.module_type || module_type,
|
594
583
|
implement_name: nil,
|
595
|
-
|
584
|
+
nesting: nesting,
|
596
585
|
class_name: self.module_context.class_name,
|
597
586
|
module_definition: module_definition,
|
598
587
|
instance_definition: instance_definition
|
599
588
|
)
|
600
589
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
instance_type: module_context.instance_type,
|
610
|
-
class_type: module_context.module_type
|
611
|
-
).annotate(annots)
|
590
|
+
singleton_definition = checker.factory.definition_builder.build_singleton(module_context.class_name)
|
591
|
+
type_env =
|
592
|
+
TypeInference::TypeEnvBuilder.new(
|
593
|
+
TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(checker.factory),
|
594
|
+
TypeInference::TypeEnvBuilder::Command::ImportConstantAnnotations.new(annots),
|
595
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots),
|
596
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(instance_definition, checker.factory)
|
597
|
+
).build(TypeInference::TypeEnv.new(context.type_env.constant_env))
|
612
598
|
|
613
599
|
body_context = TypeInference::Context.new(
|
614
600
|
method_context: nil,
|
@@ -617,7 +603,6 @@ module Steep
|
|
617
603
|
break_context: nil,
|
618
604
|
self_type: module_context.module_type,
|
619
605
|
type_env: type_env,
|
620
|
-
lvar_env: lvar_env,
|
621
606
|
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name),
|
622
607
|
variable_context: TypeInference::Context::TypeVariableContext.empty # Assuming `::Class` and `::Module` don't have type params
|
623
608
|
)
|
@@ -631,39 +616,15 @@ module Steep
|
|
631
616
|
)
|
632
617
|
end
|
633
618
|
|
634
|
-
def for_branch(node,
|
619
|
+
def for_branch(node, break_context: context.break_context)
|
635
620
|
annots = source.annotations(block: node, factory: checker.factory, context: nesting)
|
636
621
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
decls = env.declared_types.each.with_object({}) do |(name, entry), hash|
|
642
|
-
if truthy_vars.include?(name)
|
643
|
-
hash[name] = entry.update(type: unwrap(entry.type))
|
644
|
-
else
|
645
|
-
hash[name] = entry
|
646
|
-
end
|
647
|
-
end
|
648
|
-
|
649
|
-
assignments = env.assigned_types.each.with_object({}) do |(name, entry), hash|
|
650
|
-
if truthy_vars.include?(name)
|
651
|
-
hash[name] = entry.update(type: unwrap(entry.type))
|
652
|
-
else
|
653
|
-
hash[name] = entry
|
654
|
-
end
|
655
|
-
end
|
656
|
-
|
657
|
-
env.update(declared_types: decls, assigned_types: assignments)
|
658
|
-
end
|
659
|
-
end
|
660
|
-
|
661
|
-
if type_case_override
|
662
|
-
lvar_env = type_case_override.inject(lvar_env) do |lvar_env, (name, type)|
|
663
|
-
lvar_env.assign!(name, node: node, type: type) do |declared_type, assigned_type, result|
|
664
|
-
relation = Subtyping::Relation.new(sub_type: assigned_type, super_type: declared_type)
|
622
|
+
type_env = TypeInference::TypeEnvBuilder.new(
|
623
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots).merge!.on_duplicate! do |name, outer_type, annotation_type|
|
624
|
+
relation = Subtyping::Relation.new(sub_type: annotation_type, super_type: outer_type)
|
625
|
+
if result = no_subtyping?(sub_type: annotation_type, super_type: outer_type)
|
665
626
|
typing.add_error(
|
666
|
-
Diagnostic::Ruby::
|
627
|
+
Diagnostic::Ruby::IncompatibleAnnotation.new(
|
667
628
|
node: node,
|
668
629
|
var_name: name,
|
669
630
|
relation: relation,
|
@@ -672,53 +633,11 @@ module Steep
|
|
672
633
|
)
|
673
634
|
end
|
674
635
|
end
|
675
|
-
|
676
|
-
|
677
|
-
lvar_env = lvar_env.annotate(annots) do |var, outer_type, inner_type, result|
|
678
|
-
relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
|
679
|
-
typing.add_error(
|
680
|
-
Diagnostic::Ruby::IncompatibleAnnotation.new(
|
681
|
-
node: node,
|
682
|
-
var_name: var,
|
683
|
-
relation: relation,
|
684
|
-
result: result
|
685
|
-
)
|
686
|
-
)
|
687
|
-
end
|
688
|
-
|
689
|
-
type_env = context.type_env
|
636
|
+
).build(context.type_env)
|
690
637
|
|
691
|
-
|
692
|
-
type_env
|
693
|
-
self_type: self_type,
|
694
|
-
instance_type: module_context.instance_type,
|
695
|
-
class_type: module_context.module_type
|
696
|
-
)
|
697
|
-
end
|
698
|
-
|
699
|
-
type_env = type_env.with_annotations(
|
700
|
-
ivar_types: annots.ivar_types,
|
701
|
-
const_types: annots.const_types,
|
702
|
-
gvar_types: {},
|
703
|
-
self_type: self_type,
|
704
|
-
instance_type: module_context.instance_type,
|
705
|
-
class_type: module_context.module_type
|
706
|
-
) do |var, relation, result|
|
707
|
-
typing.add_error(
|
708
|
-
Diagnostic::Ruby::IncompatibleAnnotation.new(
|
709
|
-
node: node,
|
710
|
-
var_name: var,
|
711
|
-
relation: relation,
|
712
|
-
result: result
|
713
|
-
)
|
714
|
-
)
|
638
|
+
update_context do |context|
|
639
|
+
context.with(type_env: type_env, break_context: break_context)
|
715
640
|
end
|
716
|
-
|
717
|
-
update_context {|context|
|
718
|
-
context.with(type_env: type_env,
|
719
|
-
break_context: break_context,
|
720
|
-
lvar_env: lvar_env)
|
721
|
-
}
|
722
641
|
end
|
723
642
|
|
724
643
|
def add_typing(node, type:, constr: self)
|
@@ -774,8 +693,7 @@ module Steep
|
|
774
693
|
|
775
694
|
when :lvasgn
|
776
695
|
yield_self do
|
777
|
-
|
778
|
-
name = var
|
696
|
+
name, rhs = node.children
|
779
697
|
|
780
698
|
case name
|
781
699
|
when :_, :__any__
|
@@ -785,42 +703,56 @@ module Steep
|
|
785
703
|
when :__skip__
|
786
704
|
add_typing(node, type: AST::Builtin.any_type)
|
787
705
|
else
|
788
|
-
if
|
789
|
-
case
|
790
|
-
when nil
|
791
|
-
hint =
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
hint = declared_type
|
797
|
-
end
|
706
|
+
if enforced_type = context.type_env.enforced_type(name)
|
707
|
+
case
|
708
|
+
when hint == nil
|
709
|
+
hint = enforced_type
|
710
|
+
when check_relation(sub_type: enforced_type, super_type: hint).success?
|
711
|
+
# enforced_type is compatible with hint and more specific to hint.
|
712
|
+
# This typically happens when hint is untyped, top, or void.
|
713
|
+
hint = enforced_type
|
798
714
|
end
|
799
715
|
end
|
800
716
|
|
801
|
-
|
717
|
+
if rhs
|
718
|
+
rhs_type, rhs_constr, rhs_context = synthesize(rhs, hint: hint).to_ary
|
719
|
+
|
720
|
+
constr = rhs_constr.update_type_env do |type_env|
|
721
|
+
var_type = rhs_type
|
722
|
+
|
723
|
+
if enforced_type = type_env.enforced_type(name)
|
724
|
+
if result = no_subtyping?(sub_type: rhs_type, super_type: enforced_type)
|
725
|
+
typing.add_error(
|
726
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
727
|
+
node: node,
|
728
|
+
lhs_type: enforced_type,
|
729
|
+
rhs_type: rhs_type,
|
730
|
+
result: result
|
731
|
+
)
|
732
|
+
)
|
802
733
|
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
)
|
734
|
+
var_type = enforced_type
|
735
|
+
end
|
736
|
+
|
737
|
+
if rhs_type.is_a?(AST::Types::Any)
|
738
|
+
var_type = enforced_type
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
type_env.assign_local_variable(name, var_type, enforced_type)
|
813
743
|
end
|
814
|
-
end
|
815
744
|
|
816
|
-
|
745
|
+
constr.add_typing(node, type: rhs_type)
|
746
|
+
else
|
747
|
+
add_typing(node, type: enforced_type || AST::Builtin.any_type)
|
748
|
+
end
|
817
749
|
end
|
818
750
|
end
|
819
751
|
|
820
752
|
when :lvar
|
821
753
|
yield_self do
|
822
754
|
var = node.children[0]
|
823
|
-
if (type = context.
|
755
|
+
if (type = context.type_env[var])
|
824
756
|
add_typing node, type: type
|
825
757
|
else
|
826
758
|
fallback_to_any(node)
|
@@ -829,17 +761,21 @@ module Steep
|
|
829
761
|
|
830
762
|
when :ivasgn
|
831
763
|
name = node.children[0]
|
832
|
-
|
764
|
+
rhs = node.children[1]
|
765
|
+
|
766
|
+
rhs_type, constr = synthesize(rhs, hint: context.type_env[name])
|
833
767
|
|
834
|
-
|
768
|
+
constr.ivasgn(node, rhs_type)
|
835
769
|
|
836
770
|
when :ivar
|
837
771
|
yield_self do
|
838
772
|
name = node.children[0]
|
839
|
-
|
773
|
+
|
774
|
+
if type = context.type_env[name]
|
775
|
+
add_typing(node, type: type)
|
776
|
+
else
|
840
777
|
fallback_to_any node
|
841
778
|
end
|
842
|
-
add_typing(node, type: type)
|
843
779
|
end
|
844
780
|
|
845
781
|
when :send
|
@@ -860,22 +796,22 @@ module Steep
|
|
860
796
|
|
861
797
|
when :csend
|
862
798
|
yield_self do
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
799
|
+
send_type, constr =
|
800
|
+
if self_class?(node)
|
801
|
+
module_type = expand_alias(module_context.module_type)
|
802
|
+
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
803
|
+
AST::Types::Name::Singleton.new(name: module_type.name)
|
804
|
+
else
|
805
|
+
module_type
|
806
|
+
end
|
807
|
+
add_typing(node, type: type).to_ary
|
808
|
+
else
|
809
|
+
type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true).to_ary
|
810
|
+
end
|
874
811
|
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
constr: pair.constr.with_updated_context(lvar_env: lvar_env))
|
812
|
+
constr
|
813
|
+
.update_type_env { context.type_env.join(constr.context.type_env, context.type_env) }
|
814
|
+
.add_typing(node, type: union_type(send_type, AST::Builtin.nil_type))
|
879
815
|
end
|
880
816
|
|
881
817
|
when :match_with_lvasgn
|
@@ -1219,35 +1155,30 @@ module Steep
|
|
1219
1155
|
value = node.children[0]
|
1220
1156
|
|
1221
1157
|
if break_context
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1158
|
+
break_type = (break_context || raise).break_type
|
1159
|
+
|
1160
|
+
if value
|
1161
|
+
check(value, break_type) do |break_type, actual_type, result|
|
1162
|
+
typing.add_error(
|
1163
|
+
Diagnostic::Ruby::BreakTypeMismatch.new(
|
1164
|
+
node: node,
|
1165
|
+
expected: break_type,
|
1166
|
+
actual: actual_type,
|
1167
|
+
result: result
|
1168
|
+
)
|
1169
|
+
)
|
1170
|
+
end
|
1171
|
+
else
|
1172
|
+
unless break_type.is_a?(AST::Types::Bot)
|
1173
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: break_type).else do |result|
|
1225
1174
|
typing.add_error(
|
1226
|
-
Diagnostic::Ruby::
|
1175
|
+
Diagnostic::Ruby::ImplicitBreakValueMismatch.new(
|
1227
1176
|
node: node,
|
1228
|
-
|
1229
|
-
actual: actual_type,
|
1177
|
+
jump_type: break_type,
|
1230
1178
|
result: result
|
1231
1179
|
)
|
1232
1180
|
)
|
1233
1181
|
end
|
1234
|
-
else
|
1235
|
-
unless break_type.is_a?(AST::Types::Bot)
|
1236
|
-
check_relation(sub_type: AST::Builtin.nil_type, super_type: break_type).else do |result|
|
1237
|
-
typing.add_error(
|
1238
|
-
Diagnostic::Ruby::ImplicitBreakValueMismatch.new(
|
1239
|
-
node: node,
|
1240
|
-
jump_type: break_type,
|
1241
|
-
result: result
|
1242
|
-
)
|
1243
|
-
)
|
1244
|
-
end
|
1245
|
-
end
|
1246
|
-
end
|
1247
|
-
else
|
1248
|
-
if value
|
1249
|
-
synthesize(value)
|
1250
|
-
typing.add_error Diagnostic::Ruby::UnexpectedJumpValue.new(node: node)
|
1251
1182
|
end
|
1252
1183
|
end
|
1253
1184
|
else
|
@@ -1309,7 +1240,7 @@ module Steep
|
|
1309
1240
|
|
1310
1241
|
node.children.each do |arg|
|
1311
1242
|
if arg.is_a?(Symbol)
|
1312
|
-
type = context.
|
1243
|
+
type = context.type_env[arg]
|
1313
1244
|
|
1314
1245
|
if type
|
1315
1246
|
_, constr = add_typing(node, type: type)
|
@@ -1339,7 +1270,7 @@ module Steep
|
|
1339
1270
|
when :arg, :kwarg
|
1340
1271
|
yield_self do
|
1341
1272
|
var = node.children[0]
|
1342
|
-
type = context.
|
1273
|
+
type = context.type_env[var]
|
1343
1274
|
|
1344
1275
|
if type
|
1345
1276
|
add_typing(node, type: type)
|
@@ -1354,33 +1285,33 @@ module Steep
|
|
1354
1285
|
var = node.children[0]
|
1355
1286
|
rhs = node.children[1]
|
1356
1287
|
|
1357
|
-
var_type = context.
|
1358
|
-
node_type, constr = synthesize(rhs, hint: var_type)
|
1288
|
+
var_type = context.type_env[var]
|
1359
1289
|
|
1360
|
-
|
1361
|
-
|
1362
|
-
constr_ = constr.update_lvar_env do |env|
|
1363
|
-
env.assign(var, node: node, type: type) do |declared_type, type, result|
|
1290
|
+
if var_type
|
1291
|
+
type, constr = check(rhs, var_type) do |expected_type, actual_type, result|
|
1364
1292
|
typing.add_error(
|
1365
1293
|
Diagnostic::Ruby::IncompatibleAssignment.new(
|
1366
1294
|
node: node,
|
1367
|
-
lhs_type:
|
1368
|
-
rhs_type:
|
1295
|
+
lhs_type: expected_type,
|
1296
|
+
rhs_type: actual_type,
|
1369
1297
|
result: result
|
1370
1298
|
)
|
1371
1299
|
)
|
1372
1300
|
end
|
1301
|
+
else
|
1302
|
+
type, constr = synthesize(rhs)
|
1373
1303
|
end
|
1374
1304
|
|
1375
|
-
add_typing(node, type: type
|
1305
|
+
constr.add_typing(node, type: type)
|
1376
1306
|
end
|
1377
1307
|
|
1378
1308
|
when :restarg
|
1379
1309
|
yield_self do
|
1380
1310
|
var = node.children[0]
|
1381
|
-
type = context.
|
1311
|
+
type = context.type_env[var]
|
1312
|
+
|
1382
1313
|
unless type
|
1383
|
-
if context
|
1314
|
+
if context.method_context&.method_type
|
1384
1315
|
Steep.logger.error { "Unknown variable: #{node}" }
|
1385
1316
|
end
|
1386
1317
|
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
@@ -1393,9 +1324,9 @@ module Steep
|
|
1393
1324
|
when :kwrestarg
|
1394
1325
|
yield_self do
|
1395
1326
|
var = node.children[0]
|
1396
|
-
type = context.
|
1327
|
+
type = context.type_env[var]
|
1397
1328
|
unless type
|
1398
|
-
if context
|
1329
|
+
if context.method_context&.method_type
|
1399
1330
|
Steep.logger.error { "Unknown variable: #{node}" }
|
1400
1331
|
end
|
1401
1332
|
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
@@ -1447,7 +1378,8 @@ module Steep
|
|
1447
1378
|
when :true, :false
|
1448
1379
|
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1449
1380
|
|
1450
|
-
if hint && check_relation(sub_type: ty, super_type: hint).success?
|
1381
|
+
if hint && check_relation(sub_type: ty, super_type: hint).success? && !hint.is_a?(AST::Types::Any) && !hint.is_a?(AST::Types::Top)
|
1382
|
+
|
1451
1383
|
add_typing(node, type: hint)
|
1452
1384
|
else
|
1453
1385
|
add_typing(node, type: AST::Types::Boolean.new)
|
@@ -1568,7 +1500,7 @@ module Steep
|
|
1568
1500
|
|
1569
1501
|
when :sclass
|
1570
1502
|
yield_self do
|
1571
|
-
type, constr = synthesize(node.children[0])
|
1503
|
+
type, constr = synthesize(node.children[0]).to_ary
|
1572
1504
|
|
1573
1505
|
with_sclass_constr(node, type) do |constructor|
|
1574
1506
|
unless constructor
|
@@ -1578,8 +1510,7 @@ module Steep
|
|
1578
1510
|
message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
|
1579
1511
|
)
|
1580
1512
|
)
|
1581
|
-
constr.add_typing(node, type: AST::Builtin.nil_type)
|
1582
|
-
return
|
1513
|
+
return constr.add_typing(node, type: AST::Builtin.nil_type)
|
1583
1514
|
end
|
1584
1515
|
|
1585
1516
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
@@ -1739,137 +1670,152 @@ module Steep
|
|
1739
1670
|
|
1740
1671
|
when :and
|
1741
1672
|
yield_self do
|
1742
|
-
|
1673
|
+
left_node, right_node = node.children
|
1743
1674
|
|
1744
|
-
left_type, constr = synthesize(
|
1675
|
+
left_type, constr, left_context = synthesize(left_node, hint: hint, condition: true).to_ary
|
1745
1676
|
|
1746
1677
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1747
|
-
|
1678
|
+
left_truthy_env, left_falsy_env = interpreter.eval(env: left_context.type_env, node: left_node)
|
1748
1679
|
|
1749
1680
|
if left_type.is_a?(AST::Types::Logic::Env)
|
1750
1681
|
left_type = left_type.type
|
1751
1682
|
end
|
1752
1683
|
|
1753
|
-
right_type, constr =
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1684
|
+
right_type, constr, right_context =
|
1685
|
+
constr
|
1686
|
+
.update_type_env { left_truthy_env }
|
1687
|
+
.tap {|constr| typing.add_context_for_node(right_node, context: constr.context) }
|
1688
|
+
.for_branch(right_node)
|
1689
|
+
.synthesize(right_node, hint: hint, condition: true).to_ary
|
1758
1690
|
|
1759
|
-
|
1691
|
+
right_truthy_env, right_falsy_env = interpreter.eval(env: right_context.type_env, node: right_node)
|
1760
1692
|
|
1761
|
-
env =
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1693
|
+
env =
|
1694
|
+
if right_type.is_a?(AST::Types::Bot)
|
1695
|
+
left_falsy_env
|
1696
|
+
else
|
1697
|
+
context.type_env.join(left_falsy_env, right_context.type_env)
|
1698
|
+
end
|
1766
1699
|
|
1767
|
-
type =
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
|
1700
|
+
type =
|
1701
|
+
case
|
1702
|
+
when check_relation(sub_type: left_type, super_type: AST::Types::Boolean.new).success?
|
1703
|
+
union_type(left_type, right_type)
|
1704
|
+
else
|
1705
|
+
union_type(right_type, AST::Builtin.nil_type)
|
1706
|
+
end
|
1773
1707
|
|
1774
|
-
|
1708
|
+
if condition
|
1709
|
+
type = AST::Types::Logic::Env.new(
|
1710
|
+
truthy: right_truthy_env,
|
1711
|
+
falsy: context.type_env.join(left_falsy_env, right_falsy_env),
|
1712
|
+
type: type
|
1713
|
+
)
|
1714
|
+
end
|
1775
1715
|
|
1776
|
-
add_typing(node,
|
1777
|
-
type: type,
|
1778
|
-
constr: constr.update_lvar_env { env })
|
1716
|
+
constr.update_type_env { env }.add_typing(node, type: type)
|
1779
1717
|
end
|
1780
1718
|
|
1781
1719
|
when :or
|
1782
1720
|
yield_self do
|
1783
|
-
|
1721
|
+
left_node, right_node = node.children
|
1784
1722
|
|
1785
|
-
left_type, constr = synthesize(
|
1723
|
+
left_type, constr, left_context = synthesize(left_node, hint: hint, condition: true).to_ary
|
1786
1724
|
|
1787
1725
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1788
|
-
|
1726
|
+
left_truthy_env, left_falsy_env = interpreter.eval(env: left_context.type_env, node: left_node)
|
1789
1727
|
|
1790
1728
|
if left_type.is_a?(AST::Types::Logic::Env)
|
1791
1729
|
left_type = left_type.type
|
1792
1730
|
end
|
1793
1731
|
left_type, _ = checker.factory.unwrap_optional(left_type)
|
1794
1732
|
|
1795
|
-
right_type, constr =
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1733
|
+
right_type, constr, right_context =
|
1734
|
+
constr
|
1735
|
+
.update_type_env { left_falsy_env }
|
1736
|
+
.tap {|constr| typing.add_context_for_node(right_node, context: constr.context) }
|
1737
|
+
.for_branch(right_node)
|
1738
|
+
.synthesize(right_node, hint: left_type, condition: true).to_ary
|
1800
1739
|
|
1801
|
-
|
1740
|
+
right_truthy_env, right_falsy_env = interpreter.eval(env: left_falsy_env, node: right_node)
|
1802
1741
|
|
1803
1742
|
env = if right_type.is_a?(AST::Types::Bot)
|
1804
|
-
|
1743
|
+
left_truthy_env
|
1805
1744
|
else
|
1806
|
-
context.
|
1745
|
+
context.type_env.join(left_truthy_env, right_context.type_env)
|
1807
1746
|
end
|
1808
1747
|
|
1809
|
-
type =
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1748
|
+
type =
|
1749
|
+
case
|
1750
|
+
when check_relation(sub_type: left_type, super_type: AST::Builtin.bool_type).success? && !left_type.is_a?(AST::Types::Any)
|
1751
|
+
AST::Builtin.bool_type
|
1752
|
+
else
|
1753
|
+
union_type(left_type, right_type)
|
1754
|
+
end
|
1815
1755
|
|
1816
|
-
|
1756
|
+
if condition
|
1757
|
+
type = AST::Types::Logic::Env.new(
|
1758
|
+
truthy: context.type_env.join(left_truthy_env, right_truthy_env),
|
1759
|
+
falsy: right_falsy_env,
|
1760
|
+
type: type
|
1761
|
+
)
|
1762
|
+
end
|
1817
1763
|
|
1818
|
-
add_typing(node,
|
1819
|
-
type: type,
|
1820
|
-
constr: constr.update_lvar_env { env })
|
1764
|
+
constr.update_type_env { env }.add_typing(node, type: type)
|
1821
1765
|
end
|
1822
1766
|
|
1823
1767
|
when :if
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1768
|
+
yield_self do
|
1769
|
+
cond, true_clause, false_clause = node.children
|
1770
|
+
|
1771
|
+
cond_type, constr = synthesize(cond, condition: true).to_ary
|
1772
|
+
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
|
1773
|
+
truthy_env, falsy_env = interpreter.eval(env: constr.context.type_env, node: cond)
|
1774
|
+
|
1775
|
+
if true_clause
|
1776
|
+
true_pair =
|
1777
|
+
constr
|
1778
|
+
.update_type_env { truthy_env }
|
1779
|
+
.for_branch(true_clause)
|
1780
|
+
.tap {|constr| typing.add_context_for_node(true_clause, context: constr.context) }
|
1781
|
+
.synthesize(true_clause, hint: hint)
|
1782
|
+
end
|
1837
1783
|
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1784
|
+
if false_clause
|
1785
|
+
false_pair =
|
1786
|
+
constr
|
1787
|
+
.update_type_env { falsy_env }
|
1788
|
+
.for_branch(false_clause)
|
1789
|
+
.tap {|constr| typing.add_context_for_node(false_clause, context: constr.context) }
|
1790
|
+
.synthesize(false_clause, hint: hint)
|
1791
|
+
end
|
1845
1792
|
|
1846
|
-
|
1847
|
-
|
1793
|
+
constr = constr.update_type_env do |env|
|
1794
|
+
envs = []
|
1848
1795
|
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1796
|
+
if true_pair
|
1797
|
+
unless true_pair.type.is_a?(AST::Types::Bot)
|
1798
|
+
envs << true_pair.context.type_env
|
1799
|
+
end
|
1800
|
+
else
|
1801
|
+
envs << truthy_env
|
1852
1802
|
end
|
1853
|
-
else
|
1854
|
-
envs << truthy_env
|
1855
|
-
end
|
1856
1803
|
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1804
|
+
if false_pair
|
1805
|
+
unless false_pair.type.is_a?(AST::Types::Bot)
|
1806
|
+
envs << false_pair.context.type_env
|
1807
|
+
end
|
1808
|
+
else
|
1809
|
+
envs << falsy_env
|
1860
1810
|
end
|
1861
|
-
|
1862
|
-
envs
|
1811
|
+
|
1812
|
+
env.join(*envs)
|
1863
1813
|
end
|
1864
1814
|
|
1865
|
-
|
1815
|
+
node_type = union_type(true_pair&.type || AST::Builtin.nil_type, false_pair&.type || AST::Builtin.nil_type)
|
1816
|
+
add_typing(node, type: node_type, constr: constr)
|
1866
1817
|
end
|
1867
1818
|
|
1868
|
-
add_typing(node,
|
1869
|
-
type: union_type(true_pair&.type || AST::Builtin.nil_type,
|
1870
|
-
false_pair&.type || AST::Builtin.nil_type),
|
1871
|
-
constr: constr)
|
1872
|
-
|
1873
1819
|
when :case
|
1874
1820
|
yield_self do
|
1875
1821
|
cond, *whens, els = node.children
|
@@ -1878,49 +1824,41 @@ module Steep
|
|
1878
1824
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1879
1825
|
|
1880
1826
|
if cond
|
1881
|
-
|
1827
|
+
branch_results = []
|
1882
1828
|
|
1883
|
-
cond_type, constr = constr.synthesize(cond)
|
1884
|
-
|
1885
|
-
unless cond_vars.empty?
|
1886
|
-
first_var = cond_vars.to_a[0]
|
1887
|
-
var_node = cond.updated(:lvar, [first_var])
|
1888
|
-
else
|
1889
|
-
first_var = nil
|
1890
|
-
var_node = cond
|
1891
|
-
end
|
1829
|
+
cond_type, constr = constr.synthesize(cond).to_ary
|
1830
|
+
cond_value_node, cond_vars = interpreter.decompose_value(cond)
|
1892
1831
|
|
1893
1832
|
when_constr = constr
|
1894
1833
|
whens.each do |clause|
|
1834
|
+
# @type var tests: Array[Parser::AST::Node]
|
1835
|
+
# @type var body: Parser::AST::Node?
|
1895
1836
|
*tests, body = clause.children
|
1896
1837
|
|
1897
1838
|
test_constr = when_constr
|
1839
|
+
# @type var test_envs: Array[TypeInference::TypeEnv]
|
1898
1840
|
test_envs = []
|
1899
1841
|
|
1900
1842
|
tests.each do |test|
|
1901
|
-
test_node = test.updated(:send, [test, :===,
|
1902
|
-
test_type, test_constr = test_constr.synthesize(test_node, condition: true)
|
1903
|
-
truthy_env, falsy_env = interpreter.eval(
|
1904
|
-
truthy_env = cond_vars.inject(truthy_env) do |env, var|
|
1905
|
-
env.assign!(var, node: test_node, type: env[first_var])
|
1906
|
-
end
|
1907
|
-
falsy_env = cond_vars.inject(falsy_env) do |env, var|
|
1908
|
-
env.assign!(var, node: test_node, type: env[first_var])
|
1909
|
-
end
|
1843
|
+
test_node = test.updated(:send, [test, :===, cond])
|
1844
|
+
test_type, test_constr = test_constr.synthesize(test_node, condition: true).to_ary
|
1845
|
+
truthy_env, falsy_env = interpreter.eval(node: test_node, env: test_constr.context.type_env)
|
1910
1846
|
|
1911
1847
|
test_envs << truthy_env
|
1912
|
-
|
1848
|
+
|
1849
|
+
test_constr = test_constr.update_type_env { falsy_env }
|
1913
1850
|
end
|
1914
1851
|
|
1915
|
-
body_constr = when_constr.
|
1852
|
+
body_constr = when_constr.update_type_env {|env| env.join(*test_envs) }
|
1916
1853
|
|
1917
1854
|
if body
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1855
|
+
branch_results <<
|
1856
|
+
body_constr
|
1857
|
+
.for_branch(body)
|
1858
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1859
|
+
.synthesize(body, hint: hint)
|
1922
1860
|
else
|
1923
|
-
|
1861
|
+
branch_results << Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
|
1924
1862
|
end
|
1925
1863
|
|
1926
1864
|
when_constr = test_constr
|
@@ -1931,13 +1869,14 @@ module Steep
|
|
1931
1869
|
end_pos = node.loc.end.begin_pos
|
1932
1870
|
typing.add_context(begin_pos..end_pos, context: when_constr.context)
|
1933
1871
|
|
1934
|
-
|
1872
|
+
branch_results << when_constr.synthesize(els, hint: hint)
|
1935
1873
|
end
|
1936
1874
|
|
1937
|
-
types =
|
1938
|
-
constrs =
|
1875
|
+
types = branch_results.map(&:type)
|
1876
|
+
constrs = branch_results.map(&:constr)
|
1939
1877
|
|
1940
|
-
|
1878
|
+
cond_type = when_constr.context.type_env[cond_value_node]
|
1879
|
+
if cond_type.is_a?(AST::Types::Bot)
|
1941
1880
|
# Exhaustive
|
1942
1881
|
if els
|
1943
1882
|
typing.add_error Diagnostic::Ruby::ElseOnExhaustiveCase.new(node: els, type: cond_type)
|
@@ -1949,49 +1888,52 @@ module Steep
|
|
1949
1888
|
end
|
1950
1889
|
end
|
1951
1890
|
else
|
1952
|
-
|
1891
|
+
branch_results = []
|
1953
1892
|
|
1954
|
-
|
1893
|
+
condition_constr = constr
|
1955
1894
|
clause_constr = constr
|
1956
1895
|
|
1957
|
-
whens.each do |
|
1958
|
-
|
1896
|
+
whens.each do |when_clause|
|
1897
|
+
when_clause_constr = condition_constr
|
1898
|
+
body_envs = []
|
1959
1899
|
|
1960
|
-
|
1900
|
+
*tests, body = when_clause.children
|
1961
1901
|
|
1962
1902
|
tests.each do |test|
|
1963
|
-
test_type,
|
1964
|
-
truthy_env, falsy_env = interpreter.eval(env:
|
1965
|
-
clause_constr = clause_constr.update_lvar_env { truthy_env }
|
1966
|
-
test_constr = test_constr.update_lvar_env { falsy_env }
|
1967
|
-
end
|
1903
|
+
test_type, condition_constr = condition_constr.synthesize(test, condition: true).to_ary
|
1904
|
+
truthy_env, falsy_env = interpreter.eval(env: condition_constr.context.type_env, node: test)
|
1968
1905
|
|
1969
|
-
|
1906
|
+
condition_constr = condition_constr.update_type_env { falsy_env }
|
1907
|
+
body_envs << truthy_env
|
1908
|
+
end
|
1970
1909
|
|
1971
1910
|
if body
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1911
|
+
branch_results <<
|
1912
|
+
when_clause_constr
|
1913
|
+
.for_branch(body)
|
1914
|
+
.update_type_env {|env| env.join(*body_envs) }
|
1915
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1916
|
+
.synthesize(body, hint: hint)
|
1976
1917
|
else
|
1977
|
-
|
1918
|
+
branch_results << Pair.new(type: AST::Builtin.nil_type, constr: when_clause_constr)
|
1978
1919
|
end
|
1979
1920
|
end
|
1980
1921
|
|
1981
1922
|
if els
|
1982
|
-
|
1923
|
+
branch_results << condition_constr.synthesize(els, hint: hint)
|
1983
1924
|
end
|
1984
1925
|
|
1985
|
-
types =
|
1986
|
-
constrs =
|
1926
|
+
types = branch_results.map(&:type)
|
1927
|
+
constrs = branch_results.map(&:constr)
|
1987
1928
|
|
1988
1929
|
unless els
|
1989
1930
|
types << AST::Builtin.nil_type
|
1990
1931
|
end
|
1991
1932
|
end
|
1992
1933
|
|
1993
|
-
constr = constr.
|
1994
|
-
|
1934
|
+
constr = constr.update_type_env do |env|
|
1935
|
+
envs = constrs.map {|c| c.context.type_env }
|
1936
|
+
env.join(*envs)
|
1995
1937
|
end
|
1996
1938
|
|
1997
1939
|
add_typing(node, type: union_type(*types), constr: constr)
|
@@ -2002,15 +1944,19 @@ module Steep
|
|
2002
1944
|
body, *resbodies, else_node = node.children
|
2003
1945
|
body_pair = synthesize(body, hint: hint) if body
|
2004
1946
|
|
1947
|
+
# @type var body_constr: TypeConstruction
|
2005
1948
|
body_constr = if body_pair
|
2006
|
-
|
2007
|
-
env.join(env, body_pair.context.
|
1949
|
+
update_type_env do |env|
|
1950
|
+
env.join(env, body_pair.context.type_env)
|
2008
1951
|
end
|
2009
1952
|
else
|
2010
1953
|
self
|
2011
1954
|
end
|
2012
1955
|
|
2013
1956
|
resbody_pairs = resbodies.map do |resbody|
|
1957
|
+
# @type var exn_classes: Parser::AST::Node
|
1958
|
+
# @type var assignment: Parser::AST::Node?
|
1959
|
+
# @type var body: Parser::AST::Node?
|
2014
1960
|
exn_classes, assignment, body = resbody.children
|
2015
1961
|
|
2016
1962
|
if exn_classes
|
@@ -2031,25 +1977,28 @@ module Steep
|
|
2031
1977
|
end
|
2032
1978
|
end
|
2033
1979
|
|
2034
|
-
|
1980
|
+
resbody_construction = body_constr.for_branch(resbody).update_type_env do |env|
|
1981
|
+
assignments = {}
|
2035
1982
|
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
1983
|
+
case
|
1984
|
+
when exn_classes && var_name && exn_types
|
1985
|
+
instance_types = exn_types.map do |type|
|
1986
|
+
type = expand_alias(type)
|
1987
|
+
case
|
1988
|
+
when type.is_a?(AST::Types::Name::Singleton)
|
1989
|
+
to_instance_type(type)
|
1990
|
+
else
|
1991
|
+
AST::Builtin.any_type
|
1992
|
+
end
|
2045
1993
|
end
|
1994
|
+
|
1995
|
+
assignments[var_name] = AST::Types::Union.build(types: instance_types)
|
1996
|
+
when var_name
|
1997
|
+
assignments[var_name] = AST::Builtin.any_type
|
2046
1998
|
end
|
2047
|
-
type_override[var_name] = AST::Types::Union.build(types: instance_types)
|
2048
|
-
when var_name
|
2049
|
-
type_override[var_name] = AST::Builtin.any_type
|
2050
|
-
end
|
2051
1999
|
|
2052
|
-
|
2000
|
+
env.assign_local_variables(assignments)
|
2001
|
+
end
|
2053
2002
|
|
2054
2003
|
if body
|
2055
2004
|
resbody_construction.synthesize(body, hint: hint)
|
@@ -2059,17 +2008,18 @@ module Steep
|
|
2059
2008
|
end
|
2060
2009
|
|
2061
2010
|
resbody_types = resbody_pairs.map(&:type)
|
2062
|
-
resbody_envs = resbody_pairs.map {|pair| pair.context.
|
2011
|
+
resbody_envs = resbody_pairs.map {|pair| pair.context.type_env }
|
2012
|
+
|
2013
|
+
else_constr = body_pair&.constr || self
|
2063
2014
|
|
2064
2015
|
if else_node
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2016
|
+
else_type, else_constr = else_constr.for_branch(else_node).synthesize(else_node, hint: hint)
|
2017
|
+
else_constr
|
2018
|
+
.update_type_env {|env| env.join(*resbody_envs, env) }
|
2019
|
+
.add_typing(node, type: union_type(else_type, *resbody_types))
|
2069
2020
|
else
|
2070
|
-
|
2071
|
-
|
2072
|
-
constr: update_lvar_env {|env| env.join(*resbody_envs, (body_pair&.constr || self).context.lvar_env) })
|
2021
|
+
update_type_env {|env| env.join(*resbody_envs, else_constr.context.type_env) }
|
2022
|
+
.add_typing(node, type: union_type(*[body_pair&.type, *resbody_types].compact))
|
2073
2023
|
end
|
2074
2024
|
end
|
2075
2025
|
|
@@ -2097,7 +2047,7 @@ module Steep
|
|
2097
2047
|
yield_self do
|
2098
2048
|
asgn, collection, body = node.children
|
2099
2049
|
|
2100
|
-
collection_type, constr = synthesize(collection)
|
2050
|
+
collection_type, constr, collection_context = synthesize(collection).to_ary
|
2101
2051
|
collection_type = expand_self(collection_type)
|
2102
2052
|
|
2103
2053
|
var_type = case collection_type
|
@@ -2110,24 +2060,31 @@ module Steep
|
|
2110
2060
|
method_type.block.type.params.first_param&.type
|
2111
2061
|
end
|
2112
2062
|
end
|
2063
|
+
var_name = asgn.children[0]
|
2113
2064
|
|
2114
2065
|
if var_type
|
2115
2066
|
if body
|
2116
|
-
body_constr = constr.
|
2117
|
-
|
2118
|
-
|
2067
|
+
body_constr = constr.update_type_env do |type_env|
|
2068
|
+
type_env = type_env.assign_local_variables({ var_name => var_type })
|
2069
|
+
pins = type_env.pin_local_variables(nil)
|
2070
|
+
type_env.merge(local_variable_types: pins)
|
2071
|
+
end
|
2119
2072
|
|
2120
2073
|
typing.add_context_for_body(node, context: body_constr.context)
|
2121
|
-
_, _, body_context = body_constr.synthesize(body)
|
2074
|
+
_, _, body_context = body_constr.synthesize(body).to_ary
|
2122
2075
|
|
2123
|
-
constr = constr.
|
2076
|
+
constr = constr.update_type_env do |env|
|
2077
|
+
env.join(collection_context.type_env, body_context.type_env)
|
2078
|
+
end
|
2124
2079
|
else
|
2125
2080
|
constr = self
|
2126
2081
|
end
|
2127
2082
|
|
2128
2083
|
add_typing(node, type: collection_type, constr: constr)
|
2129
2084
|
else
|
2130
|
-
|
2085
|
+
constr = synthesize_children(node, skips: [collection])
|
2086
|
+
|
2087
|
+
constr.fallback_to_any(node) do
|
2131
2088
|
Diagnostic::Ruby::NoMethod.new(
|
2132
2089
|
node: node,
|
2133
2090
|
method: :each,
|
@@ -2139,10 +2096,10 @@ module Steep
|
|
2139
2096
|
when :while, :until
|
2140
2097
|
yield_self do
|
2141
2098
|
cond, body = node.children
|
2142
|
-
cond_type, constr = synthesize(cond, condition: true)
|
2099
|
+
cond_type, constr = synthesize(cond, condition: true).to_ary
|
2143
2100
|
|
2144
2101
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
2145
|
-
truthy_env, falsy_env = interpreter.eval(env: constr.context.
|
2102
|
+
truthy_env, falsy_env = interpreter.eval(env: constr.context.type_env, node: cond)
|
2146
2103
|
|
2147
2104
|
case node.type
|
2148
2105
|
when :while
|
@@ -2152,19 +2109,19 @@ module Steep
|
|
2152
2109
|
end
|
2153
2110
|
|
2154
2111
|
if body
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
constr = constr.
|
2112
|
+
pins = body_env.pin_local_variables(nil)
|
2113
|
+
body_env = body_env.merge(local_variable_types: pins)
|
2114
|
+
|
2115
|
+
_, body_constr =
|
2116
|
+
constr
|
2117
|
+
.update_type_env { body_env }
|
2118
|
+
.for_branch(body, break_context: TypeInference::Context::BreakContext.new(break_type: hint || AST::Builtin.nil_type, next_type: nil))
|
2119
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
2120
|
+
.synthesize(body).to_ary
|
2121
|
+
|
2122
|
+
constr = constr.update_type_env {|env| env.join(exit_env, body_constr.context.type_env) }
|
2166
2123
|
else
|
2167
|
-
constr = constr.
|
2124
|
+
constr = constr.update_type_env { exit_env }
|
2168
2125
|
end
|
2169
2126
|
|
2170
2127
|
add_typing(node, type: AST::Builtin.nil_type, constr: constr)
|
@@ -2174,21 +2131,18 @@ module Steep
|
|
2174
2131
|
yield_self do
|
2175
2132
|
cond, body = node.children
|
2176
2133
|
|
2177
|
-
|
2134
|
+
_, cond_constr, = synthesize(cond).to_ary
|
2178
2135
|
|
2179
2136
|
if body
|
2180
|
-
for_loop =
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
break_type: nil,
|
2185
|
-
next_type: nil
|
2186
|
-
))
|
2137
|
+
for_loop =
|
2138
|
+
cond_constr
|
2139
|
+
.update_type_env {|env| env.merge(local_variable_types: env.pin_local_variables(nil)) }
|
2140
|
+
.for_branch(body, break_context: TypeInference::Context::BreakContext.new(break_type: hint || AST::Builtin.nil_type, next_type: nil))
|
2187
2141
|
|
2188
2142
|
typing.add_context_for_node(body, context: for_loop.context)
|
2189
|
-
|
2143
|
+
_, body_constr, body_context = for_loop.synthesize(body)
|
2190
2144
|
|
2191
|
-
constr =
|
2145
|
+
constr = cond_constr.update_type_env {|env| env.join(env, body_context.type_env) }
|
2192
2146
|
|
2193
2147
|
add_typing(node, type: AST::Builtin.nil_type, constr: constr)
|
2194
2148
|
else
|
@@ -2269,37 +2223,48 @@ module Steep
|
|
2269
2223
|
when :gvasgn
|
2270
2224
|
yield_self do
|
2271
2225
|
name, rhs = node.children
|
2272
|
-
|
2273
|
-
fallback_to_any node
|
2274
|
-
end
|
2226
|
+
lhs_type = context.type_env[name]
|
2275
2227
|
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2228
|
+
rhs_type, constr = synthesize(rhs, hint: lhs_type).to_ary
|
2229
|
+
|
2230
|
+
if lhs_type
|
2231
|
+
result = constr.check_relation(sub_type: rhs_type, super_type: lhs_type)
|
2232
|
+
|
2233
|
+
if result.failure?
|
2234
|
+
constr.typing.add_error(
|
2235
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2236
|
+
node: node,
|
2237
|
+
lhs_type: lhs_type,
|
2238
|
+
rhs_type: rhs_type,
|
2239
|
+
result: result
|
2240
|
+
)
|
2283
2241
|
)
|
2284
|
-
|
2242
|
+
end
|
2243
|
+
else
|
2244
|
+
constr.typing.add_error(Diagnostic::Ruby::UnknownGlobalVariable.new(node: node, name: name))
|
2285
2245
|
end
|
2246
|
+
|
2247
|
+
constr.add_typing(node, type: rhs_type)
|
2286
2248
|
end
|
2287
2249
|
|
2288
2250
|
when :gvar
|
2289
2251
|
yield_self do
|
2290
2252
|
name = node.children.first
|
2291
|
-
type = type_env
|
2292
|
-
|
2253
|
+
if type = context.type_env[name]
|
2254
|
+
add_typing(node, type: type)
|
2255
|
+
else
|
2256
|
+
fallback_to_any(node) do
|
2257
|
+
Diagnostic::Ruby::UnknownGlobalVariable.new(node: node, name: name)
|
2258
|
+
end
|
2293
2259
|
end
|
2294
|
-
|
2295
|
-
add_typing(node, type: type)
|
2296
2260
|
end
|
2297
2261
|
|
2298
2262
|
when :block_pass
|
2299
2263
|
yield_self do
|
2300
2264
|
value = node.children[0]
|
2301
2265
|
|
2302
|
-
|
2266
|
+
case
|
2267
|
+
when hint.is_a?(AST::Types::Proc) && value && value.type == :sym
|
2303
2268
|
if hint.one_arg?
|
2304
2269
|
# Assumes Symbol#to_proc implementation
|
2305
2270
|
param_type = hint.type.params.required[0]
|
@@ -2333,9 +2298,18 @@ module Steep
|
|
2333
2298
|
else
|
2334
2299
|
Steep.logger.error "Passing multiple args through Symbol#to_proc is not supported yet"
|
2335
2300
|
end
|
2301
|
+
when value == nil
|
2302
|
+
type = AST::Types::Proc.new(
|
2303
|
+
type: method_context.method_type.block.type,
|
2304
|
+
location: nil,
|
2305
|
+
block: nil
|
2306
|
+
)
|
2307
|
+
if method_context.method_type.block.optional?
|
2308
|
+
type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2309
|
+
end
|
2336
2310
|
end
|
2337
2311
|
|
2338
|
-
type ||= synthesize(
|
2312
|
+
type ||= synthesize(value, hint: hint).type
|
2339
2313
|
|
2340
2314
|
add_typing node, type: type
|
2341
2315
|
end
|
@@ -2452,33 +2426,6 @@ module Steep
|
|
2452
2426
|
end
|
2453
2427
|
end
|
2454
2428
|
|
2455
|
-
def type_ivasgn(name, rhs, node)
|
2456
|
-
rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) }).type
|
2457
|
-
|
2458
|
-
ivar_type = type_env.assign(
|
2459
|
-
ivar: name,
|
2460
|
-
type: rhs_type,
|
2461
|
-
self_type: self_type,
|
2462
|
-
instance_type: module_context.instance_type,
|
2463
|
-
class_type: module_context.module_type
|
2464
|
-
) do |error|
|
2465
|
-
if error
|
2466
|
-
type = type_env.get(ivar: name)
|
2467
|
-
typing.add_error(
|
2468
|
-
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2469
|
-
node: node,
|
2470
|
-
lhs_type: type,
|
2471
|
-
rhs_type: rhs_type,
|
2472
|
-
result: error
|
2473
|
-
)
|
2474
|
-
)
|
2475
|
-
else
|
2476
|
-
fallback_to_any node
|
2477
|
-
end
|
2478
|
-
end
|
2479
|
-
add_typing(node, type: ivar_type)
|
2480
|
-
end
|
2481
|
-
|
2482
2429
|
def masgn_lhs?(lhs)
|
2483
2430
|
lhs.children.all? do |a|
|
2484
2431
|
asgn_type = if a.type == :splat
|
@@ -2492,233 +2439,140 @@ module Steep
|
|
2492
2439
|
|
2493
2440
|
def lvasgn(node, type)
|
2494
2441
|
name = node.children[0]
|
2495
|
-
env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
|
2496
|
-
typing.add_error(
|
2497
|
-
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2498
|
-
node: node,
|
2499
|
-
lhs_type: declared_type,
|
2500
|
-
rhs_type: type,
|
2501
|
-
result: result
|
2502
|
-
)
|
2503
|
-
)
|
2504
|
-
end
|
2505
2442
|
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
def ivasgn(node, type)
|
2510
|
-
ivar = node.children[0]
|
2511
|
-
|
2512
|
-
type_env.assign(
|
2513
|
-
ivar: ivar,
|
2514
|
-
type: type,
|
2515
|
-
self_type: self_type,
|
2516
|
-
instance_type: module_context.instance_type,
|
2517
|
-
class_type: module_context.module_type
|
2518
|
-
) do |error|
|
2519
|
-
if error
|
2520
|
-
var_type = type_env.get(ivar: ivar)
|
2443
|
+
if enforced_type = context.type_env.enforced_type(name)
|
2444
|
+
if result = no_subtyping?(sub_type: type, super_type: enforced_type)
|
2521
2445
|
typing.add_error(
|
2522
2446
|
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2523
2447
|
node: node,
|
2524
|
-
lhs_type:
|
2448
|
+
lhs_type: enforced_type,
|
2525
2449
|
rhs_type: type,
|
2526
|
-
result:
|
2450
|
+
result: result
|
2527
2451
|
)
|
2528
2452
|
)
|
2529
|
-
|
2530
|
-
|
2453
|
+
|
2454
|
+
type = enforced_type
|
2531
2455
|
end
|
2532
2456
|
end
|
2533
2457
|
|
2534
|
-
|
2458
|
+
update_type_env {|env| env.assign_local_variable(name, type, enforced_type) }
|
2459
|
+
.add_typing(node, type: type)
|
2535
2460
|
end
|
2536
2461
|
|
2537
|
-
def
|
2538
|
-
|
2539
|
-
rhs_pair = synthesize(rhs)
|
2540
|
-
rhs_type = deep_expand_alias(rhs_pair.type)
|
2541
|
-
|
2542
|
-
constr = rhs_pair.constr
|
2543
|
-
|
2544
|
-
unless masgn_lhs?(lhs)
|
2545
|
-
Steep.logger.error("Unsupported masgn lhs node: only lvasgn, ivasgn, and splat are supported")
|
2546
|
-
_, constr = constr.fallback_to_any(lhs)
|
2547
|
-
return add_typing(node, type: rhs_type, constr: constr)
|
2548
|
-
end
|
2549
|
-
|
2550
|
-
falseys, truthys = partition_flatten_types(rhs_type) do |type|
|
2551
|
-
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
2552
|
-
end
|
2553
|
-
|
2554
|
-
unwrap_rhs_type = AST::Types::Union.build(types: truthys)
|
2555
|
-
|
2556
|
-
case
|
2557
|
-
when unwrap_rhs_type.is_a?(AST::Types::Tuple) || (rhs.type == :array && rhs.children.none? {|n| n.type == :splat })
|
2558
|
-
tuple_types = if unwrap_rhs_type.is_a?(AST::Types::Tuple)
|
2559
|
-
unwrap_rhs_type.types.dup
|
2560
|
-
else
|
2561
|
-
rhs.children.map do |node|
|
2562
|
-
typing.type_of(node: node)
|
2563
|
-
end
|
2564
|
-
end
|
2565
|
-
|
2566
|
-
assignment_nodes = lhs.children.dup
|
2567
|
-
leading_assignments = []
|
2568
|
-
trailing_assignments = []
|
2462
|
+
def ivasgn(node, rhs_type)
|
2463
|
+
name = node.children[0]
|
2569
2464
|
|
2570
|
-
|
2571
|
-
cursor = assignment_nodes.first
|
2465
|
+
lhs_type = context.type_env[name]
|
2572
2466
|
|
2573
|
-
|
2574
|
-
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2467
|
+
if lhs_type
|
2468
|
+
if (result = check_relation(sub_type: rhs_type, super_type: lhs_type)).failure?
|
2469
|
+
typing.add_error(
|
2470
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(node: node, lhs_type: lhs_type, rhs_type: rhs_type, result: result)
|
2471
|
+
)
|
2578
2472
|
end
|
2473
|
+
else
|
2474
|
+
typing.add_error(Diagnostic::Ruby::UnknownInstanceVariable.new(node: node, name: name))
|
2475
|
+
end
|
2579
2476
|
|
2580
|
-
|
2581
|
-
|
2582
|
-
|
2583
|
-
if cursor.type == :splat
|
2584
|
-
break
|
2585
|
-
else
|
2586
|
-
trailing_assignments.unshift assignment_nodes.pop
|
2587
|
-
end
|
2588
|
-
end
|
2477
|
+
add_typing(node, type: rhs_type)
|
2478
|
+
end
|
2589
2479
|
|
2590
|
-
|
2591
|
-
|
2480
|
+
def type_masgn_type(mlhs_node, rhs_type, masgn:, optional:)
|
2481
|
+
# @type var constr: TypeConstruction
|
2482
|
+
constr = self
|
2592
2483
|
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
type = AST::Builtin.nil_type
|
2597
|
-
end
|
2484
|
+
if assignments = masgn.expand(mlhs_node, rhs_type || AST::Builtin.any_type, optional)
|
2485
|
+
assignments.each do |pair|
|
2486
|
+
node, type = pair
|
2598
2487
|
|
2599
|
-
|
2600
|
-
|
2601
|
-
_, constr = constr.lvasgn(asgn, type)
|
2602
|
-
when :ivasgn
|
2603
|
-
_, constr = constr.ivasgn(asgn, type)
|
2488
|
+
if assignments.optional
|
2489
|
+
type = AST::Builtin.optional(type)
|
2604
2490
|
end
|
2605
|
-
end
|
2606
2491
|
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
tuple_types.pop
|
2492
|
+
if node.type == :splat
|
2493
|
+
asgn_node = node.children[0]
|
2494
|
+
next unless asgn_node
|
2495
|
+
var_type = asgn_node.type
|
2612
2496
|
else
|
2613
|
-
|
2497
|
+
asgn_node = node
|
2498
|
+
var_type = type
|
2614
2499
|
end
|
2615
2500
|
|
2616
|
-
case
|
2501
|
+
case asgn_node.type
|
2617
2502
|
when :lvasgn
|
2618
|
-
_, constr = constr.lvasgn(
|
2503
|
+
_, constr = constr.lvasgn(asgn_node, type)
|
2619
2504
|
when :ivasgn
|
2620
|
-
_, constr = constr.ivasgn(
|
2505
|
+
_, constr = constr.ivasgn(asgn_node, type)
|
2506
|
+
when :gvasgn
|
2507
|
+
raise
|
2508
|
+
when :mlhs
|
2509
|
+
constr = (constr.type_masgn_type(asgn_node, type, masgn: masgn, optional: optional) or return)
|
2621
2510
|
end
|
2622
|
-
end
|
2623
2511
|
|
2624
|
-
|
2625
|
-
|
2626
|
-
else
|
2627
|
-
AST::Types::Union.build(types: tuple_types)
|
2628
|
-
end
|
2629
|
-
array_type = AST::Builtin::Array.instance_type(element_type)
|
2630
|
-
|
2631
|
-
assignment_nodes.each do |asgn|
|
2632
|
-
case asgn.type
|
2633
|
-
when :splat
|
2634
|
-
case asgn.children[0]&.type
|
2635
|
-
when :lvasgn
|
2636
|
-
_, constr = constr.lvasgn(asgn.children[0], array_type)
|
2637
|
-
when :ivasgn
|
2638
|
-
_, constr = constr.ivasgn(asgn.children[0], array_type)
|
2639
|
-
end
|
2640
|
-
when :lvasgn
|
2641
|
-
_, constr = constr.lvasgn(asgn, element_type)
|
2642
|
-
when :ivasgn
|
2643
|
-
_,constr = constr.ivasgn(asgn, element_type)
|
2512
|
+
if node.type == :splat
|
2513
|
+
_, constr = constr.add_typing(node, type: type)
|
2644
2514
|
end
|
2645
2515
|
end
|
2646
2516
|
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2650
|
-
|
2651
|
-
add_typing(node, type: rhs_type, constr: constr)
|
2517
|
+
constr
|
2518
|
+
end
|
2519
|
+
end
|
2652
2520
|
|
2653
|
-
|
2654
|
-
|
2655
|
-
element_type = AST::Types::Union.build(types: array_elements + [AST::Builtin.nil_type])
|
2521
|
+
def type_masgn(node)
|
2522
|
+
lhs, rhs = node.children
|
2656
2523
|
|
2657
|
-
|
2658
|
-
|
2659
|
-
when :lvasgn
|
2660
|
-
_, constr = constr.lvasgn(assignment, element_type)
|
2524
|
+
masgn = TypeInference::MultipleAssignment.new()
|
2525
|
+
hint = masgn.hint_for_mlhs(lhs, context.type_env)
|
2661
2526
|
|
2662
|
-
|
2663
|
-
|
2664
|
-
when :splat
|
2665
|
-
case assignment.children[0]&.type
|
2666
|
-
when :lvasgn
|
2667
|
-
_, constr = constr.lvasgn(assignment.children[0], unwrap_rhs_type)
|
2668
|
-
when :ivasgn
|
2669
|
-
_, constr = constr.ivasgn(assignment.children[0], unwrap_rhs_type)
|
2670
|
-
when nil
|
2671
|
-
# foo, * = bar
|
2672
|
-
else
|
2673
|
-
raise
|
2674
|
-
end
|
2675
|
-
end
|
2527
|
+
rhs_type, lhs_constr = try_tuple_type!(rhs, hint: hint).to_ary
|
2528
|
+
rhs_type = deep_expand_alias(rhs_type)
|
2676
2529
|
|
2677
|
-
|
2678
|
-
|
2530
|
+
falsys, truthys = partition_flatten_types(rhs_type) do |type|
|
2531
|
+
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
2532
|
+
end
|
2679
2533
|
|
2680
|
-
|
2681
|
-
|
2682
|
-
end
|
2534
|
+
truthy_rhs_type = AST::Types::Union.build(types: truthys)
|
2535
|
+
optional = !falsys.empty?
|
2683
2536
|
|
2684
|
-
|
2537
|
+
if truthy_rhs_type.is_a?(AST::Types::Tuple) || AST::Builtin::Array.instance_type?(truthy_rhs_type) || truthy_rhs_type.is_a?(AST::Types::Any)
|
2538
|
+
constr = lhs_constr.type_masgn_type(lhs, truthy_rhs_type, masgn: masgn, optional: optional)
|
2685
2539
|
else
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2540
|
+
ary_type = try_convert(truthy_rhs_type, :to_ary) || try_convert(truthy_rhs_type, :to_a) || AST::Types::Tuple.new(types: [truthy_rhs_type])
|
2541
|
+
constr = lhs_constr.type_masgn_type(lhs, ary_type, masgn: masgn, optional: optional)
|
2542
|
+
end
|
2689
2543
|
|
2690
|
-
|
2544
|
+
unless constr
|
2545
|
+
typing.add_error(
|
2546
|
+
Diagnostic::Ruby::MultipleAssignmentConversionError.new(
|
2547
|
+
node: rhs,
|
2548
|
+
original_type: rhs_type,
|
2549
|
+
returned_type: ary_type || AST::Builtin.bottom_type
|
2550
|
+
)
|
2551
|
+
)
|
2691
2552
|
|
2692
|
-
constr =
|
2693
|
-
|
2553
|
+
constr = lhs_constr
|
2554
|
+
|
2555
|
+
each_descendant_node(lhs) do |node|
|
2556
|
+
case node.type
|
2694
2557
|
when :lvasgn
|
2695
|
-
_, constr = constr.lvasgn(
|
2558
|
+
_, constr = constr.lvasgn(node, AST::Builtin.any_type).to_ary
|
2696
2559
|
when :ivasgn
|
2697
|
-
_, constr = constr.ivasgn(
|
2698
|
-
when :
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
when :ivasgn
|
2703
|
-
_, constr = constr.ivasgn(assignment.children[0], untyped)
|
2704
|
-
when nil
|
2705
|
-
# foo, * = bar
|
2706
|
-
else
|
2707
|
-
raise
|
2708
|
-
end
|
2560
|
+
_, constr = constr.ivasgn(node, AST::Builtin.any_type).to_ary
|
2561
|
+
when :gvasgn
|
2562
|
+
raise
|
2563
|
+
else
|
2564
|
+
_, constr = constr.add_typing(node, type: AST::Builtin.any_type).to_ary
|
2709
2565
|
end
|
2710
|
-
|
2711
|
-
constr
|
2712
2566
|
end
|
2713
|
-
|
2714
|
-
add_typing(node, type: rhs_type, constr: constr)
|
2715
2567
|
end
|
2568
|
+
|
2569
|
+
constr.add_typing(node, type: truthy_rhs_type)
|
2716
2570
|
end
|
2717
2571
|
|
2718
2572
|
def synthesize_constant(node, parent_node, constant_name)
|
2719
2573
|
const_name = module_name_from_node(parent_node, constant_name)
|
2720
2574
|
|
2721
|
-
if const_name && type = type_env.
|
2575
|
+
if const_name && type = context.type_env.annotated_constant(const_name)
|
2722
2576
|
# const-type annotation wins
|
2723
2577
|
if node
|
2724
2578
|
constr = synthesize_children(node)
|
@@ -2732,7 +2586,7 @@ module Steep
|
|
2732
2586
|
when !parent_node
|
2733
2587
|
constr = self
|
2734
2588
|
|
2735
|
-
if (type, name =
|
2589
|
+
if (type, name = context.type_env.constant(constant_name, false))
|
2736
2590
|
if node
|
2737
2591
|
_, constr = add_typing(node, type: type)
|
2738
2592
|
end
|
@@ -2742,7 +2596,7 @@ module Steep
|
|
2742
2596
|
when parent_node.type == :cbase
|
2743
2597
|
_, constr = add_typing(parent_node, type: AST::Builtin.nil_type)
|
2744
2598
|
|
2745
|
-
if (type, name = constr.
|
2599
|
+
if (type, name = constr.context.type_env.constant(constant_name, true))
|
2746
2600
|
if node
|
2747
2601
|
_, constr = constr.add_typing(node, type: type)
|
2748
2602
|
end
|
@@ -2750,12 +2604,12 @@ module Steep
|
|
2750
2604
|
return [type, constr, name]
|
2751
2605
|
end
|
2752
2606
|
else
|
2753
|
-
parent_type, constr = synthesize(parent_node)
|
2607
|
+
parent_type, constr = synthesize(parent_node).to_ary
|
2754
2608
|
parent_type = deep_expand_alias(parent_type)
|
2755
2609
|
|
2756
2610
|
case parent_type
|
2757
2611
|
when AST::Types::Name::Singleton
|
2758
|
-
if (type, name =
|
2612
|
+
if (type, name = constr.context.type_env.constant(parent_type.name, constant_name))
|
2759
2613
|
if node
|
2760
2614
|
_, constr = add_typing(node, type: type)
|
2761
2615
|
end
|
@@ -2817,6 +2671,7 @@ module Steep
|
|
2817
2671
|
end
|
2818
2672
|
|
2819
2673
|
block_constr = for_block(
|
2674
|
+
body_node,
|
2820
2675
|
block_params: params,
|
2821
2676
|
block_param_hint: params_hint,
|
2822
2677
|
block_type_hint: return_hint,
|
@@ -2827,13 +2682,6 @@ module Steep
|
|
2827
2682
|
|
2828
2683
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2829
2684
|
|
2830
|
-
default_proc_function =
|
2831
|
-
Interface::Function.new(
|
2832
|
-
params: Interface::Function::Params.empty,
|
2833
|
-
return_type: AST::Builtin.any_type,
|
2834
|
-
location: nil
|
2835
|
-
)
|
2836
|
-
|
2837
2685
|
params.params.each do |param|
|
2838
2686
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2839
2687
|
end
|
@@ -2878,6 +2726,10 @@ module Steep
|
|
2878
2726
|
)
|
2879
2727
|
|
2880
2728
|
if expected_block_type = block_constr.block_context.body_type
|
2729
|
+
type_vars = expected_block_type.free_variables
|
2730
|
+
subst = Interface::Substitution.build(type_vars, type_vars.map { AST::Builtin.any_type })
|
2731
|
+
expected_block_type = expected_block_type.subst(subst)
|
2732
|
+
|
2881
2733
|
check_relation(sub_type: return_type, super_type: expected_block_type).else do |result|
|
2882
2734
|
block_constr.typing.add_error(
|
2883
2735
|
Diagnostic::Ruby::BlockBodyTypeMismatch.new(
|
@@ -2921,6 +2773,20 @@ module Steep
|
|
2921
2773
|
constr
|
2922
2774
|
end
|
2923
2775
|
|
2776
|
+
KNOWN_PURE_METHODS = Set[
|
2777
|
+
MethodName("::Array#[]"),
|
2778
|
+
MethodName("::Hash#[]")
|
2779
|
+
]
|
2780
|
+
|
2781
|
+
def pure_send?(call, receiver, arguments)
|
2782
|
+
return false unless call.node.type == :send || call.node.type == :csend
|
2783
|
+
return false unless call.pure? || KNOWN_PURE_METHODS.superset?(Set.new(call.method_decls.map(&:method_name)))
|
2784
|
+
|
2785
|
+
[receiver, *arguments].all? do |node|
|
2786
|
+
!node || value_node?(node) || context.type_env[node]
|
2787
|
+
end
|
2788
|
+
end
|
2789
|
+
|
2924
2790
|
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:)
|
2925
2791
|
method = interface.methods[method_name]
|
2926
2792
|
|
@@ -2937,8 +2803,28 @@ module Steep
|
|
2937
2803
|
if call && constr
|
2938
2804
|
case method_name.to_s
|
2939
2805
|
when "[]=", /\w=\Z/
|
2940
|
-
|
2941
|
-
|
2806
|
+
last_arg = arguments.last or raise
|
2807
|
+
if typing.has_type?(last_arg)
|
2808
|
+
call = call.with_return_type(typing.type_of(node: last_arg))
|
2809
|
+
end
|
2810
|
+
end
|
2811
|
+
|
2812
|
+
if call.is_a?(TypeInference::MethodCall::Typed)
|
2813
|
+
if (pure_call, type = constr.context.type_env.pure_method_calls[node])
|
2814
|
+
if type
|
2815
|
+
call = pure_call.update(node: node, return_type: type)
|
2816
|
+
constr.add_typing(node, type: call.return_type)
|
2817
|
+
end
|
2818
|
+
else
|
2819
|
+
if pure_send?(call, receiver, arguments)
|
2820
|
+
constr = constr.update_type_env do |env|
|
2821
|
+
env.add_pure_call(node, call, call.return_type)
|
2822
|
+
end
|
2823
|
+
else
|
2824
|
+
constr = constr.update_type_env do |env|
|
2825
|
+
env.invalidate_pure_node(receiver)
|
2826
|
+
end
|
2827
|
+
end
|
2942
2828
|
end
|
2943
2829
|
end
|
2944
2830
|
|
@@ -2997,6 +2883,17 @@ module Steep
|
|
2997
2883
|
)
|
2998
2884
|
end
|
2999
2885
|
|
2886
|
+
if node.type == :block
|
2887
|
+
send_node = node.children[0]
|
2888
|
+
case send_node.type
|
2889
|
+
when :super, :zsuper
|
2890
|
+
method_name = method_context.name
|
2891
|
+
return fallback_to_any(send_node) do
|
2892
|
+
Diagnostic::Ruby::UnexpectedSuper.new(node: send_node, method: method_name)
|
2893
|
+
end
|
2894
|
+
end
|
2895
|
+
end
|
2896
|
+
|
3000
2897
|
constr.add_call(
|
3001
2898
|
TypeInference::MethodCall::NoMethodError.new(
|
3002
2899
|
node: node,
|
@@ -3093,6 +2990,15 @@ module Steep
|
|
3093
2990
|
private: private,
|
3094
2991
|
self_type: AST::Types::Self.new)
|
3095
2992
|
|
2993
|
+
if send_node.type == :super || send_node.type == :zsuper
|
2994
|
+
method_name = method_context.name
|
2995
|
+
unless method_context.super_method
|
2996
|
+
return fallback_to_any(send_node) do
|
2997
|
+
Diagnostic::Ruby::UnexpectedSuper.new(node: send_node, method: method_name)
|
2998
|
+
end
|
2999
|
+
end
|
3000
|
+
end
|
3001
|
+
|
3096
3002
|
constr.type_send_interface(node,
|
3097
3003
|
interface: interface,
|
3098
3004
|
receiver: receiver,
|
@@ -3144,6 +3050,9 @@ module Steep
|
|
3144
3050
|
array_compact: Set[
|
3145
3051
|
MethodName("::Array#compact"),
|
3146
3052
|
MethodName("::Enumerable#compact")
|
3053
|
+
],
|
3054
|
+
hash_compact: Set[
|
3055
|
+
MethodName("::Hash#compact")
|
3147
3056
|
]
|
3148
3057
|
}
|
3149
3058
|
|
@@ -3170,6 +3079,29 @@ module Steep
|
|
3170
3079
|
method_decls: decls
|
3171
3080
|
)
|
3172
3081
|
|
3082
|
+
return [call, constr]
|
3083
|
+
end
|
3084
|
+
end
|
3085
|
+
when decl = decls.find {|decl| SPECIAL_METHOD_NAMES[:hash_compact].include?(decl.method_name) }
|
3086
|
+
if arguments.empty? && !block_params
|
3087
|
+
# compact
|
3088
|
+
return_type = method_type.type.return_type
|
3089
|
+
if AST::Builtin::Hash.instance_type?(return_type)
|
3090
|
+
key = return_type.args[0]
|
3091
|
+
value = return_type.args[1]
|
3092
|
+
type = AST::Builtin::Hash.instance_type(key, unwrap(value))
|
3093
|
+
|
3094
|
+
_, constr = add_typing(node, type: type)
|
3095
|
+
call = TypeInference::MethodCall::Special.new(
|
3096
|
+
node: node,
|
3097
|
+
context: constr.context.method_context,
|
3098
|
+
method_name: decl.method_name,
|
3099
|
+
receiver_type: receiver_type,
|
3100
|
+
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
3101
|
+
return_type: type,
|
3102
|
+
method_decls: decls
|
3103
|
+
)
|
3104
|
+
|
3173
3105
|
return [call, constr]
|
3174
3106
|
end
|
3175
3107
|
end
|
@@ -3239,7 +3171,7 @@ module Steep
|
|
3239
3171
|
|
3240
3172
|
[
|
3241
3173
|
call,
|
3242
|
-
|
3174
|
+
update_type_env { constr.context.type_env }
|
3243
3175
|
]
|
3244
3176
|
end
|
3245
3177
|
|
@@ -3306,10 +3238,18 @@ module Steep
|
|
3306
3238
|
|
3307
3239
|
constr = self
|
3308
3240
|
|
3241
|
+
constr = constr.with(
|
3242
|
+
context: context.with(
|
3243
|
+
variable_context: TypeInference::Context::TypeVariableContext.new(
|
3244
|
+
type_params,
|
3245
|
+
parent_context: context.variable_context
|
3246
|
+
)
|
3247
|
+
)
|
3248
|
+
)
|
3249
|
+
|
3309
3250
|
method_type = method_type.instantiate(instantiation)
|
3310
3251
|
|
3311
3252
|
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
3312
|
-
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
3313
3253
|
constraints = Subtyping::Constraints.new(unknowns: type_params.map(&:name))
|
3314
3254
|
ccontext = Subtyping::Constraints::Context.new(
|
3315
3255
|
self_type: self_type,
|
@@ -3426,6 +3366,7 @@ module Steep
|
|
3426
3366
|
if pairs
|
3427
3367
|
# Block parameters are compatible with the block type
|
3428
3368
|
block_constr = constr.for_block(
|
3369
|
+
block_body,
|
3429
3370
|
block_params: block_params_,
|
3430
3371
|
block_param_hint: method_type.block.type.params,
|
3431
3372
|
block_type_hint: method_type.block.type.return_type,
|
@@ -3434,15 +3375,13 @@ module Steep
|
|
3434
3375
|
node_type_hint: method_type.type.return_type
|
3435
3376
|
)
|
3436
3377
|
block_constr = block_constr.with_new_typing(
|
3437
|
-
block_constr.typing.new_child(
|
3438
|
-
range: block_constr.typing.block_range(node)
|
3439
|
-
)
|
3378
|
+
block_constr.typing.new_child(block_constr.typing.block_range(node))
|
3440
3379
|
)
|
3441
3380
|
|
3442
3381
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
3443
3382
|
|
3444
3383
|
pairs.each do |param, type|
|
3445
|
-
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
|
3384
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type).to_ary
|
3446
3385
|
|
3447
3386
|
if param.type
|
3448
3387
|
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
@@ -3467,16 +3406,20 @@ module Steep
|
|
3467
3406
|
|
3468
3407
|
if solved
|
3469
3408
|
# Ready for type check the body of the block
|
3470
|
-
block_constr = block_constr.
|
3471
|
-
|
3472
|
-
|
3473
|
-
|
3474
|
-
|
3475
|
-
|
3409
|
+
block_constr = block_constr.update_type_env {|env| env.subst(s) }
|
3410
|
+
block_constr = block_constr.update_context {|context|
|
3411
|
+
context.with(
|
3412
|
+
type_env: context.type_env.subst(s),
|
3413
|
+
block_context: context.block_context&.subst(s),
|
3414
|
+
break_context: context.break_context&.subst(s)
|
3476
3415
|
)
|
3477
|
-
|
3478
|
-
|
3479
|
-
|
3416
|
+
}
|
3417
|
+
|
3418
|
+
block_body_type = block_constr.synthesize_block(
|
3419
|
+
node: node,
|
3420
|
+
block_body: block_body,
|
3421
|
+
block_type_hint: method_type.block.type.return_type
|
3422
|
+
)
|
3480
3423
|
|
3481
3424
|
result = check_relation(sub_type: block_body_type,
|
3482
3425
|
super_type: method_type.block.type.return_type,
|
@@ -3537,10 +3480,20 @@ module Steep
|
|
3537
3480
|
errors << error
|
3538
3481
|
end
|
3539
3482
|
|
3540
|
-
|
3541
|
-
|
3542
|
-
|
3543
|
-
|
3483
|
+
case node.children[0].type
|
3484
|
+
when :super, :zsuper
|
3485
|
+
unless method_context.super_method
|
3486
|
+
errors << Diagnostic::Ruby::UnexpectedSuper.new(
|
3487
|
+
node: node.children[0],
|
3488
|
+
method: method_name
|
3489
|
+
)
|
3490
|
+
end
|
3491
|
+
else
|
3492
|
+
errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
|
3493
|
+
node: node,
|
3494
|
+
method_type: method_type
|
3495
|
+
)
|
3496
|
+
end
|
3544
3497
|
|
3545
3498
|
method_type = eliminate_vars(method_type, type_param_names)
|
3546
3499
|
return_type = method_type.type.return_type
|
@@ -3652,6 +3605,12 @@ module Steep
|
|
3652
3605
|
)
|
3653
3606
|
end
|
3654
3607
|
|
3608
|
+
constr = constr.with(
|
3609
|
+
context: constr.context.with(
|
3610
|
+
variable_context: context.variable_context
|
3611
|
+
)
|
3612
|
+
)
|
3613
|
+
|
3655
3614
|
[
|
3656
3615
|
call,
|
3657
3616
|
constr
|
@@ -3683,12 +3642,13 @@ module Steep
|
|
3683
3642
|
end
|
3684
3643
|
|
3685
3644
|
block_constr = for_block(
|
3645
|
+
block_body,
|
3686
3646
|
block_params: block_params,
|
3687
3647
|
block_param_hint: nil,
|
3688
|
-
block_type_hint:
|
3648
|
+
block_type_hint: nil,
|
3689
3649
|
block_block_hint: nil,
|
3690
3650
|
block_annotations: block_annotations,
|
3691
|
-
node_type_hint:
|
3651
|
+
node_type_hint: nil
|
3692
3652
|
)
|
3693
3653
|
|
3694
3654
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
@@ -3713,7 +3673,7 @@ module Steep
|
|
3713
3673
|
end
|
3714
3674
|
end
|
3715
3675
|
|
3716
|
-
def for_block(block_params:, block_param_hint:, block_type_hint:, block_block_hint:, block_annotations:, node_type_hint:)
|
3676
|
+
def for_block(body_node, block_params:, block_param_hint:, block_type_hint:, block_block_hint:, block_annotations:, node_type_hint:)
|
3717
3677
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint, block_block_hint)
|
3718
3678
|
|
3719
3679
|
param_types_hash = {}
|
@@ -3729,14 +3689,32 @@ module Steep
|
|
3729
3689
|
end
|
3730
3690
|
end
|
3731
3691
|
|
3732
|
-
|
3733
|
-
hash[
|
3692
|
+
param_types = param_types_hash.each.with_object({}) do |pair, hash|
|
3693
|
+
# @type var hash: Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
3694
|
+
name, type = pair
|
3695
|
+
hash[name] = [type, nil]
|
3734
3696
|
end
|
3735
|
-
|
3736
|
-
|
3737
|
-
|
3738
|
-
|
3739
|
-
|
3697
|
+
|
3698
|
+
pins = context.type_env.pin_local_variables(nil)
|
3699
|
+
|
3700
|
+
type_env = context.type_env
|
3701
|
+
type_env = type_env.merge(local_variable_types: pins)
|
3702
|
+
type_env = type_env.merge(local_variable_types: param_types)
|
3703
|
+
type_env = TypeInference::TypeEnvBuilder.new(
|
3704
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(block_annotations).merge!.on_duplicate! do |name, outer_type, inner_type|
|
3705
|
+
next if outer_type.is_a?(AST::Types::Var) || inner_type.is_a?(AST::Types::Var)
|
3706
|
+
next unless body_node
|
3707
|
+
|
3708
|
+
if result = no_subtyping?(sub_type: outer_type, super_type: inner_type)
|
3709
|
+
typing.add_error Diagnostic::Ruby::IncompatibleAnnotation.new(
|
3710
|
+
node: body_node,
|
3711
|
+
var_name: name,
|
3712
|
+
result: result,
|
3713
|
+
relation: result.relation
|
3714
|
+
)
|
3715
|
+
end
|
3716
|
+
end
|
3717
|
+
).build(type_env)
|
3740
3718
|
|
3741
3719
|
break_type = if block_annotations.break_type
|
3742
3720
|
union_type(node_type_hint, block_annotations.break_type)
|
@@ -3745,21 +3723,18 @@ module Steep
|
|
3745
3723
|
end
|
3746
3724
|
|
3747
3725
|
block_context = TypeInference::Context::BlockContext.new(
|
3748
|
-
body_type: block_annotations.block_type || block_type_hint
|
3726
|
+
body_type: block_annotations.block_type || block_type_hint
|
3749
3727
|
)
|
3750
3728
|
break_context = TypeInference::Context::BreakContext.new(
|
3751
|
-
break_type: break_type,
|
3752
|
-
next_type: block_context.body_type
|
3729
|
+
break_type: break_type || AST::Builtin.any_type,
|
3730
|
+
next_type: block_context.body_type || AST::Builtin.any_type
|
3753
3731
|
)
|
3754
3732
|
|
3755
3733
|
self_type = self.self_type
|
3756
3734
|
module_context = self.module_context
|
3757
3735
|
|
3758
3736
|
if implements = block_annotations.implement_module_annotation
|
3759
|
-
module_context = default_module_context(
|
3760
|
-
implements.name,
|
3761
|
-
const_env: self.module_context.const_env
|
3762
|
-
)
|
3737
|
+
module_context = default_module_context(implements.name, nesting: nesting)
|
3763
3738
|
|
3764
3739
|
self_type = module_context.module_type
|
3765
3740
|
end
|
@@ -3779,8 +3754,7 @@ module Steep
|
|
3779
3754
|
module_context: module_context,
|
3780
3755
|
break_context: break_context,
|
3781
3756
|
self_type: self_type,
|
3782
|
-
type_env: type_env
|
3783
|
-
lvar_env: lvar_env,
|
3757
|
+
type_env: type_env,
|
3784
3758
|
call_context: self.context.call_context,
|
3785
3759
|
variable_context: variable_context
|
3786
3760
|
)
|
@@ -3800,35 +3774,10 @@ module Steep
|
|
3800
3774
|
end
|
3801
3775
|
end
|
3802
3776
|
|
3803
|
-
def each_child_node(node)
|
3804
|
-
if block_given?
|
3805
|
-
node.children.each do |child|
|
3806
|
-
if child.is_a?(::AST::Node)
|
3807
|
-
yield child
|
3808
|
-
end
|
3809
|
-
end
|
3810
|
-
else
|
3811
|
-
enum_for :each_child_node, node
|
3812
|
-
end
|
3813
|
-
end
|
3814
|
-
|
3815
3777
|
def nesting
|
3816
3778
|
module_context&.nesting
|
3817
3779
|
end
|
3818
3780
|
|
3819
|
-
def absolute_nested_module_name(module_name)
|
3820
|
-
n = nesting
|
3821
|
-
while n && !n[1]
|
3822
|
-
n = n[0]
|
3823
|
-
end
|
3824
|
-
|
3825
|
-
if n
|
3826
|
-
module_name.absolute!
|
3827
|
-
else
|
3828
|
-
n + module_name
|
3829
|
-
end
|
3830
|
-
end
|
3831
|
-
|
3832
3781
|
def absolute_name(name)
|
3833
3782
|
checker.factory.absolute_type_name(name, context: nesting)
|
3834
3783
|
end
|
@@ -4025,12 +3974,14 @@ module Steep
|
|
4025
3974
|
end
|
4026
3975
|
|
4027
3976
|
def try_tuple_type!(node, hint: nil)
|
4028
|
-
if node.type == :array
|
4029
|
-
|
3977
|
+
if node.type == :array
|
3978
|
+
if hint.nil? || hint.is_a?(AST::Types::Tuple)
|
3979
|
+
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
4030
3980
|
|
4031
|
-
|
4032
|
-
|
4033
|
-
|
3981
|
+
typing.new_child(node_range) do |child_typing|
|
3982
|
+
if pair = with_new_typing(child_typing).try_tuple_type(node, hint)
|
3983
|
+
return pair.with(constr: pair.constr.save_typing)
|
3984
|
+
end
|
4034
3985
|
end
|
4035
3986
|
end
|
4036
3987
|
end
|
@@ -4065,13 +4016,13 @@ module Steep
|
|
4065
4016
|
return
|
4066
4017
|
end
|
4067
4018
|
|
4068
|
-
interface = checker.factory.interface(type, private: false)
|
4019
|
+
interface = checker.factory.interface(type, private: false, self_type: self_type)
|
4069
4020
|
if entry = interface.methods[method]
|
4070
4021
|
method_type = entry.method_types.find do |method_type|
|
4071
4022
|
method_type.type.params.optional?
|
4072
4023
|
end
|
4073
4024
|
|
4074
|
-
method_type.type.return_type
|
4025
|
+
method_type.type.return_type if method_type
|
4075
4026
|
end
|
4076
4027
|
rescue => exn
|
4077
4028
|
Steep.log_error(exn, message: "Unexpected error when converting #{type.to_s} with #{method}")
|
@@ -4109,20 +4060,15 @@ module Steep
|
|
4109
4060
|
constr.add_typing(node, type: AST::Builtin::Array.instance_type(element_type))
|
4110
4061
|
end
|
4111
4062
|
|
4112
|
-
# Try to give record type to hash_node.
|
4113
|
-
#
|
4114
|
-
# Returns nil when it cannot have a record type.
|
4115
|
-
# `record_type` can be nil when the keys are not specified.
|
4116
|
-
#
|
4117
4063
|
def type_hash_record(hash_node, record_type)
|
4118
4064
|
raise unless hash_node.type == :hash || hash_node.type == :kwargs
|
4119
4065
|
|
4120
4066
|
constr = self
|
4121
4067
|
|
4122
4068
|
if record_type
|
4123
|
-
|
4069
|
+
hints = record_type.elements.dup
|
4124
4070
|
else
|
4125
|
-
|
4071
|
+
hints = {}
|
4126
4072
|
end
|
4127
4073
|
|
4128
4074
|
elems = {}
|
@@ -4137,7 +4083,18 @@ module Steep
|
|
4137
4083
|
key = key_node.children[0]
|
4138
4084
|
|
4139
4085
|
_, constr = constr.synthesize(key_node, hint: AST::Types::Literal.new(value: key))
|
4140
|
-
|
4086
|
+
|
4087
|
+
value_type, constr = constr.synthesize(value_node, hint: hints[key])
|
4088
|
+
|
4089
|
+
if hints.key?(key)
|
4090
|
+
hint_type = hints[key]
|
4091
|
+
case
|
4092
|
+
when value_type.is_a?(AST::Types::Any)
|
4093
|
+
value_type = hints[key]
|
4094
|
+
when hint_type.is_a?(AST::Types::Var)
|
4095
|
+
value_type = value_type
|
4096
|
+
end
|
4097
|
+
end
|
4141
4098
|
|
4142
4099
|
elems[key] = value_type
|
4143
4100
|
else
|
@@ -4240,11 +4197,11 @@ module Steep
|
|
4240
4197
|
def pick_one_of(types, range:)
|
4241
4198
|
types.each do |type|
|
4242
4199
|
with_child_typing(range: range) do |constr|
|
4243
|
-
type_, constr = yield
|
4244
|
-
|
4245
|
-
|
4246
|
-
|
4247
|
-
|
4200
|
+
if (type_, constr = yield(type, constr))
|
4201
|
+
constr.check_relation(sub_type: type_, super_type: type).then do
|
4202
|
+
constr = constr.save_typing
|
4203
|
+
return Pair.new(type: type, constr: constr)
|
4204
|
+
end
|
4248
4205
|
end
|
4249
4206
|
end
|
4250
4207
|
end
|