steep 0.37.0 → 0.42.0
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.yml +1 -1
- data/CHANGELOG.md +34 -0
- data/Rakefile +5 -2
- data/bin/output_rebaseline.rb +34 -0
- data/bin/output_test.rb +53 -0
- data/lib/steep.rb +95 -14
- data/lib/steep/ast/types/bot.rb +1 -1
- data/lib/steep/ast/types/class.rb +4 -0
- data/lib/steep/ast/types/factory.rb +10 -0
- data/lib/steep/ast/types/logic.rb +16 -3
- data/lib/steep/ast/types/top.rb +1 -1
- data/lib/steep/cli.rb +31 -7
- data/lib/steep/diagnostic/helper.rb +17 -0
- data/lib/steep/diagnostic/lsp_formatter.rb +16 -0
- data/lib/steep/diagnostic/ruby.rb +619 -0
- data/lib/steep/diagnostic/signature.rb +357 -0
- data/lib/steep/drivers/annotations.rb +19 -28
- data/lib/steep/drivers/check.rb +182 -60
- data/lib/steep/drivers/diagnostic_printer.rb +99 -0
- data/lib/steep/drivers/langserver.rb +3 -8
- data/lib/steep/drivers/print_project.rb +10 -9
- data/lib/steep/drivers/stats.rb +124 -32
- data/lib/steep/drivers/trace_printer.rb +5 -1
- data/lib/steep/drivers/utils/jobs_count.rb +9 -0
- data/lib/steep/drivers/validate.rb +31 -13
- data/lib/steep/drivers/watch.rb +69 -48
- data/lib/steep/drivers/worker.rb +16 -8
- data/lib/steep/expectations.rb +159 -0
- data/lib/steep/index/rbs_index.rb +334 -0
- data/lib/steep/index/signature_symbol_provider.rb +162 -0
- data/lib/steep/index/source_index.rb +100 -0
- data/lib/steep/project.rb +0 -30
- data/lib/steep/project/dsl.rb +5 -3
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/pattern.rb +56 -0
- data/lib/steep/project/target.rb +9 -214
- data/lib/steep/range_extension.rb +29 -0
- data/lib/steep/server/base_worker.rb +43 -7
- data/lib/steep/server/change_buffer.rb +63 -0
- data/lib/steep/server/interaction_worker.rb +73 -56
- data/lib/steep/server/master.rb +245 -109
- data/lib/steep/server/type_check_worker.rb +122 -0
- data/lib/steep/server/worker_process.rb +17 -15
- data/lib/steep/{project → services}/completion_provider.rb +3 -3
- data/lib/steep/services/content_change.rb +61 -0
- data/lib/steep/services/file_loader.rb +48 -0
- data/lib/steep/{project → services}/hover_content.rb +14 -16
- data/lib/steep/services/path_assignment.rb +29 -0
- data/lib/steep/services/signature_service.rb +369 -0
- data/lib/steep/services/stats_calculator.rb +69 -0
- data/lib/steep/services/type_check_service.rb +342 -0
- data/lib/steep/signature/validator.rb +174 -32
- data/lib/steep/subtyping/check.rb +248 -47
- data/lib/steep/subtyping/constraints.rb +2 -2
- data/lib/steep/type_construction.rb +565 -295
- data/lib/steep/type_inference/constant_env.rb +5 -1
- data/lib/steep/type_inference/local_variable_type_env.rb +26 -12
- data/lib/steep/type_inference/logic_type_interpreter.rb +99 -26
- data/lib/steep/type_inference/type_env.rb +43 -17
- data/lib/steep/typing.rb +8 -2
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +0 -3
- data/smoke/alias/b.rb +0 -1
- data/smoke/alias/c.rb +0 -2
- data/smoke/alias/test_expectations.yml +96 -0
- data/smoke/and/a.rb +0 -3
- data/smoke/and/test_expectations.yml +31 -0
- data/smoke/array/a.rb +0 -3
- data/smoke/array/b.rb +0 -2
- data/smoke/array/c.rb +0 -1
- data/smoke/array/test_expectations.yml +103 -0
- data/smoke/block/a.rb +0 -2
- data/smoke/block/b.rb +0 -2
- data/smoke/block/d.rb +0 -4
- data/smoke/block/test_expectations.yml +125 -0
- data/smoke/case/a.rb +0 -3
- data/smoke/case/test_expectations.yml +47 -0
- data/smoke/class/a.rb +0 -3
- data/smoke/class/c.rb +0 -1
- data/smoke/class/f.rb +0 -1
- data/smoke/class/g.rb +0 -2
- data/smoke/class/i.rb +0 -2
- data/smoke/class/test_expectations.yml +120 -0
- data/smoke/const/a.rb +0 -3
- data/smoke/const/b.rb +7 -0
- data/smoke/const/b.rbs +5 -0
- data/smoke/const/test_expectations.yml +139 -0
- data/smoke/diagnostics-rbs-duplicated/Steepfile +5 -0
- data/smoke/diagnostics-rbs-duplicated/a.rbs +5 -0
- data/smoke/diagnostics-rbs-duplicated/test_expectations.yml +13 -0
- data/smoke/diagnostics-rbs/Steepfile +8 -0
- data/smoke/diagnostics-rbs/duplicated-method-definition.rbs +20 -0
- data/smoke/diagnostics-rbs/generic-parameter-mismatch.rbs +7 -0
- data/smoke/diagnostics-rbs/invalid-method-overload.rbs +3 -0
- data/smoke/diagnostics-rbs/invalid-type-application.rbs +7 -0
- data/smoke/diagnostics-rbs/invalid_variance_annotation.rbs +3 -0
- data/smoke/diagnostics-rbs/recursive-alias.rbs +5 -0
- data/smoke/diagnostics-rbs/recursive-class.rbs +8 -0
- data/smoke/diagnostics-rbs/superclass-mismatch.rbs +7 -0
- data/smoke/diagnostics-rbs/test_expectations.yml +231 -0
- data/smoke/diagnostics-rbs/unknown-method-alias.rbs +3 -0
- data/smoke/diagnostics-rbs/unknown-type-name-2.rbs +5 -0
- data/smoke/diagnostics-rbs/unknown-type-name.rbs +13 -0
- data/smoke/diagnostics/Steepfile +5 -0
- data/smoke/diagnostics/a.rbs +26 -0
- data/smoke/diagnostics/argument_type_mismatch.rb +1 -0
- data/smoke/diagnostics/block_body_type_mismatch.rb +1 -0
- data/smoke/diagnostics/block_type_mismatch.rb +3 -0
- data/smoke/diagnostics/break_type_mismatch.rb +1 -0
- data/smoke/diagnostics/else_on_exhaustive_case.rb +12 -0
- data/smoke/diagnostics/incompatible_annotation.rb +6 -0
- data/smoke/diagnostics/incompatible_argument.rb +1 -0
- data/smoke/diagnostics/incompatible_assignment.rb +8 -0
- data/smoke/diagnostics/method_arity_mismatch.rb +11 -0
- data/smoke/diagnostics/method_body_type_mismatch.rb +6 -0
- data/smoke/diagnostics/method_definition_missing.rb +2 -0
- data/smoke/diagnostics/method_return_type_annotation_mismatch.rb +7 -0
- data/smoke/diagnostics/missing_keyword.rb +1 -0
- data/smoke/diagnostics/no_method.rb +1 -0
- data/smoke/diagnostics/required_block_missing.rb +1 -0
- data/smoke/diagnostics/return_type_mismatch.rb +6 -0
- data/smoke/diagnostics/test_expectations.yml +477 -0
- data/smoke/diagnostics/unexpected_block_given.rb +1 -0
- data/smoke/diagnostics/unexpected_dynamic_method.rb +3 -0
- data/smoke/diagnostics/unexpected_jump.rb +4 -0
- data/smoke/diagnostics/unexpected_jump_value.rb +3 -0
- data/smoke/diagnostics/unexpected_keyword.rb +1 -0
- data/smoke/diagnostics/unexpected_splat.rb +1 -0
- data/smoke/diagnostics/unexpected_yield.rb +6 -0
- data/smoke/diagnostics/unknown_constant_assigned.rb +7 -0
- data/smoke/diagnostics/unresolved_overloading.rb +1 -0
- data/smoke/diagnostics/unsatisfiable_constraint.rb +7 -0
- data/smoke/diagnostics/unsupported_syntax.rb +2 -0
- data/smoke/dstr/a.rb +0 -1
- data/smoke/dstr/test_expectations.yml +13 -0
- data/smoke/ensure/a.rb +0 -4
- data/smoke/ensure/test_expectations.yml +62 -0
- data/smoke/enumerator/a.rb +0 -6
- data/smoke/enumerator/b.rb +0 -3
- data/smoke/enumerator/test_expectations.yml +135 -0
- data/smoke/extension/a.rb +0 -1
- data/smoke/extension/b.rb +0 -2
- data/smoke/extension/c.rb +0 -1
- data/smoke/extension/f.rb +2 -0
- data/smoke/extension/f.rbs +3 -0
- data/smoke/extension/test_expectations.yml +73 -0
- data/smoke/hash/b.rb +0 -1
- data/smoke/hash/c.rb +0 -3
- data/smoke/hash/d.rb +0 -1
- data/smoke/hash/e.rb +0 -1
- data/smoke/hash/test_expectations.yml +81 -0
- data/smoke/hello/hello.rb +0 -2
- data/smoke/hello/test_expectations.yml +25 -0
- data/smoke/if/a.rb +0 -2
- data/smoke/if/test_expectations.yml +34 -0
- data/smoke/implements/a.rb +0 -2
- data/smoke/implements/test_expectations.yml +23 -0
- data/smoke/initialize/test_expectations.yml +1 -0
- data/smoke/integer/a.rb +0 -7
- data/smoke/integer/test_expectations.yml +101 -0
- data/smoke/interface/a.rb +0 -2
- data/smoke/interface/test_expectations.yml +23 -0
- data/smoke/kwbegin/a.rb +0 -1
- data/smoke/kwbegin/test_expectations.yml +17 -0
- data/smoke/lambda/a.rb +1 -4
- data/smoke/lambda/test_expectations.yml +39 -0
- data/smoke/literal/a.rb +0 -5
- data/smoke/literal/b.rb +0 -2
- data/smoke/literal/test_expectations.yml +106 -0
- data/smoke/map/test_expectations.yml +1 -0
- data/smoke/method/a.rb +0 -5
- data/smoke/method/b.rb +0 -1
- data/smoke/method/test_expectations.yml +90 -0
- data/smoke/module/a.rb +0 -2
- data/smoke/module/b.rb +0 -2
- data/smoke/module/c.rb +0 -1
- data/smoke/module/d.rb +0 -1
- data/smoke/module/f.rb +0 -2
- data/smoke/module/test_expectations.yml +75 -0
- data/smoke/regexp/a.rb +0 -38
- data/smoke/regexp/b.rb +0 -26
- data/smoke/regexp/test_expectations.yml +615 -0
- data/smoke/regression/set_divide.rb +0 -4
- data/smoke/regression/test_expectations.yml +43 -0
- data/smoke/rescue/a.rb +0 -5
- data/smoke/rescue/test_expectations.yml +79 -0
- data/smoke/self/a.rb +0 -2
- data/smoke/self/test_expectations.yml +23 -0
- data/smoke/skip/skip.rb +0 -2
- data/smoke/skip/test_expectations.yml +23 -0
- data/smoke/stdout/test_expectations.yml +1 -0
- data/smoke/super/a.rb +0 -4
- data/smoke/super/test_expectations.yml +79 -0
- data/smoke/toplevel/a.rb +0 -1
- data/smoke/toplevel/test_expectations.yml +15 -0
- data/smoke/tsort/Steepfile +2 -0
- data/smoke/tsort/a.rb +0 -3
- data/smoke/tsort/test_expectations.yml +63 -0
- data/smoke/type_case/a.rb +0 -4
- data/smoke/type_case/test_expectations.yml +48 -0
- data/smoke/unexpected/Steepfile +5 -0
- data/smoke/unexpected/test_expectations.yml +25 -0
- data/smoke/unexpected/unexpected.rb +1 -0
- data/smoke/unexpected/unexpected.rbs +3 -0
- data/smoke/yield/a.rb +0 -3
- data/smoke/yield/b.rb +6 -0
- data/smoke/yield/test_expectations.yml +68 -0
- data/steep.gemspec +4 -3
- metadata +144 -29
- data/bin/smoke_runner.rb +0 -139
- data/lib/steep/drivers/signature_error_printer.rb +0 -25
- data/lib/steep/errors.rb +0 -565
- data/lib/steep/project/file_loader.rb +0 -68
- data/lib/steep/project/signature_file.rb +0 -33
- data/lib/steep/project/source_file.rb +0 -129
- data/lib/steep/server/code_worker.rb +0 -137
- data/lib/steep/server/signature_worker.rb +0 -152
- data/lib/steep/server/utils.rb +0 -69
- data/lib/steep/signature/errors.rb +0 -82
- data/lib/steep/type_assignability.rb +0 -367
@@ -207,7 +207,7 @@ module Steep
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
-
def solution(checker, variance:, variables:, self_type:)
|
210
|
+
def solution(checker, variance:, variables:, self_type:, instance_type:, class_type:)
|
211
211
|
vars = []
|
212
212
|
types = []
|
213
213
|
|
@@ -218,7 +218,7 @@ module Steep
|
|
218
218
|
lower_bound = lower_bound(var)
|
219
219
|
relation = Relation.new(sub_type: lower_bound, super_type: upper_bound)
|
220
220
|
|
221
|
-
checker.check(relation, self_type: self_type, constraints: self.class.empty).yield_self do |result|
|
221
|
+
checker.check(relation, self_type: self_type, instance_type: instance_type, class_type: class_type, constraints: self.class.empty).yield_self do |result|
|
222
222
|
if result.success?
|
223
223
|
vars << var
|
224
224
|
|
@@ -115,8 +115,15 @@ module Steep
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
|
118
|
-
Steep.logger.debug { "check_relation: self:#{self_type} |- #{sub_type} <: #{super_type}" }
|
119
|
-
|
118
|
+
Steep.logger.debug { "check_relation: self:#{self_type}, instance:#{module_context.instance_type}, class:#{module_context.module_type} |- #{sub_type} <: #{super_type}" }
|
119
|
+
relation = Subtyping::Relation.new(sub_type: sub_type, super_type: super_type)
|
120
|
+
checker.check(
|
121
|
+
relation,
|
122
|
+
self_type: self_type,
|
123
|
+
instance_type: module_context.instance_type,
|
124
|
+
class_type: module_context.module_type,
|
125
|
+
constraints: constraints
|
126
|
+
)
|
120
127
|
end
|
121
128
|
|
122
129
|
def for_new_method(method_name, node, args:, self_type:, definition:)
|
@@ -142,10 +149,14 @@ module Steep
|
|
142
149
|
|
143
150
|
if annots&.return_type && method_type&.type&.return_type
|
144
151
|
check_relation(sub_type: annots.return_type, super_type: method_type.type.return_type).else do |result|
|
145
|
-
typing.add_error
|
146
|
-
|
147
|
-
|
148
|
-
|
152
|
+
typing.add_error(
|
153
|
+
Diagnostic::Ruby::MethodReturnTypeAnnotationMismatch.new(
|
154
|
+
node: node,
|
155
|
+
method_type: method_type.type.return_type,
|
156
|
+
annotation_type: annots.return_type,
|
157
|
+
result: result
|
158
|
+
)
|
159
|
+
)
|
149
160
|
end
|
150
161
|
end
|
151
162
|
|
@@ -154,7 +165,7 @@ module Steep
|
|
154
165
|
if method_type
|
155
166
|
var_types = TypeConstruction.parameter_types(args, method_type.type)
|
156
167
|
unless TypeConstruction.valid_parameter_env?(var_types, args.reject {|arg| arg.type == :blockarg}, method_type.type.params)
|
157
|
-
typing.add_error
|
168
|
+
typing.add_error Diagnostic::Ruby::MethodArityMismatch.new(node: node, method_type: method_type)
|
158
169
|
end
|
159
170
|
end
|
160
171
|
|
@@ -196,12 +207,16 @@ module Steep
|
|
196
207
|
type_env = type_env.with_annotations(
|
197
208
|
ivar_types: annots.ivar_types,
|
198
209
|
const_types: annots.const_types,
|
199
|
-
self_type: annots.self_type || self_type
|
210
|
+
self_type: annots.self_type || self_type,
|
211
|
+
instance_type: module_context.instance_type,
|
212
|
+
class_type: module_context.module_type
|
200
213
|
)
|
201
214
|
|
202
215
|
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
203
216
|
subtyping: checker,
|
204
|
-
self_type: annots.self_type || self_type
|
217
|
+
self_type: annots.self_type || self_type,
|
218
|
+
instance_type: module_context.instance_type,
|
219
|
+
class_type: module_context.module_type
|
205
220
|
)
|
206
221
|
|
207
222
|
if var_types
|
@@ -355,7 +370,9 @@ module Steep
|
|
355
370
|
|
356
371
|
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
357
372
|
subtyping: checker,
|
358
|
-
self_type: module_context_.module_type
|
373
|
+
self_type: module_context_.module_type,
|
374
|
+
instance_type: module_context_.instance_type,
|
375
|
+
class_type: module_context_.module_type
|
359
376
|
).annotate(annots)
|
360
377
|
|
361
378
|
self.class.new(
|
@@ -399,6 +416,9 @@ module Steep
|
|
399
416
|
|
400
417
|
instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
|
401
418
|
module_type = AST::Types::Name::Singleton.new(name: class_name)
|
419
|
+
else
|
420
|
+
instance_type = AST::Builtin::Object.instance_type
|
421
|
+
module_type = AST::Builtin::Object.module_type
|
402
422
|
end
|
403
423
|
|
404
424
|
if annots.instance_type
|
@@ -430,7 +450,9 @@ module Steep
|
|
430
450
|
|
431
451
|
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
432
452
|
subtyping: checker,
|
433
|
-
self_type: module_context.module_type
|
453
|
+
self_type: module_context.module_type,
|
454
|
+
instance_type: module_context.instance_type,
|
455
|
+
class_type: module_context.module_type
|
434
456
|
).annotate(annots)
|
435
457
|
|
436
458
|
class_body_context = TypeInference::Context.new(
|
@@ -516,7 +538,9 @@ module Steep
|
|
516
538
|
|
517
539
|
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
518
540
|
subtyping: checker,
|
519
|
-
self_type: module_context.module_type
|
541
|
+
self_type: module_context.module_type,
|
542
|
+
instance_type: module_context.instance_type,
|
543
|
+
class_type: module_context.module_type
|
520
544
|
).annotate(annots)
|
521
545
|
|
522
546
|
body_context = TypeInference::Context.new(
|
@@ -571,7 +595,7 @@ module Steep
|
|
571
595
|
lvar_env.assign!(name, node: node, type: type) do |declared_type, assigned_type, result|
|
572
596
|
relation = Subtyping::Relation.new(sub_type: assigned_type, super_type: declared_type)
|
573
597
|
typing.add_error(
|
574
|
-
|
598
|
+
Diagnostic::Ruby::IncompatibleTypeCase.new(
|
575
599
|
node: node,
|
576
600
|
var_name: name,
|
577
601
|
relation: relation,
|
@@ -585,30 +609,40 @@ module Steep
|
|
585
609
|
lvar_env = lvar_env.annotate(annots) do |var, outer_type, inner_type, result|
|
586
610
|
relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
|
587
611
|
typing.add_error(
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
612
|
+
Diagnostic::Ruby::IncompatibleAnnotation.new(
|
613
|
+
node: node,
|
614
|
+
var_name: var,
|
615
|
+
relation: relation,
|
616
|
+
result: result
|
617
|
+
)
|
592
618
|
)
|
593
619
|
end
|
594
620
|
|
595
621
|
type_env = context.type_env
|
596
622
|
|
597
623
|
if type_case_override
|
598
|
-
type_env = type_env.with_annotations(
|
624
|
+
type_env = type_env.with_annotations(
|
625
|
+
self_type: self_type,
|
626
|
+
instance_type: module_context.instance_type,
|
627
|
+
class_type: module_context.module_type
|
628
|
+
)
|
599
629
|
end
|
600
630
|
|
601
631
|
type_env = type_env.with_annotations(
|
602
632
|
ivar_types: annots.ivar_types,
|
603
633
|
const_types: annots.const_types,
|
604
634
|
gvar_types: {},
|
605
|
-
self_type: self_type
|
635
|
+
self_type: self_type,
|
636
|
+
instance_type: module_context.instance_type,
|
637
|
+
class_type: module_context.module_type
|
606
638
|
) do |var, relation, result|
|
607
639
|
typing.add_error(
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
640
|
+
Diagnostic::Ruby::IncompatibleAnnotation.new(
|
641
|
+
node: node,
|
642
|
+
var_name: var,
|
643
|
+
relation: relation,
|
644
|
+
result: result
|
645
|
+
)
|
612
646
|
)
|
613
647
|
end
|
614
648
|
|
@@ -642,7 +676,7 @@ module Steep
|
|
642
676
|
Pair.new(type: call.return_type, constr: self)
|
643
677
|
end
|
644
678
|
|
645
|
-
def synthesize(node, hint: nil)
|
679
|
+
def synthesize(node, hint: nil, condition: false)
|
646
680
|
Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
|
647
681
|
Steep.logger.debug node.type
|
648
682
|
case node.type
|
@@ -691,10 +725,14 @@ module Steep
|
|
691
725
|
|
692
726
|
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
693
727
|
lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
|
694
|
-
typing.add_error(
|
695
|
-
|
696
|
-
|
697
|
-
|
728
|
+
typing.add_error(
|
729
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
730
|
+
node: node,
|
731
|
+
lhs_type: declared_type,
|
732
|
+
rhs_type: actual_type,
|
733
|
+
result: result
|
734
|
+
)
|
735
|
+
)
|
698
736
|
end
|
699
737
|
end
|
700
738
|
|
@@ -849,7 +887,7 @@ module Steep
|
|
849
887
|
constr.add_call(call)
|
850
888
|
else
|
851
889
|
fallback_to_any node do
|
852
|
-
|
890
|
+
Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context.name)
|
853
891
|
end
|
854
892
|
end
|
855
893
|
else
|
@@ -879,18 +917,20 @@ module Steep
|
|
879
917
|
new.typing.add_context_for_node(node, context: new.context)
|
880
918
|
new.typing.add_context_for_body(node, context: new.context)
|
881
919
|
|
882
|
-
|
883
|
-
_, new = new.synthesize(arg)
|
884
|
-
end
|
920
|
+
new = new.synthesize_children(args_node)
|
885
921
|
|
886
922
|
body_pair = if body_node
|
887
923
|
return_type = expand_alias(new.method_context&.return_type)
|
888
924
|
if return_type && !return_type.is_a?(AST::Types::Void)
|
889
925
|
new.check(body_node, return_type) do |_, actual_type, result|
|
890
|
-
typing.add_error(
|
891
|
-
|
892
|
-
|
893
|
-
|
926
|
+
typing.add_error(
|
927
|
+
Diagnostic::Ruby::MethodBodyTypeMismatch.new(
|
928
|
+
node: node,
|
929
|
+
expected: new.method_context&.return_type,
|
930
|
+
actual: actual_type,
|
931
|
+
result: result
|
932
|
+
)
|
933
|
+
)
|
894
934
|
end
|
895
935
|
else
|
896
936
|
new.synthesize(body_node)
|
@@ -900,10 +940,14 @@ module Steep
|
|
900
940
|
if return_type && !return_type.is_a?(AST::Types::Void)
|
901
941
|
result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
|
902
942
|
if result.failure?
|
903
|
-
typing.add_error(
|
904
|
-
|
905
|
-
|
906
|
-
|
943
|
+
typing.add_error(
|
944
|
+
Diagnostic::Ruby::MethodBodyTypeMismatch.new(
|
945
|
+
node: node,
|
946
|
+
expected: new.method_context&.return_type,
|
947
|
+
actual: AST::Builtin.nil_type,
|
948
|
+
result: result
|
949
|
+
)
|
950
|
+
)
|
907
951
|
end
|
908
952
|
end
|
909
953
|
|
@@ -936,14 +980,17 @@ module Steep
|
|
936
980
|
checker.factory.definition_builder.build_singleton(name)
|
937
981
|
end
|
938
982
|
|
983
|
+
args_node = node.children[2]
|
939
984
|
new = for_new_method(node.children[1],
|
940
985
|
node,
|
941
|
-
args:
|
986
|
+
args: args_node.children,
|
942
987
|
self_type: self_type,
|
943
988
|
definition: definition)
|
944
989
|
new.typing.add_context_for_node(node, context: new.context)
|
945
990
|
new.typing.add_context_for_body(node, context: new.context)
|
946
991
|
|
992
|
+
new = new.synthesize_children(args_node)
|
993
|
+
|
947
994
|
each_child_node(node.children[2]) do |arg|
|
948
995
|
new.synthesize(arg)
|
949
996
|
end
|
@@ -952,10 +999,14 @@ module Steep
|
|
952
999
|
return_type = expand_alias(new.method_context&.return_type)
|
953
1000
|
if return_type && !return_type.is_a?(AST::Types::Void)
|
954
1001
|
new.check(node.children[3], return_type) do |return_type, actual_type, result|
|
955
|
-
typing.add_error(
|
956
|
-
|
957
|
-
|
958
|
-
|
1002
|
+
typing.add_error(
|
1003
|
+
Diagnostic::Ruby::MethodBodyTypeMismatch.new(
|
1004
|
+
node: node,
|
1005
|
+
expected: return_type,
|
1006
|
+
actual: actual_type,
|
1007
|
+
result: result
|
1008
|
+
)
|
1009
|
+
)
|
959
1010
|
end
|
960
1011
|
else
|
961
1012
|
new.synthesize(node.children[3])
|
@@ -996,10 +1047,14 @@ module Steep
|
|
996
1047
|
result = check_relation(sub_type: value_type, super_type: method_return_type)
|
997
1048
|
|
998
1049
|
if result.failure?
|
999
|
-
typing.add_error(
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1050
|
+
typing.add_error(
|
1051
|
+
Diagnostic::Ruby::ReturnTypeMismatch.new(
|
1052
|
+
node: node,
|
1053
|
+
expected: method_context&.return_type,
|
1054
|
+
actual: value_type,
|
1055
|
+
result: result
|
1056
|
+
)
|
1057
|
+
)
|
1003
1058
|
end
|
1004
1059
|
end
|
1005
1060
|
end
|
@@ -1012,23 +1067,39 @@ module Steep
|
|
1012
1067
|
value = node.children[0]
|
1013
1068
|
|
1014
1069
|
if break_context
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1070
|
+
if break_type = break_context.break_type
|
1071
|
+
if value
|
1072
|
+
check(value, break_type) do |break_type, actual_type, result|
|
1073
|
+
typing.add_error(
|
1074
|
+
Diagnostic::Ruby::BreakTypeMismatch.new(
|
1075
|
+
node: node,
|
1076
|
+
expected: break_type,
|
1077
|
+
actual: actual_type,
|
1078
|
+
result: result
|
1079
|
+
)
|
1080
|
+
)
|
1081
|
+
end
|
1082
|
+
else
|
1083
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: break_type).else do |result|
|
1084
|
+
typing.add_error(
|
1085
|
+
Diagnostic::Ruby::BreakTypeMismatch.new(
|
1086
|
+
node: node,
|
1087
|
+
expected: break_type,
|
1088
|
+
actual: AST::Builtin.nil_type,
|
1089
|
+
result: result
|
1090
|
+
)
|
1091
|
+
)
|
1092
|
+
end
|
1022
1093
|
end
|
1023
|
-
when !value
|
1024
|
-
# ok
|
1025
1094
|
else
|
1026
|
-
|
1027
|
-
|
1095
|
+
if value
|
1096
|
+
synthesize(value)
|
1097
|
+
typing.add_error Diagnostic::Ruby::UnexpectedJumpValue.new(node: node)
|
1098
|
+
end
|
1028
1099
|
end
|
1029
1100
|
else
|
1030
|
-
synthesize(value)
|
1031
|
-
typing.add_error
|
1101
|
+
synthesize(value) if value
|
1102
|
+
typing.add_error Diagnostic::Ruby::UnexpectedJump.new(node: node)
|
1032
1103
|
end
|
1033
1104
|
|
1034
1105
|
add_typing(node, type: AST::Builtin.bottom_type)
|
@@ -1037,30 +1108,48 @@ module Steep
|
|
1037
1108
|
value = node.children[0]
|
1038
1109
|
|
1039
1110
|
if break_context
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1111
|
+
if next_type = break_context.next_type
|
1112
|
+
next_type = deep_expand_alias(next_type)
|
1113
|
+
|
1114
|
+
if value
|
1115
|
+
_, constr = check(value, next_type) do |break_type, actual_type, result|
|
1116
|
+
typing.add_error(
|
1117
|
+
Diagnostic::Ruby::BreakTypeMismatch.new(
|
1118
|
+
node: node,
|
1119
|
+
expected: break_type,
|
1120
|
+
actual: actual_type,
|
1121
|
+
result: result
|
1122
|
+
)
|
1123
|
+
)
|
1124
|
+
end
|
1125
|
+
else
|
1126
|
+
check_relation(sub_type: AST::Builtin.nil_type, super_type: next_type).else do |result|
|
1127
|
+
typing.add_error(
|
1128
|
+
Diagnostic::Ruby::BreakTypeMismatch.new(
|
1129
|
+
node: node,
|
1130
|
+
expected: next_type,
|
1131
|
+
actual: AST::Builtin.nil_type,
|
1132
|
+
result: result
|
1133
|
+
)
|
1134
|
+
)
|
1135
|
+
end
|
1047
1136
|
end
|
1048
|
-
when !value
|
1049
|
-
# ok
|
1050
1137
|
else
|
1051
|
-
|
1052
|
-
|
1138
|
+
if value
|
1139
|
+
synthesize(value)
|
1140
|
+
typing.add_error Diagnostic::Ruby::UnexpectedJumpValue.new(node: node)
|
1141
|
+
end
|
1053
1142
|
end
|
1054
1143
|
else
|
1055
|
-
synthesize(value)
|
1056
|
-
typing.add_error
|
1144
|
+
synthesize(value) if value
|
1145
|
+
typing.add_error Diagnostic::Ruby::UnexpectedJump.new(node: node)
|
1057
1146
|
end
|
1058
1147
|
|
1059
1148
|
add_typing(node, type: AST::Builtin.bottom_type)
|
1060
1149
|
|
1061
1150
|
when :retry
|
1062
1151
|
unless break_context
|
1063
|
-
typing.add_error
|
1152
|
+
typing.add_error Diagnostic::Ruby::UnexpectedJump.new(node: node)
|
1064
1153
|
end
|
1065
1154
|
add_typing(node, type: AST::Builtin.bottom_type)
|
1066
1155
|
|
@@ -1073,10 +1162,6 @@ module Steep
|
|
1073
1162
|
add_typing(node, type: type)
|
1074
1163
|
else
|
1075
1164
|
type = AST::Builtin.any_type
|
1076
|
-
if context&.method_context&.method_type
|
1077
|
-
Steep.logger.error { "Unknown arg type: #{node}" }
|
1078
|
-
end
|
1079
|
-
|
1080
1165
|
lvasgn(node, type)
|
1081
1166
|
end
|
1082
1167
|
end
|
@@ -1094,10 +1179,12 @@ module Steep
|
|
1094
1179
|
constr_ = constr.update_lvar_env do |env|
|
1095
1180
|
env.assign(var.name, node: node, type: type) do |declared_type, type, result|
|
1096
1181
|
typing.add_error(
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1182
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
1183
|
+
node: node,
|
1184
|
+
lhs_type: declared_type,
|
1185
|
+
rhs_type: type,
|
1186
|
+
result: result
|
1187
|
+
)
|
1101
1188
|
)
|
1102
1189
|
end
|
1103
1190
|
end
|
@@ -1113,7 +1200,7 @@ module Steep
|
|
1113
1200
|
if context&.method_context&.method_type
|
1114
1201
|
Steep.logger.error { "Unknown variable: #{node}" }
|
1115
1202
|
end
|
1116
|
-
typing.add_error
|
1203
|
+
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
1117
1204
|
type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1118
1205
|
end
|
1119
1206
|
|
@@ -1128,7 +1215,7 @@ module Steep
|
|
1128
1215
|
if context&.method_context&.method_type
|
1129
1216
|
Steep.logger.error { "Unknown variable: #{node}" }
|
1130
1217
|
end
|
1131
|
-
typing.add_error
|
1218
|
+
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
1132
1219
|
type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
|
1133
1220
|
end
|
1134
1221
|
|
@@ -1211,7 +1298,7 @@ module Steep
|
|
1211
1298
|
key_types << splat_type.args[0]
|
1212
1299
|
value_types << splat_type.args[1]
|
1213
1300
|
else
|
1214
|
-
typing.add_error
|
1301
|
+
typing.add_error Diagnostic::Ruby::UnexpectedSplat.new(node: child, type: original_type)
|
1215
1302
|
key_types << AST::Builtin.any_type
|
1216
1303
|
value_types << AST::Builtin.any_type
|
1217
1304
|
end
|
@@ -1225,7 +1312,7 @@ module Steep
|
|
1225
1312
|
value_type = value_types.empty? ? AST::Builtin.any_type : AST::Types::Union.build(types: value_types)
|
1226
1313
|
|
1227
1314
|
if key_types.empty? && value_types.empty? && !hint
|
1228
|
-
typing.add_error
|
1315
|
+
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
1229
1316
|
end
|
1230
1317
|
|
1231
1318
|
add_typing(node, type: AST::Builtin::Hash.instance_type(key_type, value_type))
|
@@ -1250,13 +1337,32 @@ module Steep
|
|
1250
1337
|
constr = self
|
1251
1338
|
|
1252
1339
|
name, sup, _ = node.children
|
1253
|
-
|
1340
|
+
if name.type == :const
|
1341
|
+
# skip the last constant reference
|
1342
|
+
if const_parent = name.children[0]
|
1343
|
+
_, constr = constr.synthesize(const_parent)
|
1344
|
+
end
|
1345
|
+
else
|
1346
|
+
_, constr = constr.synthesize(name)
|
1347
|
+
end
|
1254
1348
|
_, constr = constr.synthesize(sup) if sup
|
1255
1349
|
|
1256
1350
|
constr.for_class(node).tap do |constructor|
|
1351
|
+
if module_type = constructor.module_context&.module_type
|
1352
|
+
_, constructor = constructor.add_typing(name, type: module_type)
|
1353
|
+
else
|
1354
|
+
_, constructor = constructor.fallback_to_any(name)
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
constructor.typing.source_index.add_definition(
|
1358
|
+
constant: constructor.module_context.class_name,
|
1359
|
+
definition: node
|
1360
|
+
)
|
1361
|
+
|
1257
1362
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1258
1363
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1259
1364
|
|
1365
|
+
constructor.synthesize(node.children[1]) if node.children[1]
|
1260
1366
|
constructor.synthesize(node.children[2]) if node.children[2]
|
1261
1367
|
|
1262
1368
|
if constructor.module_context&.implement_name && !namespace_module?(node)
|
@@ -1275,6 +1381,11 @@ module Steep
|
|
1275
1381
|
_, constr = constr.synthesize(name)
|
1276
1382
|
|
1277
1383
|
for_module(node).yield_self do |constructor|
|
1384
|
+
constructor.typing.source_index.add_definition(
|
1385
|
+
constant: constructor.module_context.class_name,
|
1386
|
+
definition: node
|
1387
|
+
)
|
1388
|
+
|
1278
1389
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1279
1390
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1280
1391
|
|
@@ -1295,7 +1406,7 @@ module Steep
|
|
1295
1406
|
|
1296
1407
|
unless constructor
|
1297
1408
|
typing.add_error(
|
1298
|
-
|
1409
|
+
Diagnostic::Ruby::UnsupportedSyntax.new(
|
1299
1410
|
node: node,
|
1300
1411
|
message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
|
1301
1412
|
)
|
@@ -1335,6 +1446,10 @@ module Steep
|
|
1335
1446
|
const_name = constr.module_name_from_node(node)
|
1336
1447
|
|
1337
1448
|
if const_name
|
1449
|
+
if constant = module_context.const_env.lookup_constant(const_name)
|
1450
|
+
typing.source_index.add_reference(constant: constant.name, ref: node)
|
1451
|
+
end
|
1452
|
+
|
1338
1453
|
type = type_env.get(const: const_name) do
|
1339
1454
|
constr.fallback_to_any(node)
|
1340
1455
|
end
|
@@ -1352,18 +1467,38 @@ module Steep
|
|
1352
1467
|
const_name = constr.module_name_from_node(node)
|
1353
1468
|
|
1354
1469
|
if const_name
|
1470
|
+
if constant = module_context.const_env.lookup_constant(const_name)
|
1471
|
+
typing.source_index.add_definition(constant: constant.name, definition: node)
|
1472
|
+
end
|
1473
|
+
|
1355
1474
|
const_type = type_env.get(const: const_name) {}
|
1356
1475
|
value_type, constr = constr.synthesize(node.children.last, hint: const_type)
|
1357
|
-
type = type_env.assign(
|
1476
|
+
type = type_env.assign(
|
1477
|
+
const: const_name,
|
1478
|
+
type: value_type,
|
1479
|
+
self_type: self_type,
|
1480
|
+
instance_type: module_context.instance_type,
|
1481
|
+
class_type: module_context.module_type
|
1482
|
+
) do |error|
|
1358
1483
|
case error
|
1359
1484
|
when Subtyping::Result::Failure
|
1360
1485
|
const_type = type_env.get(const: const_name)
|
1361
|
-
typing.add_error(
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1486
|
+
typing.add_error(
|
1487
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
1488
|
+
node: node,
|
1489
|
+
lhs_type: const_type,
|
1490
|
+
rhs_type: value_type,
|
1491
|
+
result: error
|
1492
|
+
)
|
1493
|
+
)
|
1365
1494
|
when nil
|
1366
|
-
typing.add_error(
|
1495
|
+
typing.add_error(
|
1496
|
+
Diagnostic::Ruby::UnknownConstantAssigned.new(
|
1497
|
+
node: node,
|
1498
|
+
name: const_name,
|
1499
|
+
context: module_context
|
1500
|
+
)
|
1501
|
+
)
|
1367
1502
|
end
|
1368
1503
|
end
|
1369
1504
|
|
@@ -1381,17 +1516,21 @@ module Steep
|
|
1381
1516
|
block_type.type.params.flat_unnamed_params.map(&:last).zip(node.children).each do |(type, node)|
|
1382
1517
|
if node && type
|
1383
1518
|
check(node, type) do |_, rhs_type, result|
|
1384
|
-
typing.add_error(
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1519
|
+
typing.add_error(
|
1520
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
1521
|
+
node: node,
|
1522
|
+
lhs_type: type,
|
1523
|
+
rhs_type: rhs_type,
|
1524
|
+
result: result
|
1525
|
+
)
|
1526
|
+
)
|
1388
1527
|
end
|
1389
1528
|
end
|
1390
1529
|
end
|
1391
1530
|
|
1392
1531
|
add_typing(node, type: block_type.type.return_type)
|
1393
1532
|
else
|
1394
|
-
typing.add_error(
|
1533
|
+
typing.add_error(Diagnostic::Ruby::UnexpectedYield.new(node: node))
|
1395
1534
|
fallback_to_any node
|
1396
1535
|
end
|
1397
1536
|
else
|
@@ -1407,7 +1546,7 @@ module Steep
|
|
1407
1546
|
}
|
1408
1547
|
add_typing(node, type: union_type(*types))
|
1409
1548
|
else
|
1410
|
-
typing.add_error(
|
1549
|
+
typing.add_error(Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context.name))
|
1411
1550
|
fallback_to_any node
|
1412
1551
|
end
|
1413
1552
|
else
|
@@ -1426,7 +1565,7 @@ module Steep
|
|
1426
1565
|
add_typing node, type: array
|
1427
1566
|
end
|
1428
1567
|
else
|
1429
|
-
typing.add_error
|
1568
|
+
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
1430
1569
|
add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1431
1570
|
end
|
1432
1571
|
else
|
@@ -1464,18 +1603,22 @@ module Steep
|
|
1464
1603
|
yield_self do
|
1465
1604
|
left, right = node.children
|
1466
1605
|
|
1467
|
-
left_type, constr = synthesize(left)
|
1606
|
+
left_type, constr = synthesize(left, hint: hint, condition: true)
|
1468
1607
|
|
1469
1608
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1470
1609
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1471
1610
|
|
1611
|
+
if left_type.is_a?(AST::Types::Logic::Env)
|
1612
|
+
left_type = left_type.type
|
1613
|
+
end
|
1614
|
+
|
1472
1615
|
right_type, constr = constr
|
1473
1616
|
.update_lvar_env { truthy_env }
|
1474
1617
|
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1475
1618
|
.for_branch(right)
|
1476
|
-
.synthesize(right)
|
1619
|
+
.synthesize(right, hint: hint, condition: true)
|
1477
1620
|
|
1478
|
-
truthy_env, _ = interpreter.eval(env:
|
1621
|
+
truthy_env, _ = interpreter.eval(env: constr.context.lvar_env, type: right_type, node: right)
|
1479
1622
|
|
1480
1623
|
env = if right_type.is_a?(AST::Types::Bot)
|
1481
1624
|
falsey_env
|
@@ -1484,14 +1627,14 @@ module Steep
|
|
1484
1627
|
end
|
1485
1628
|
|
1486
1629
|
type = case
|
1487
|
-
when left_type.is_a?(AST::Types::Logic::Base) && right_type.is_a?(AST::Types::Logic::Base)
|
1488
|
-
AST::Types::Logic::Env.new(truthy: truthy_env, falsy: env)
|
1489
1630
|
when check_relation(sub_type: left_type, super_type: AST::Types::Boolean.new).success?
|
1490
1631
|
union_type(left_type, right_type)
|
1491
1632
|
else
|
1492
1633
|
union_type(right_type, AST::Builtin.nil_type)
|
1493
1634
|
end
|
1494
1635
|
|
1636
|
+
type = AST::Types::Logic::Env.new(truthy: truthy_env, falsy: env, type: type) if condition
|
1637
|
+
|
1495
1638
|
add_typing(node,
|
1496
1639
|
type: type,
|
1497
1640
|
constr: constr.update_lvar_env { env })
|
@@ -1501,17 +1644,21 @@ module Steep
|
|
1501
1644
|
yield_self do
|
1502
1645
|
left, right = node.children
|
1503
1646
|
|
1504
|
-
left_type, constr = synthesize(left, hint: hint)
|
1647
|
+
left_type, constr = synthesize(left, hint: hint, condition: true)
|
1505
1648
|
|
1506
1649
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1507
1650
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1508
1651
|
|
1652
|
+
if left_type.is_a?(AST::Types::Logic::Env)
|
1653
|
+
left_type = left_type.type
|
1654
|
+
end
|
1509
1655
|
left_type, _ = checker.factory.unwrap_optional(left_type)
|
1656
|
+
|
1510
1657
|
right_type, constr = constr
|
1511
1658
|
.update_lvar_env { falsey_env }
|
1512
1659
|
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1513
1660
|
.for_branch(right)
|
1514
|
-
.synthesize(right, hint: left_type)
|
1661
|
+
.synthesize(right, hint: left_type, condition: true)
|
1515
1662
|
|
1516
1663
|
_, falsey_env = interpreter.eval(env: falsey_env, type: right_type, node: right)
|
1517
1664
|
|
@@ -1522,12 +1669,14 @@ module Steep
|
|
1522
1669
|
end
|
1523
1670
|
|
1524
1671
|
type = case
|
1525
|
-
when left_type
|
1526
|
-
AST::
|
1672
|
+
when check_relation(sub_type: left_type, super_type: AST::Builtin.bool_type).success? && !left_type.is_a?(AST::Types::Any)
|
1673
|
+
AST::Builtin.bool_type
|
1527
1674
|
else
|
1528
1675
|
union_type(left_type, right_type)
|
1529
1676
|
end
|
1530
1677
|
|
1678
|
+
type = AST::Types::Logic::Env.new(truthy: env, falsy: falsey_env, type: type) if condition
|
1679
|
+
|
1531
1680
|
add_typing(node,
|
1532
1681
|
type: type,
|
1533
1682
|
constr: constr.update_lvar_env { env })
|
@@ -1536,7 +1685,7 @@ module Steep
|
|
1536
1685
|
when :if
|
1537
1686
|
cond, true_clause, false_clause = node.children
|
1538
1687
|
|
1539
|
-
cond_type, constr = synthesize(cond)
|
1688
|
+
cond_type, constr = synthesize(cond, condition: true)
|
1540
1689
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
|
1541
1690
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: cond_type, node: cond)
|
1542
1691
|
|
@@ -1617,7 +1766,7 @@ module Steep
|
|
1617
1766
|
|
1618
1767
|
tests.each do |test|
|
1619
1768
|
test_node = test.updated(:send, [test, :===, var_node])
|
1620
|
-
test_type, test_constr = test_constr.synthesize(test_node)
|
1769
|
+
test_type, test_constr = test_constr.synthesize(test_node, condition: true)
|
1621
1770
|
truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
|
1622
1771
|
truthy_env = cond_vars.inject(truthy_env) do |env, var|
|
1623
1772
|
env.assign!(var, node: test_node, type: env[first_var])
|
@@ -1625,6 +1774,7 @@ module Steep
|
|
1625
1774
|
falsy_env = cond_vars.inject(falsy_env) do |env, var|
|
1626
1775
|
env.assign!(var, node: test_node, type: env[first_var])
|
1627
1776
|
end
|
1777
|
+
|
1628
1778
|
test_envs << truthy_env
|
1629
1779
|
test_constr = test_constr.update_lvar_env { falsy_env }
|
1630
1780
|
end
|
@@ -1657,7 +1807,7 @@ module Steep
|
|
1657
1807
|
if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
|
1658
1808
|
# Exhaustive
|
1659
1809
|
if els
|
1660
|
-
typing.add_error
|
1810
|
+
typing.add_error Diagnostic::Ruby::ElseOnExhaustiveCase.new(node: els, type: cond_type)
|
1661
1811
|
end
|
1662
1812
|
else
|
1663
1813
|
unless els
|
@@ -1669,21 +1819,20 @@ module Steep
|
|
1669
1819
|
branch_pairs = []
|
1670
1820
|
|
1671
1821
|
when_constr = constr
|
1822
|
+
clause_constr = constr
|
1672
1823
|
|
1673
1824
|
whens.each do |clause|
|
1674
1825
|
*tests, body = clause.children
|
1675
1826
|
|
1676
1827
|
test_constr = when_constr
|
1677
|
-
test_envs = []
|
1678
1828
|
|
1679
1829
|
tests.each do |test|
|
1680
|
-
test_type, test_constr = test_constr.synthesize(test)
|
1830
|
+
test_type, test_constr = test_constr.synthesize(test, condition: true)
|
1681
1831
|
truthy_env, falsy_env = interpreter.eval(env: test_constr.context.lvar_env, type: test_type, node: test)
|
1682
|
-
|
1832
|
+
clause_constr = clause_constr.update_lvar_env { truthy_env }
|
1683
1833
|
test_constr = test_constr.update_lvar_env { falsy_env }
|
1684
1834
|
end
|
1685
1835
|
|
1686
|
-
clause_constr = when_constr.update_lvar_env {|env| env.join(*test_envs) }
|
1687
1836
|
when_constr = test_constr
|
1688
1837
|
|
1689
1838
|
if body
|
@@ -1822,7 +1971,7 @@ module Steep
|
|
1822
1971
|
when AST::Types::Any
|
1823
1972
|
AST::Types::Any.new
|
1824
1973
|
else
|
1825
|
-
each =
|
1974
|
+
each = calculate_interface(collection_type, private: true).methods[:each]
|
1826
1975
|
method_type = (each&.method_types || []).find {|type| type.block && type.block.type.params.first_param }
|
1827
1976
|
method_type&.yield_self do |method_type|
|
1828
1977
|
method_type.block.type.params.first_param&.type
|
@@ -1846,7 +1995,7 @@ module Steep
|
|
1846
1995
|
add_typing(node, type: collection_type, constr: constr)
|
1847
1996
|
else
|
1848
1997
|
fallback_to_any(node) do
|
1849
|
-
|
1998
|
+
Diagnostic::Ruby::NoMethod.new(
|
1850
1999
|
node: node,
|
1851
2000
|
method: :each,
|
1852
2001
|
type: collection_type
|
@@ -1857,7 +2006,7 @@ module Steep
|
|
1857
2006
|
when :while, :until
|
1858
2007
|
yield_self do
|
1859
2008
|
cond, body = node.children
|
1860
|
-
cond_type, constr = synthesize(cond)
|
2009
|
+
cond_type, constr = synthesize(cond, condition: true)
|
1861
2010
|
|
1862
2011
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1863
2012
|
truthy_env, falsy_env = interpreter.eval(env: constr.context.lvar_env, node: cond, type: cond_type)
|
@@ -1995,11 +2144,13 @@ module Steep
|
|
1995
2144
|
end
|
1996
2145
|
|
1997
2146
|
check(rhs, type) do |_, rhs_type, result|
|
1998
|
-
typing.add_error(
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2147
|
+
typing.add_error(
|
2148
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2149
|
+
node: node,
|
2150
|
+
lhs_type: type,
|
2151
|
+
rhs_type: rhs_type,
|
2152
|
+
result: result
|
2153
|
+
)
|
2003
2154
|
)
|
2004
2155
|
end
|
2005
2156
|
end
|
@@ -2008,7 +2159,7 @@ module Steep
|
|
2008
2159
|
yield_self do
|
2009
2160
|
name = node.children.first
|
2010
2161
|
type = type_env.get(gvar: name) do
|
2011
|
-
typing.add_error
|
2162
|
+
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
2012
2163
|
end
|
2013
2164
|
|
2014
2165
|
add_typing(node, type: type)
|
@@ -2022,24 +2173,29 @@ module Steep
|
|
2022
2173
|
if hint.one_arg?
|
2023
2174
|
# Assumes Symbol#to_proc implementation
|
2024
2175
|
param_type = hint.type.params.required[0]
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2176
|
+
case param_type
|
2177
|
+
when AST::Types::Any
|
2178
|
+
type = AST::Types::Any.new
|
2179
|
+
else
|
2180
|
+
interface = calculate_interface(param_type, private: true)
|
2181
|
+
method = interface.methods[value.children[0]]
|
2182
|
+
if method
|
2183
|
+
return_types = method.method_types.select {|method_type|
|
2184
|
+
method_type.type.params.empty?
|
2185
|
+
}.map {|method_type|
|
2186
|
+
method_type.type.return_type
|
2187
|
+
}
|
2188
|
+
|
2189
|
+
unless return_types.empty?
|
2190
|
+
type = AST::Types::Proc.new(
|
2191
|
+
type: Interface::Function.new(
|
2192
|
+
params: Interface::Function::Params.empty.update(required: [param_type]),
|
2193
|
+
return_type: AST::Types::Union.build(types: return_types),
|
2194
|
+
location: nil
|
2195
|
+
),
|
2196
|
+
block: nil
|
2197
|
+
)
|
2198
|
+
end
|
2043
2199
|
end
|
2044
2200
|
end
|
2045
2201
|
else
|
@@ -2077,10 +2233,12 @@ module Steep
|
|
2077
2233
|
add_typing node, type: type, constr: constr
|
2078
2234
|
else
|
2079
2235
|
fallback_to_any node do
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2236
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2237
|
+
node: node,
|
2238
|
+
lhs_type: var_type,
|
2239
|
+
rhs_type: type,
|
2240
|
+
result: result
|
2241
|
+
)
|
2084
2242
|
end
|
2085
2243
|
end
|
2086
2244
|
else
|
@@ -2104,7 +2262,12 @@ module Steep
|
|
2104
2262
|
|
2105
2263
|
when :splat
|
2106
2264
|
yield_self do
|
2107
|
-
|
2265
|
+
typing.add_error(
|
2266
|
+
Diagnostic::Ruby::UnsupportedSyntax.new(
|
2267
|
+
node: node,
|
2268
|
+
message: "Unsupported splat node occurrence"
|
2269
|
+
)
|
2270
|
+
)
|
2108
2271
|
|
2109
2272
|
each_child_node node do |child|
|
2110
2273
|
synthesize(child)
|
@@ -2123,7 +2286,7 @@ module Steep
|
|
2123
2286
|
add_typing node, type: AST::Builtin.any_type, constr: constr
|
2124
2287
|
|
2125
2288
|
else
|
2126
|
-
|
2289
|
+
typing.add_error(Diagnostic::Ruby::UnsupportedSyntax.new(node: node))
|
2127
2290
|
|
2128
2291
|
end.tap do |pair|
|
2129
2292
|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
@@ -2132,6 +2295,10 @@ module Steep
|
|
2132
2295
|
raise "#synthesize should return an instance of Pair: #{pair.class}, node=#{node.inspect}"
|
2133
2296
|
end
|
2134
2297
|
end
|
2298
|
+
rescue StandardError => exn
|
2299
|
+
Steep.log_error exn
|
2300
|
+
typing.add_error(Diagnostic::Ruby::UnexpectedError.new(node: node, error: exn))
|
2301
|
+
type_any_rec(node)
|
2135
2302
|
end
|
2136
2303
|
end
|
2137
2304
|
|
@@ -2149,14 +2316,24 @@ module Steep
|
|
2149
2316
|
|
2150
2317
|
def type_ivasgn(name, rhs, node)
|
2151
2318
|
rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) }).type
|
2152
|
-
ivar_type = type_env.assign(
|
2319
|
+
ivar_type = type_env.assign(
|
2320
|
+
ivar: name,
|
2321
|
+
type: rhs_type,
|
2322
|
+
self_type: self_type,
|
2323
|
+
instance_type: module_context.instance_type,
|
2324
|
+
class_type: module_context.module_type
|
2325
|
+
) do |error|
|
2153
2326
|
case error
|
2154
2327
|
when Subtyping::Result::Failure
|
2155
2328
|
type = type_env.get(ivar: name)
|
2156
|
-
typing.add_error(
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2329
|
+
typing.add_error(
|
2330
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2331
|
+
node: node,
|
2332
|
+
lhs_type: type,
|
2333
|
+
rhs_type: rhs_type,
|
2334
|
+
result: error
|
2335
|
+
)
|
2336
|
+
)
|
2160
2337
|
when nil
|
2161
2338
|
fallback_to_any node
|
2162
2339
|
end
|
@@ -2179,10 +2356,12 @@ module Steep
|
|
2179
2356
|
name = node.children[0].name
|
2180
2357
|
env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
|
2181
2358
|
typing.add_error(
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2359
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2360
|
+
node: node,
|
2361
|
+
lhs_type: declared_type,
|
2362
|
+
rhs_type: type,
|
2363
|
+
result: result
|
2364
|
+
)
|
2186
2365
|
)
|
2187
2366
|
end
|
2188
2367
|
|
@@ -2192,14 +2371,24 @@ module Steep
|
|
2192
2371
|
def ivasgn(node, type)
|
2193
2372
|
ivar = node.children[0]
|
2194
2373
|
|
2195
|
-
type_env.assign(
|
2374
|
+
type_env.assign(
|
2375
|
+
ivar: ivar,
|
2376
|
+
type: type,
|
2377
|
+
self_type: self_type,
|
2378
|
+
instance_type: module_context.instance_type,
|
2379
|
+
class_type: module_context.module_type
|
2380
|
+
) do |error|
|
2196
2381
|
case error
|
2197
2382
|
when Subtyping::Result::Failure
|
2198
2383
|
var_type = type_env.get(ivar: ivar)
|
2199
|
-
typing.add_error(
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2384
|
+
typing.add_error(
|
2385
|
+
Diagnostic::Ruby::IncompatibleAssignment.new(
|
2386
|
+
node: node,
|
2387
|
+
lhs_type: var_type,
|
2388
|
+
rhs_type: type,
|
2389
|
+
result: error
|
2390
|
+
)
|
2391
|
+
)
|
2203
2392
|
when nil
|
2204
2393
|
fallback_to_any node
|
2205
2394
|
end
|
@@ -2376,6 +2565,7 @@ module Steep
|
|
2376
2565
|
block_constr = for_block(
|
2377
2566
|
block_params: params,
|
2378
2567
|
block_param_hint: params_hint,
|
2568
|
+
block_type_hint: return_hint,
|
2379
2569
|
block_annotations: block_annotations,
|
2380
2570
|
node_type_hint: nil
|
2381
2571
|
)
|
@@ -2390,10 +2580,22 @@ module Steep
|
|
2390
2580
|
return_type = block_constr.synthesize_block(
|
2391
2581
|
node: node,
|
2392
2582
|
block_body: block_body,
|
2393
|
-
topdown_hint: true,
|
2394
2583
|
block_type_hint: return_hint
|
2395
|
-
)
|
2396
|
-
|
2584
|
+
)
|
2585
|
+
|
2586
|
+
if expected_block_type = block_constr.block_context.body_type
|
2587
|
+
check_relation(sub_type: return_type, super_type: expected_block_type).else do |result|
|
2588
|
+
block_constr.typing.add_error(
|
2589
|
+
Diagnostic::Ruby::BlockBodyTypeMismatch.new(
|
2590
|
+
node: node,
|
2591
|
+
expected: expected_block_type,
|
2592
|
+
actual: return_type,
|
2593
|
+
result: result
|
2594
|
+
)
|
2595
|
+
)
|
2596
|
+
|
2597
|
+
return_type = expected_block_type
|
2598
|
+
end
|
2397
2599
|
end
|
2398
2600
|
else
|
2399
2601
|
return_type = AST::Builtin.any_type
|
@@ -2447,7 +2649,7 @@ module Steep
|
|
2447
2649
|
end
|
2448
2650
|
end
|
2449
2651
|
else
|
2450
|
-
error =
|
2652
|
+
error = Diagnostic::Ruby::UnresolvedOverloading.new(
|
2451
2653
|
node: node,
|
2452
2654
|
receiver_type: receiver_type,
|
2453
2655
|
method_name: method_name,
|
@@ -2473,21 +2675,37 @@ module Steep
|
|
2473
2675
|
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2474
2676
|
block_annotations: block_annotations,
|
2475
2677
|
block_body: block_body
|
2476
|
-
)
|
2477
|
-
constr.typing.add_error(error)
|
2478
|
-
end
|
2678
|
+
)
|
2479
2679
|
end
|
2480
2680
|
end
|
2481
2681
|
|
2482
2682
|
constr.add_call(call)
|
2483
2683
|
else
|
2484
|
-
|
2684
|
+
skips = []
|
2685
|
+
skips << receiver if receiver
|
2686
|
+
skips << node.children[0] if node.type == :block
|
2687
|
+
skips << block_params if block_params
|
2688
|
+
skips << block_body if block_body
|
2689
|
+
|
2690
|
+
constr = synthesize_children(node, skips: skips)
|
2691
|
+
if block_params
|
2692
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2693
|
+
|
2694
|
+
constr.type_block_without_hint(
|
2695
|
+
node: node,
|
2696
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2697
|
+
block_annotations: block_annotations,
|
2698
|
+
block_body: block_body
|
2699
|
+
)
|
2700
|
+
end
|
2701
|
+
|
2702
|
+
constr.add_call(
|
2485
2703
|
TypeInference::MethodCall::NoMethodError.new(
|
2486
2704
|
node: node,
|
2487
2705
|
context: context.method_context,
|
2488
2706
|
method_name: method_name,
|
2489
2707
|
receiver_type: receiver_type,
|
2490
|
-
error:
|
2708
|
+
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2491
2709
|
)
|
2492
2710
|
)
|
2493
2711
|
end
|
@@ -2525,7 +2743,7 @@ module Steep
|
|
2525
2743
|
context: context.method_context,
|
2526
2744
|
method_name: method_name,
|
2527
2745
|
receiver_type: receiver_type,
|
2528
|
-
error:
|
2746
|
+
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2529
2747
|
)
|
2530
2748
|
)
|
2531
2749
|
|
@@ -2542,13 +2760,13 @@ module Steep
|
|
2542
2760
|
context: context.method_context,
|
2543
2761
|
method_name: method_name,
|
2544
2762
|
receiver_type: receiver_type,
|
2545
|
-
error:
|
2763
|
+
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2546
2764
|
)
|
2547
2765
|
)
|
2548
2766
|
else
|
2549
|
-
interface =
|
2550
|
-
|
2551
|
-
|
2767
|
+
interface = calculate_interface(expanded_self,
|
2768
|
+
private: !receiver,
|
2769
|
+
self_type: AST::Types::Self.new)
|
2552
2770
|
|
2553
2771
|
constr.type_send_interface(node,
|
2554
2772
|
interface: interface,
|
@@ -2560,9 +2778,7 @@ module Steep
|
|
2560
2778
|
block_body: block_body)
|
2561
2779
|
end
|
2562
2780
|
else
|
2563
|
-
interface =
|
2564
|
-
private: !receiver,
|
2565
|
-
self_type: receiver_type)
|
2781
|
+
interface = calculate_interface(receiver_type, private: !receiver, self_type: receiver_type)
|
2566
2782
|
|
2567
2783
|
constr.type_send_interface(node,
|
2568
2784
|
interface: interface,
|
@@ -2575,27 +2791,19 @@ module Steep
|
|
2575
2791
|
end
|
2576
2792
|
|
2577
2793
|
Pair.new(type: type, constr: constr)
|
2578
|
-
|
2579
|
-
case exn
|
2580
|
-
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2581
|
-
# ignore known RBS errors.
|
2582
|
-
else
|
2583
|
-
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2584
|
-
end
|
2585
|
-
|
2586
|
-
error = Errors::UnexpectedError.new(node: node, error: exn)
|
2794
|
+
end
|
2587
2795
|
|
2588
|
-
|
2796
|
+
def calculate_interface(type, private:, self_type: type)
|
2797
|
+
case type
|
2798
|
+
when AST::Types::Self
|
2799
|
+
type = self_type
|
2800
|
+
when AST::Types::Instance
|
2801
|
+
type = module_context.instance_type
|
2802
|
+
when AST::Types::Class
|
2803
|
+
type = module_context.module_type
|
2804
|
+
end
|
2589
2805
|
|
2590
|
-
|
2591
|
-
TypeInference::MethodCall::Error.new(
|
2592
|
-
node: node,
|
2593
|
-
context: context.method_context,
|
2594
|
-
method_name: method_name,
|
2595
|
-
receiver_type: receiver_type,
|
2596
|
-
errors: [error]
|
2597
|
-
)
|
2598
|
-
)
|
2806
|
+
checker.factory.interface(type, private: private, self_type: self_type)
|
2599
2807
|
end
|
2600
2808
|
|
2601
2809
|
def expand_self(type)
|
@@ -2637,7 +2845,8 @@ module Steep
|
|
2637
2845
|
all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
|
2638
2846
|
set.merge(method_type.method_decls)
|
2639
2847
|
end
|
2640
|
-
|
2848
|
+
|
2849
|
+
error = Diagnostic::Ruby::IncompatibleArguments.new(node: node, method_name: method_name, receiver_type: receiver_type, method_types: method.method_types)
|
2641
2850
|
call = TypeInference::MethodCall::Error.new(
|
2642
2851
|
node: node,
|
2643
2852
|
context: context.method_context,
|
@@ -2702,7 +2911,7 @@ module Steep
|
|
2702
2911
|
|
2703
2912
|
if keyword_type
|
2704
2913
|
check(value_node, keyword_type, constraints: constraints) do |expected, actual, result|
|
2705
|
-
return
|
2914
|
+
return Diagnostic::Ruby::IncompatibleAssignment.new(
|
2706
2915
|
node: value_node,
|
2707
2916
|
lhs_type: expected,
|
2708
2917
|
rhs_type: actual,
|
@@ -2715,7 +2924,7 @@ module Steep
|
|
2715
2924
|
|
2716
2925
|
else
|
2717
2926
|
check(key_node, AST::Builtin::Symbol.instance_type, constraints: constraints) do |expected, actual, result|
|
2718
|
-
return
|
2927
|
+
return Diagnostic::Ruby::IncompatibleAssignment.new(
|
2719
2928
|
node: key_node,
|
2720
2929
|
lhs_type: expected,
|
2721
2930
|
rhs_type: actual,
|
@@ -2728,7 +2937,7 @@ module Steep
|
|
2728
2937
|
Steep.logger.warn("Keyword arg with kwsplat(**) node are not supported.")
|
2729
2938
|
|
2730
2939
|
check(element.children[0], keyword_hash_type, constraints: constraints) do |expected, actual, result|
|
2731
|
-
return
|
2940
|
+
return Diagnostic::Ruby::IncompatibleAssignment.new(
|
2732
2941
|
node: node,
|
2733
2942
|
lhs_type: expected,
|
2734
2943
|
rhs_type: actual,
|
@@ -2744,14 +2953,18 @@ module Steep
|
|
2744
2953
|
when Set
|
2745
2954
|
missing_keywords = Set.new(params.required_keywords.keys) - given_keys
|
2746
2955
|
unless missing_keywords.empty?
|
2747
|
-
return
|
2748
|
-
|
2956
|
+
return Diagnostic::Ruby::MissingKeyword.new(
|
2957
|
+
node: node,
|
2958
|
+
missing_keywords: missing_keywords
|
2959
|
+
)
|
2749
2960
|
end
|
2750
2961
|
|
2751
2962
|
extra_keywords = given_keys - Set.new(params.required_keywords.keys) - Set.new(params.optional_keywords.keys)
|
2752
2963
|
if extra_keywords.any? && !params.rest_keywords
|
2753
|
-
return
|
2754
|
-
|
2964
|
+
return Diagnostic::Ruby::UnexpectedKeyword.new(
|
2965
|
+
node: node,
|
2966
|
+
unexpected_keywords: extra_keywords
|
2967
|
+
)
|
2755
2968
|
end
|
2756
2969
|
end
|
2757
2970
|
else
|
@@ -2778,12 +2991,13 @@ module Steep
|
|
2778
2991
|
|
2779
2992
|
node_type = synthesize(node, hint: hash_type).type
|
2780
2993
|
|
2781
|
-
check_relation(sub_type: node_type, super_type: hash_type).else do
|
2782
|
-
return
|
2994
|
+
check_relation(sub_type: node_type, super_type: hash_type).else do |result|
|
2995
|
+
return Diagnostic::Ruby::ArgumentTypeMismatch.new(
|
2783
2996
|
node: node,
|
2784
2997
|
receiver_type: receiver_type,
|
2785
2998
|
expected: hash_type,
|
2786
|
-
actual: node_type
|
2999
|
+
actual: node_type,
|
3000
|
+
result: result
|
2787
3001
|
)
|
2788
3002
|
end
|
2789
3003
|
end
|
@@ -2818,11 +3032,12 @@ module Steep
|
|
2818
3032
|
constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
|
2819
3033
|
end
|
2820
3034
|
|
2821
|
-
check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do
|
2822
|
-
errors <<
|
2823
|
-
|
2824
|
-
|
2825
|
-
|
3035
|
+
check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do |result|
|
3036
|
+
errors << Diagnostic::Ruby::ArgumentTypeMismatch.new(node: arg_node,
|
3037
|
+
receiver_type: receiver_type,
|
3038
|
+
expected: param_type,
|
3039
|
+
actual: arg_type,
|
3040
|
+
result: result)
|
2826
3041
|
end
|
2827
3042
|
else
|
2828
3043
|
# keyword
|
@@ -2831,7 +3046,7 @@ module Steep
|
|
2831
3046
|
method_type: method_type,
|
2832
3047
|
constraints: constraints)
|
2833
3048
|
|
2834
|
-
if result.is_a?(
|
3049
|
+
if result.is_a?(Diagnostic::Ruby::Base)
|
2835
3050
|
errors << result
|
2836
3051
|
end
|
2837
3052
|
end
|
@@ -2850,6 +3065,7 @@ module Steep
|
|
2850
3065
|
block_constr = constr.for_block(
|
2851
3066
|
block_params: block_params_,
|
2852
3067
|
block_param_hint: method_type.block.type.params,
|
3068
|
+
block_type_hint: method_type.block.type.return_type,
|
2853
3069
|
block_annotations: block_annotations,
|
2854
3070
|
node_type_hint: method_type.type.return_type
|
2855
3071
|
)
|
@@ -2866,7 +3082,7 @@ module Steep
|
|
2866
3082
|
|
2867
3083
|
if param.type
|
2868
3084
|
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
2869
|
-
error =
|
3085
|
+
error = Diagnostic::Ruby::IncompatibleAssignment.new(
|
2870
3086
|
node: param.node,
|
2871
3087
|
lhs_type: param.type,
|
2872
3088
|
rhs_type: type,
|
@@ -2880,6 +3096,8 @@ module Steep
|
|
2880
3096
|
s = constraints.solution(
|
2881
3097
|
checker,
|
2882
3098
|
self_type: self_type,
|
3099
|
+
instance_type: module_context.instance_type,
|
3100
|
+
class_type: module_context.module_type,
|
2883
3101
|
variance: variance,
|
2884
3102
|
variables: method_type.type.params.free_variables + method_type.block.type.params.free_variables
|
2885
3103
|
)
|
@@ -2888,12 +3106,9 @@ module Steep
|
|
2888
3106
|
if block_body
|
2889
3107
|
block_body_type = block_constr.synthesize_block(
|
2890
3108
|
node: node,
|
2891
|
-
block_type_hint: method_type.block.type.return_type,
|
2892
3109
|
block_body: block_body,
|
2893
|
-
|
2894
|
-
)
|
2895
|
-
errors << error
|
2896
|
-
end
|
3110
|
+
block_type_hint: method_type.block.type.return_type
|
3111
|
+
)
|
2897
3112
|
else
|
2898
3113
|
block_body_type = AST::Builtin.nil_type
|
2899
3114
|
end
|
@@ -2904,7 +3119,14 @@ module Steep
|
|
2904
3119
|
|
2905
3120
|
case result
|
2906
3121
|
when Subtyping::Result::Success
|
2907
|
-
s = constraints.solution(
|
3122
|
+
s = constraints.solution(
|
3123
|
+
checker,
|
3124
|
+
self_type: self_type,
|
3125
|
+
instance_type: module_context.instance_type,
|
3126
|
+
class_type: module_context.module_type,
|
3127
|
+
variance: variance,
|
3128
|
+
variables: fresh_vars
|
3129
|
+
)
|
2908
3130
|
method_type = method_type.subst(s)
|
2909
3131
|
|
2910
3132
|
return_type = method_type.type.return_type
|
@@ -2913,35 +3135,20 @@ module Steep
|
|
2913
3135
|
end
|
2914
3136
|
|
2915
3137
|
when Subtyping::Result::Failure
|
2916
|
-
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
2920
|
-
|
2921
|
-
),
|
2922
|
-
block: nil
|
2923
|
-
)
|
2924
|
-
|
2925
|
-
method_block_type = AST::Types::Proc.new(
|
2926
|
-
type: Interface::Function.new(
|
2927
|
-
params: method_type.block.type.params,
|
2928
|
-
return_type: method_type.block.type.return_type,
|
2929
|
-
location: nil
|
2930
|
-
),
|
2931
|
-
block: nil
|
3138
|
+
errors << Diagnostic::Ruby::BlockBodyTypeMismatch.new(
|
3139
|
+
node: node,
|
3140
|
+
expected: method_type.block.type.return_type,
|
3141
|
+
actual: block_body_type,
|
3142
|
+
result: result
|
2932
3143
|
)
|
2933
3144
|
|
2934
|
-
errors << Errors::BlockTypeMismatch.new(node: node,
|
2935
|
-
expected: method_block_type,
|
2936
|
-
actual: given_block_type,
|
2937
|
-
result: result)
|
2938
|
-
|
2939
3145
|
return_type = method_type.type.return_type
|
2940
3146
|
end
|
2941
3147
|
|
2942
3148
|
block_constr.typing.save!
|
3149
|
+
|
2943
3150
|
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
2944
|
-
errors <<
|
3151
|
+
errors << Diagnostic::Ruby::UnsatisfiableConstraint.new(
|
2945
3152
|
node: node,
|
2946
3153
|
method_type: method_type,
|
2947
3154
|
var: exn.var,
|
@@ -2959,12 +3166,19 @@ module Steep
|
|
2959
3166
|
method_type = method_type.subst(s)
|
2960
3167
|
end
|
2961
3168
|
else
|
2962
|
-
errors <<
|
3169
|
+
errors << Diagnostic::Ruby::UnsupportedSyntax.new(
|
2963
3170
|
node: block_params,
|
2964
3171
|
message: "Unsupported block params pattern, probably masgn?"
|
2965
3172
|
)
|
2966
3173
|
|
2967
|
-
s = constraints.solution(
|
3174
|
+
s = constraints.solution(
|
3175
|
+
checker,
|
3176
|
+
variance: variance,
|
3177
|
+
variables: fresh_vars,
|
3178
|
+
self_type: self_type,
|
3179
|
+
instance_type: module_context.instance_type,
|
3180
|
+
class_type: module_context.module_type
|
3181
|
+
)
|
2968
3182
|
method_type = method_type.subst(s)
|
2969
3183
|
end
|
2970
3184
|
else
|
@@ -2974,7 +3188,7 @@ module Steep
|
|
2974
3188
|
errors << error
|
2975
3189
|
end
|
2976
3190
|
|
2977
|
-
errors <<
|
3191
|
+
errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
|
2978
3192
|
node: node,
|
2979
3193
|
method_type: method_type
|
2980
3194
|
)
|
@@ -2985,14 +3199,28 @@ module Steep
|
|
2985
3199
|
# Method call without block is allowed
|
2986
3200
|
unless args.block_pass_arg
|
2987
3201
|
# OK, without block
|
2988
|
-
s = constraints.solution(
|
3202
|
+
s = constraints.solution(
|
3203
|
+
checker,
|
3204
|
+
variance: variance,
|
3205
|
+
variables: fresh_vars,
|
3206
|
+
self_type: self_type,
|
3207
|
+
instance_type: module_context.instance_type,
|
3208
|
+
class_type: module_context.module_type
|
3209
|
+
)
|
2989
3210
|
method_type = method_type.subst(s)
|
2990
3211
|
else
|
2991
3212
|
# &block arg is given
|
2992
|
-
s = constraints.solution(
|
3213
|
+
s = constraints.solution(
|
3214
|
+
checker,
|
3215
|
+
variance: variance,
|
3216
|
+
variables: fresh_vars,
|
3217
|
+
self_type: self_type,
|
3218
|
+
instance_type: module_context.instance_type,
|
3219
|
+
class_type: module_context.module_type
|
3220
|
+
)
|
2993
3221
|
method_type = method_type.subst(s)
|
2994
3222
|
|
2995
|
-
errors <<
|
3223
|
+
errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
|
2996
3224
|
node: node,
|
2997
3225
|
method_type: method_type
|
2998
3226
|
)
|
@@ -3000,16 +3228,32 @@ module Steep
|
|
3000
3228
|
else
|
3001
3229
|
unless args.block_pass_arg
|
3002
3230
|
# Required block is missing
|
3003
|
-
errors <<
|
3231
|
+
errors << Diagnostic::Ruby::RequiredBlockMissing.new(
|
3004
3232
|
node: node,
|
3005
3233
|
method_type: method_type
|
3006
3234
|
)
|
3007
3235
|
|
3008
|
-
s = constraints.solution(
|
3236
|
+
s = constraints.solution(
|
3237
|
+
checker,
|
3238
|
+
variance: variance,
|
3239
|
+
variables: fresh_vars,
|
3240
|
+
self_type: self_type,
|
3241
|
+
instance_type: module_context.instance_type,
|
3242
|
+
class_type: module_context.module_type
|
3243
|
+
)
|
3009
3244
|
method_type = method_type.subst(s)
|
3010
3245
|
else
|
3011
3246
|
begin
|
3012
|
-
method_type = method_type.subst(
|
3247
|
+
method_type = method_type.subst(
|
3248
|
+
constraints.solution(
|
3249
|
+
checker,
|
3250
|
+
self_type: self_type,
|
3251
|
+
instance_type: module_context.instance_type,
|
3252
|
+
class_type: module_context.module_type,
|
3253
|
+
variance: variance,
|
3254
|
+
variables: occurence.params
|
3255
|
+
)
|
3256
|
+
)
|
3013
3257
|
hint_type = if topdown_hint
|
3014
3258
|
AST::Types::Proc.new(type: method_type.block.type, block: nil)
|
3015
3259
|
end
|
@@ -3025,13 +3269,24 @@ module Steep
|
|
3025
3269
|
|
3026
3270
|
result = check_relation(sub_type: given_block_type, super_type: method_block_type, constraints: constraints)
|
3027
3271
|
result.else do |result|
|
3028
|
-
errors <<
|
3029
|
-
|
3030
|
-
|
3031
|
-
|
3272
|
+
errors << Diagnostic::Ruby::BlockTypeMismatch.new(
|
3273
|
+
node: args.block_pass_arg,
|
3274
|
+
expected: method_block_type,
|
3275
|
+
actual: given_block_type,
|
3276
|
+
result: result
|
3277
|
+
)
|
3032
3278
|
end
|
3033
3279
|
|
3034
|
-
method_type = method_type.subst(
|
3280
|
+
method_type = method_type.subst(
|
3281
|
+
constraints.solution(
|
3282
|
+
checker,
|
3283
|
+
self_type: self_type,
|
3284
|
+
instance_type: module_context.instance_type,
|
3285
|
+
class_type: module_context.module_type,
|
3286
|
+
variance: variance,
|
3287
|
+
variables: method_type.free_variables
|
3288
|
+
)
|
3289
|
+
)
|
3035
3290
|
end
|
3036
3291
|
end
|
3037
3292
|
end
|
@@ -3069,8 +3324,9 @@ module Steep
|
|
3069
3324
|
block_constr = for_block(
|
3070
3325
|
block_params: block_params,
|
3071
3326
|
block_param_hint: nil,
|
3327
|
+
block_type_hint: AST::Builtin.any_type,
|
3072
3328
|
block_annotations: block_annotations,
|
3073
|
-
node_type_hint:
|
3329
|
+
node_type_hint: AST::Builtin.any_type
|
3074
3330
|
)
|
3075
3331
|
|
3076
3332
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
@@ -3079,10 +3335,23 @@ module Steep
|
|
3079
3335
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
3080
3336
|
end
|
3081
3337
|
|
3082
|
-
block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body
|
3338
|
+
block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
|
3339
|
+
|
3340
|
+
if expected_block_type = block_constr.block_context.body_type
|
3341
|
+
block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
|
3342
|
+
block_constr.typing.add_error(
|
3343
|
+
Diagnostic::Ruby::BlockBodyTypeMismatch.new(
|
3344
|
+
node: node,
|
3345
|
+
expected: expected_block_type,
|
3346
|
+
actual: block_type,
|
3347
|
+
result: result
|
3348
|
+
)
|
3349
|
+
)
|
3350
|
+
end
|
3351
|
+
end
|
3083
3352
|
end
|
3084
3353
|
|
3085
|
-
def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
|
3354
|
+
def for_block(block_params:, block_param_hint:, block_type_hint:, block_annotations:, node_type_hint:)
|
3086
3355
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
3087
3356
|
|
3088
3357
|
param_types_hash = {}
|
@@ -3114,7 +3383,7 @@ module Steep
|
|
3114
3383
|
end
|
3115
3384
|
|
3116
3385
|
block_context = TypeInference::Context::BlockContext.new(
|
3117
|
-
body_type: block_annotations.block_type
|
3386
|
+
body_type: block_annotations.block_type || block_type_hint || AST::Builtin.any_type
|
3118
3387
|
)
|
3119
3388
|
break_context = TypeInference::Context::BreakContext.new(
|
3120
3389
|
break_type: break_type,
|
@@ -3139,20 +3408,9 @@ module Steep
|
|
3139
3408
|
)
|
3140
3409
|
end
|
3141
3410
|
|
3142
|
-
def synthesize_block(node:, block_type_hint:, block_body
|
3411
|
+
def synthesize_block(node:, block_type_hint:, block_body:)
|
3143
3412
|
if block_body
|
3144
|
-
body_type, _, context =
|
3145
|
-
if (body_type = block_context.body_type)
|
3146
|
-
check(block_body, body_type) do |expected, actual, result|
|
3147
|
-
error = Errors::BlockTypeMismatch.new(node: block_body,
|
3148
|
-
expected: expected,
|
3149
|
-
actual: actual,
|
3150
|
-
result: result)
|
3151
|
-
yield(error) if block_given?
|
3152
|
-
end
|
3153
|
-
else
|
3154
|
-
synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
3155
|
-
end
|
3413
|
+
body_type, _, context = synthesize(block_body, hint: block_context.body_type || block_type_hint)
|
3156
3414
|
|
3157
3415
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
3158
3416
|
typing.add_context(range, context: context)
|
@@ -3245,7 +3503,7 @@ module Steep
|
|
3245
3503
|
if module_name.namespace.relative?
|
3246
3504
|
(current_namespace + module_name.namespace).append(module_name.name)
|
3247
3505
|
else
|
3248
|
-
module_name
|
3506
|
+
module_name.to_namespace
|
3249
3507
|
end
|
3250
3508
|
end
|
3251
3509
|
|
@@ -3295,10 +3553,14 @@ module Steep
|
|
3295
3553
|
# ok
|
3296
3554
|
else
|
3297
3555
|
if module_name.name == module_context&.class_name
|
3298
|
-
typing.add_error
|
3299
|
-
|
3300
|
-
|
3301
|
-
|
3556
|
+
typing.add_error(
|
3557
|
+
Diagnostic::Ruby::MethodDefinitionMissing.new(
|
3558
|
+
node: node,
|
3559
|
+
module_name: module_name.name,
|
3560
|
+
kind: :instance,
|
3561
|
+
missing_method: method_name
|
3562
|
+
)
|
3563
|
+
)
|
3302
3564
|
end
|
3303
3565
|
end
|
3304
3566
|
end
|
@@ -3310,26 +3572,32 @@ module Steep
|
|
3310
3572
|
# ok
|
3311
3573
|
else
|
3312
3574
|
if module_name.name == module_context&.class_name
|
3313
|
-
typing.add_error
|
3314
|
-
|
3315
|
-
|
3316
|
-
|
3575
|
+
typing.add_error(
|
3576
|
+
Diagnostic::Ruby::MethodDefinitionMissing.new(node: node,
|
3577
|
+
module_name: module_name.name,
|
3578
|
+
kind: :module,
|
3579
|
+
missing_method: method_name)
|
3580
|
+
)
|
3317
3581
|
end
|
3318
3582
|
end
|
3319
3583
|
end
|
3320
3584
|
|
3321
3585
|
annotations.instance_dynamics.each do |method_name|
|
3322
3586
|
unless expected_instance_method_names.member?(method_name)
|
3323
|
-
typing.add_error
|
3324
|
-
|
3325
|
-
|
3587
|
+
typing.add_error(
|
3588
|
+
Diagnostic::Ruby::UnexpectedDynamicMethod.new(node: node,
|
3589
|
+
module_name: module_name.name,
|
3590
|
+
method_name: method_name)
|
3591
|
+
)
|
3326
3592
|
end
|
3327
3593
|
end
|
3328
3594
|
annotations.module_dynamics.each do |method_name|
|
3329
3595
|
unless expected_module_method_names.member?(method_name)
|
3330
|
-
typing.add_error
|
3331
|
-
|
3332
|
-
|
3596
|
+
typing.add_error(
|
3597
|
+
Diagnostic::Ruby::UnexpectedDynamicMethod.new(node: node,
|
3598
|
+
module_name: module_name.name,
|
3599
|
+
method_name: method_name)
|
3600
|
+
)
|
3333
3601
|
end
|
3334
3602
|
end
|
3335
3603
|
end
|
@@ -3357,7 +3625,7 @@ module Steep
|
|
3357
3625
|
if block_given?
|
3358
3626
|
typing.add_error yield
|
3359
3627
|
else
|
3360
|
-
typing.add_error
|
3628
|
+
typing.add_error Diagnostic::Ruby::FallbackAny.new(node: node)
|
3361
3629
|
end
|
3362
3630
|
|
3363
3631
|
add_typing node, type: AST::Builtin.any_type
|
@@ -3390,6 +3658,8 @@ module Steep
|
|
3390
3658
|
each_child_node(node) do |child|
|
3391
3659
|
type_any_rec(child)
|
3392
3660
|
end
|
3661
|
+
|
3662
|
+
Pair.new(type: AST::Builtin.any_type, constr: self)
|
3393
3663
|
end
|
3394
3664
|
|
3395
3665
|
def fallback_any_rec(node)
|