steep 0.13.0 → 0.16.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/CHANGELOG.md +28 -0
  4. data/Rakefile +0 -13
  5. data/bin/setup +0 -2
  6. data/bin/smoke_runner.rb +0 -1
  7. data/exe/steep +0 -1
  8. data/lib/steep.rb +33 -1
  9. data/lib/steep/annotation_parser.rb +4 -4
  10. data/lib/steep/ast/buffer.rb +11 -7
  11. data/lib/steep/ast/builtin.rb +8 -0
  12. data/lib/steep/ast/types/factory.rb +124 -89
  13. data/lib/steep/cli.rb +16 -1
  14. data/lib/steep/drivers/annotations.rb +1 -1
  15. data/lib/steep/drivers/check.rb +20 -4
  16. data/lib/steep/drivers/init.rb +5 -5
  17. data/lib/steep/drivers/langserver.rb +13 -287
  18. data/lib/steep/drivers/utils/driver_helper.rb +1 -1
  19. data/lib/steep/drivers/vendor.rb +2 -2
  20. data/lib/steep/drivers/watch.rb +97 -85
  21. data/lib/steep/drivers/worker.rb +51 -0
  22. data/lib/steep/project.rb +9 -5
  23. data/lib/steep/project/completion_provider.rb +298 -0
  24. data/lib/steep/project/dsl.rb +14 -0
  25. data/lib/steep/project/file.rb +54 -47
  26. data/lib/steep/project/hover_content.rb +17 -8
  27. data/lib/steep/project/options.rb +25 -3
  28. data/lib/steep/project/target.rb +40 -24
  29. data/lib/steep/server/base_worker.rb +56 -0
  30. data/lib/steep/server/code_worker.rb +151 -0
  31. data/lib/steep/server/interaction_worker.rb +281 -0
  32. data/lib/steep/server/master.rb +196 -0
  33. data/lib/steep/server/signature_worker.rb +148 -0
  34. data/lib/steep/server/utils.rb +36 -0
  35. data/lib/steep/server/worker_process.rb +62 -0
  36. data/lib/steep/signature/errors.rb +1 -1
  37. data/lib/steep/signature/validator.rb +13 -13
  38. data/lib/steep/source.rb +1 -1
  39. data/lib/steep/type_construction.rb +1004 -727
  40. data/lib/steep/type_inference/constant_env.rb +3 -11
  41. data/lib/steep/type_inference/context.rb +8 -3
  42. data/lib/steep/type_inference/context_array.rb +111 -0
  43. data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
  44. data/lib/steep/type_inference/logic.rb +130 -0
  45. data/lib/steep/type_inference/type_env.rb +5 -69
  46. data/lib/steep/typing.rb +91 -23
  47. data/lib/steep/version.rb +1 -1
  48. data/smoke/alias/Steepfile +1 -0
  49. data/smoke/alias/a.rb +1 -1
  50. data/smoke/and/Steepfile +1 -0
  51. data/smoke/array/Steepfile +1 -0
  52. data/smoke/array/b.rb +0 -2
  53. data/smoke/block/Steepfile +1 -0
  54. data/smoke/case/Steepfile +1 -0
  55. data/smoke/class/Steepfile +1 -0
  56. data/smoke/const/Steepfile +1 -0
  57. data/smoke/dstr/Steepfile +1 -0
  58. data/smoke/ensure/Steepfile +1 -0
  59. data/smoke/enumerator/Steepfile +1 -0
  60. data/smoke/extension/Steepfile +1 -0
  61. data/smoke/extension/c.rb +1 -0
  62. data/smoke/hash/Steepfile +1 -0
  63. data/smoke/hello/Steepfile +1 -0
  64. data/smoke/if/Steepfile +1 -0
  65. data/smoke/if/a.rb +1 -1
  66. data/smoke/implements/Steepfile +1 -0
  67. data/smoke/initialize/Steepfile +1 -0
  68. data/smoke/integer/Steepfile +1 -0
  69. data/smoke/interface/Steepfile +1 -0
  70. data/smoke/kwbegin/Steepfile +1 -0
  71. data/smoke/lambda/Steepfile +1 -0
  72. data/smoke/literal/Steepfile +1 -0
  73. data/smoke/map/Steepfile +1 -0
  74. data/smoke/method/Steepfile +1 -0
  75. data/smoke/module/Steepfile +1 -0
  76. data/smoke/regexp/Steepfile +1 -0
  77. data/smoke/regexp/b.rb +4 -4
  78. data/smoke/regression/Steepfile +1 -0
  79. data/smoke/rescue/Steepfile +1 -0
  80. data/smoke/rescue/a.rb +1 -1
  81. data/smoke/self/Steepfile +1 -0
  82. data/smoke/skip/Steepfile +1 -0
  83. data/smoke/stdout/Steepfile +1 -0
  84. data/smoke/super/Steepfile +1 -0
  85. data/smoke/type_case/Steepfile +1 -0
  86. data/smoke/yield/Steepfile +1 -0
  87. data/steep.gemspec +8 -8
  88. metadata +38 -138
  89. data/exe/rbs +0 -3
  90. data/exe/ruby-signature +0 -3
  91. data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
  92. data/vendor/ruby-signature/.gitignore +0 -12
  93. data/vendor/ruby-signature/.rubocop.yml +0 -15
  94. data/vendor/ruby-signature/BSDL +0 -22
  95. data/vendor/ruby-signature/COPYING +0 -56
  96. data/vendor/ruby-signature/Gemfile +0 -6
  97. data/vendor/ruby-signature/README.md +0 -93
  98. data/vendor/ruby-signature/Rakefile +0 -66
  99. data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -156
  100. data/vendor/ruby-signature/bin/console +0 -14
  101. data/vendor/ruby-signature/bin/query-rdoc +0 -103
  102. data/vendor/ruby-signature/bin/setup +0 -10
  103. data/vendor/ruby-signature/bin/sort +0 -88
  104. data/vendor/ruby-signature/bin/test_runner.rb +0 -17
  105. data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
  106. data/vendor/ruby-signature/docs/sigs.md +0 -148
  107. data/vendor/ruby-signature/docs/stdlib.md +0 -152
  108. data/vendor/ruby-signature/docs/syntax.md +0 -528
  109. data/vendor/ruby-signature/exe/rbs +0 -3
  110. data/vendor/ruby-signature/exe/ruby-signature +0 -7
  111. data/vendor/ruby-signature/lib/ruby/signature.rb +0 -64
  112. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
  113. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
  114. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
  115. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
  116. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
  117. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
  118. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -534
  119. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
  120. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
  121. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
  122. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
  123. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
  124. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
  125. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
  126. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
  127. data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
  128. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
  129. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
  130. data/vendor/ruby-signature/lib/ruby/signature/parser.y +0 -1343
  131. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -441
  132. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
  133. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
  134. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
  135. data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
  136. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
  137. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
  138. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +0 -58
  139. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -324
  140. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
  141. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
  142. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
  143. data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
  144. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
  145. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
  146. data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
  147. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
  148. data/vendor/ruby-signature/ruby-signature.gemspec +0 -45
  149. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -3
  150. data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -15
  151. data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
  152. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
  153. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
  154. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -35
  155. data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
  156. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
  157. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
  158. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
  159. data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
  160. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
  161. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -419
  162. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -606
  163. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
  164. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
  165. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
  166. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
  167. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -193
  168. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
  169. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
  170. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
  171. data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -476
  172. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
  173. data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
  174. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -121
  175. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
  176. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -710
  177. data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
  178. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -574
  179. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -135
  180. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -141
  181. data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -66
  182. data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -182
  183. data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -248
  184. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
  185. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
  186. data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
  187. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -426
  188. data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -354
  189. data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -93
  190. data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
  191. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
  192. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -10
  193. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -131
  194. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
  195. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
  196. data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -770
  197. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -13
  198. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
  199. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -230
  200. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1112
  201. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
  202. data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -739
  203. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -91
  204. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
  205. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -159
  206. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
  207. data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -18
  208. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -44
  209. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -21
  210. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
  211. data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
  212. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
  213. data/vendor/ruby-signature/stdlib/set/set.rbs +0 -77
  214. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
@@ -0,0 +1,148 @@
1
+ module Steep
2
+ module Server
3
+ class SignatureWorker < BaseWorker
4
+ attr_reader :queue
5
+ attr_reader :last_target_validated_at
6
+
7
+ def initialize(project:, reader:, writer:, queue: Queue.new)
8
+ super(project: project, reader: reader, writer: writer)
9
+
10
+ @queue = queue
11
+ @last_target_validated_at = {}
12
+ end
13
+
14
+ def validate_signature_if_required(request)
15
+ path = source_path(URI.parse(request[:params][:textDocument][:uri]))
16
+
17
+ project.targets.each do |target|
18
+ if target.signature_file?(path)
19
+ enqueue_target target: target, timestamp: Time.now
20
+ end
21
+ end
22
+ end
23
+
24
+ def enqueue_target(target:, timestamp:)
25
+ Steep.logger.debug "queueing target #{target.name}@#{timestamp}"
26
+ last_target_validated_at[target] = timestamp
27
+ queue << [target, timestamp]
28
+ end
29
+
30
+ def handle_request(request)
31
+ case request[:method]
32
+ when "initialize"
33
+ # Don't respond to initialize request, but start type checking.
34
+ project.targets.each do |target|
35
+ enqueue_target(target: target, timestamp: Time.now)
36
+ end
37
+ when "textDocument/didChange"
38
+ update_source(request)
39
+ validate_signature_if_required(request)
40
+ end
41
+ end
42
+
43
+ def validate_signature(target, timestamp:)
44
+ Steep.logger.info "Starting signature validation: #{target.name} (#{timestamp})..."
45
+
46
+ target.type_check(target_sources: [], validate_signatures: true)
47
+
48
+ Steep.logger.info "Finished signature validation: #{target.name} (#{timestamp})"
49
+
50
+ diagnostics = case status = target.status
51
+ when Project::Target::SignatureSyntaxErrorStatus
52
+ target.signature_files.each.with_object({}) do |(path, file), hash|
53
+ if file.status.is_a?(Project::SignatureFile::ParseErrorStatus)
54
+ location = case error = file.status.error
55
+ when RBS::Parser::SyntaxError
56
+ if error.error_value.is_a?(String)
57
+ buf = RBS::Buffer.new(name: path, content: file.content)
58
+ RBS::Location.new(buffer: buf, start_pos: buf.content.size, end_pos: buf.content.size)
59
+ else
60
+ error.error_value.location
61
+ end
62
+ when RBS::Parser::SemanticsError
63
+ error.location
64
+ else
65
+ raise
66
+ end
67
+
68
+ hash[path] =
69
+ [
70
+ LSP::Interface::Diagnostic.new(
71
+ message: file.status.error.message,
72
+ severity: LSP::Constant::DiagnosticSeverity::ERROR,
73
+ range: LSP::Interface::Range.new(
74
+ start: LSP::Interface::Position.new(
75
+ line: location.start_line - 1,
76
+ character: location.start_column,
77
+ ),
78
+ end: LSP::Interface::Position.new(
79
+ line: location.end_line - 1,
80
+ character: location.end_column
81
+ )
82
+ )
83
+ )
84
+ ]
85
+ else
86
+ hash[path] = []
87
+ end
88
+ end
89
+ when Project::Target::SignatureValidationErrorStatus
90
+ error_hash = status.errors.group_by {|error| error.location.buffer.name }
91
+
92
+ target.signature_files.each_key.with_object({}) do |path, hash|
93
+ errors = error_hash[path] || []
94
+ hash[path] = errors.map do |error|
95
+ LSP::Interface::Diagnostic.new(
96
+ message: StringIO.new.tap {|io| error.puts(io) }.string.split(/\t/, 2).last,
97
+ severity: LSP::Constant::DiagnosticSeverity::ERROR,
98
+ range: LSP::Interface::Range.new(
99
+ start: LSP::Interface::Position.new(
100
+ line: error.location.start_line - 1,
101
+ character: error.location.start_column,
102
+ ),
103
+ end: LSP::Interface::Position.new(
104
+ line: error.location.end_line - 1,
105
+ character: error.location.end_column
106
+ )
107
+ )
108
+ )
109
+ end
110
+ end
111
+ when Project::Target::TypeCheckStatus
112
+ target.signature_files.each_key.with_object({}) do |path, hash|
113
+ hash[path] = []
114
+ end
115
+ else
116
+ Steep.logger.info "Unexpected target status: #{status.class}"
117
+ end
118
+
119
+ diagnostics.each do |path, diags|
120
+ writer.write(
121
+ method: :"textDocument/publishDiagnostics",
122
+ params: LSP::Interface::PublishDiagnosticsParams.new(
123
+ uri: URI.parse(project.absolute_path(path).to_s).tap {|uri| uri.scheme = "file"},
124
+ diagnostics: diags
125
+ )
126
+ )
127
+ end
128
+ end
129
+
130
+ def active_job?(target, timestamp)
131
+ if last_target_validated_at[target] == timestamp
132
+ sleep 0.1
133
+ last_target_validated_at[target] == timestamp
134
+ end
135
+ end
136
+
137
+ def handle_job(job)
138
+ target, timestamp = job
139
+
140
+ if active_job?(target, timestamp)
141
+ validate_signature(target, timestamp: timestamp)
142
+ else
143
+ Steep.logger.info "Skipping signature validation: #{target.name}, queued timestamp=#{timestamp}, latest timestamp=#{last_target_validated_at[target]}"
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,36 @@
1
+ module Steep
2
+ module Server
3
+ module Utils
4
+ LSP = LanguageServer::Protocol
5
+
6
+ def source_path(uri)
7
+ project.relative_path(Pathname(uri.path))
8
+ end
9
+
10
+ def update_source(request)
11
+ path = source_path(URI.parse(request[:params][:textDocument][:uri]))
12
+ text = request[:params][:contentChanges][0][:text]
13
+ version = request[:params][:textDocument][:version]
14
+
15
+ Steep.logger.debug "Updateing source: path=#{path}, version=#{version}, size=#{text.bytesize}"
16
+
17
+ project.targets.each do |target|
18
+ case
19
+ when target.source_file?(path)
20
+ target.update_source path, text
21
+ when target.possible_source_file?(path)
22
+ target.add_source path, text
23
+ when target.signature_file?(path)
24
+ target.update_signature path, text
25
+ when target.possible_signature_file?(path)
26
+ target.add_signature path, text
27
+ end
28
+ end
29
+
30
+ if block_given?
31
+ yield path, version
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,62 @@
1
+ module Steep
2
+ module Server
3
+ class WorkerProcess
4
+ attr_reader :reader
5
+ attr_reader :writer
6
+ attr_reader :stderr
7
+
8
+ attr_reader :wait_thread
9
+
10
+ def initialize(reader:, writer:, stderr:, wait_thread:)
11
+ @reader = reader
12
+ @writer = writer
13
+ @stderr = stderr
14
+ @wait_thread = wait_thread
15
+ end
16
+
17
+ def self.spawn_worker(type, name:, steepfile:)
18
+ log_level = %w(debug info warn error fatal unknown)[Steep.logger.level]
19
+ command = case type
20
+ when :code
21
+ ["steep", "worker", "--code", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
22
+ when :signature
23
+ ["steep", "worker", "--signature", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
24
+ when :interaction
25
+ ["steep", "worker", "--interaction", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
26
+ else
27
+ raise
28
+ end
29
+
30
+ stdin, stdout, thread = Open3.popen2(*command, pgroup: true)
31
+ stderr = nil
32
+
33
+ writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
34
+ reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout)
35
+
36
+ new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread)
37
+ end
38
+
39
+ def self.spawn_code_workers(steepfile:, count: [Etc.nprocessors-3, 1].max)
40
+ count.times.map do |i|
41
+ spawn_worker(:code, name: "code@#{i}", steepfile: steepfile)
42
+ end
43
+ end
44
+
45
+ def <<(message)
46
+ writer.write(message)
47
+ end
48
+
49
+ def read(&block)
50
+ reader.read(&block)
51
+ end
52
+
53
+ def shutdown
54
+ self << { method: :shutdown, params: nil }
55
+ self << { method: :exit, params: nil }
56
+
57
+ writer.io.close()
58
+ @wait_thread.join()
59
+ end
60
+ end
61
+ end
62
+ end
@@ -5,7 +5,7 @@ module Steep
5
5
  attr_reader :location
6
6
 
7
7
  def loc_to_s
8
- Ruby::Signature::Location.to_string location
8
+ RBS::Location.to_string location
9
9
  end
10
10
 
11
11
  def to_s
@@ -1,8 +1,8 @@
1
1
  module Steep
2
2
  module Signature
3
3
  class Validator
4
- Location = Ruby::Signature::Location
5
- Declarations = Ruby::Signature::AST::Declarations
4
+ Location = RBS::Location
5
+ Declarations = RBS::AST::Declarations
6
6
 
7
7
  attr_reader :checker
8
8
 
@@ -51,19 +51,19 @@ module Steep
51
51
  case decl
52
52
  when Declarations::Class
53
53
  rescue_validation_errors do
54
- Steep.logger.info "#{Location.to_string decl.location}:\tValidating class definition `#{name}`..."
54
+ Steep.logger.debug "#{Location.to_string decl.location}:\tValidating class definition `#{name}`..."
55
55
  builder.build_instance(decl.name.absolute!).each_type do |type|
56
- env.validate type, namespace: Ruby::Signature::Namespace.root
56
+ env.validate type, namespace: RBS::Namespace.root
57
57
  end
58
58
  builder.build_singleton(decl.name.absolute!).each_type do |type|
59
- env.validate type, namespace: Ruby::Signature::Namespace.root
59
+ env.validate type, namespace: RBS::Namespace.root
60
60
  end
61
61
  end
62
62
  when Declarations::Interface
63
63
  rescue_validation_errors do
64
- Steep.logger.info "#{Location.to_string decl.location}:\tValidating interface `#{name}`..."
64
+ Steep.logger.debug "#{Location.to_string decl.location}:\tValidating interface `#{name}`..."
65
65
  builder.build_interface(decl.name.absolute!, decl).each_type do |type|
66
- env.validate type, namespace: Ruby::Signature::Namespace.root
66
+ env.validate type, namespace: RBS::Namespace.root
67
67
  end
68
68
  end
69
69
  end
@@ -78,7 +78,7 @@ module Steep
78
78
  def validate_const
79
79
  env.each_constant do |name, decl|
80
80
  rescue_validation_errors do
81
- Steep.logger.info "#{Location.to_string decl.location}:\tValidating constant `#{name}`..."
81
+ Steep.logger.debug "#{Location.to_string decl.location}:\tValidating constant `#{name}`..."
82
82
  env.validate(decl.type, namespace: name.namespace)
83
83
  end
84
84
  end
@@ -87,8 +87,8 @@ module Steep
87
87
  def validate_global
88
88
  env.each_global do |name, decl|
89
89
  rescue_validation_errors do
90
- Steep.logger.info "#{Location.to_string decl.location}:\tValidating global `#{name}`..."
91
- env.validate(decl.type, namespace: Ruby::Signature::Namespace.root)
90
+ Steep.logger.debug "#{Location.to_string decl.location}:\tValidating global `#{name}`..."
91
+ env.validate(decl.type, namespace: RBS::Namespace.root)
92
92
  end
93
93
  end
94
94
  end
@@ -96,7 +96,7 @@ module Steep
96
96
  def validate_alias
97
97
  env.each_alias do |name, decl|
98
98
  rescue_validation_errors do
99
- Steep.logger.info "#{Location.to_string decl.location}:\tValidating alias `#{name}`..."
99
+ Steep.logger.debug "#{Location.to_string decl.location}:\tValidating alias `#{name}`..."
100
100
  env.validate(decl.type, namespace: name.namespace)
101
101
  end
102
102
  end
@@ -104,14 +104,14 @@ module Steep
104
104
 
105
105
  def rescue_validation_errors
106
106
  yield
107
- rescue Ruby::Signature::InvalidTypeApplicationError => exn
107
+ rescue RBS::InvalidTypeApplicationError => exn
108
108
  @errors << Errors::InvalidTypeApplicationError.new(
109
109
  name: factory.type_name(exn.type_name),
110
110
  args: exn.args.map {|ty| factory.type(ty) },
111
111
  params: exn.params.each.map(&:name),
112
112
  location: exn.location
113
113
  )
114
- rescue Ruby::Signature::NoTypeFoundError => exn
114
+ rescue RBS::NoTypeFoundError => exn
115
115
  @errors << Errors::UnknownTypeNameError.new(
116
116
  name: factory.type_name(exn.type_name),
117
117
  location: exn.location
@@ -51,7 +51,7 @@ module Steep
51
51
  if n
52
52
  labeling.translate(n, {})
53
53
  else
54
- return
54
+ return new(path: path, node: nil, mapping: {})
55
55
  end
56
56
  end
57
57
 
@@ -1,5 +1,38 @@
1
1
  module Steep
2
2
  class TypeConstruction
3
+ class Pair
4
+ attr_reader :type
5
+ attr_reader :constr
6
+
7
+ def initialize(type:, constr:)
8
+ @type = type
9
+ @constr = constr
10
+ end
11
+
12
+ def with(type: self.type, constr: self.constr)
13
+ self.class.new(
14
+ type: type,
15
+ constr: constr
16
+ )
17
+ end
18
+
19
+ def +(other)
20
+ if type.is_a?(AST::Types::Bot)
21
+ other.with(type: type)
22
+ else
23
+ other
24
+ end
25
+ end
26
+
27
+ def context
28
+ constr.context
29
+ end
30
+
31
+ def to_ary
32
+ [type, constr, context]
33
+ end
34
+ end
35
+
3
36
  attr_reader :checker
4
37
  attr_reader :source
5
38
  attr_reader :annotations
@@ -50,6 +83,36 @@ module Steep
50
83
  )
51
84
  end
52
85
 
86
+ def with_updated_context(lvar_env: self.context.lvar_env)
87
+ if lvar_env != self.context.lvar_env
88
+ with(context: self.context.with(lvar_env: lvar_env))
89
+ else
90
+ self
91
+ end
92
+ end
93
+
94
+ def with(annotations: self.annotations, context: self.context, typing: self.typing)
95
+ if context != self.context || typing != self.typing
96
+ self.class.new(
97
+ checker: checker,
98
+ source: source,
99
+ annotations: annotations,
100
+ typing: typing,
101
+ context: context
102
+ )
103
+ else
104
+ self
105
+ end
106
+ end
107
+
108
+ def update_context()
109
+ with(context: yield(self.context))
110
+ end
111
+
112
+ def update_lvar_env
113
+ with_updated_context(lvar_env: yield(context.lvar_env))
114
+ end
115
+
53
116
  def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
54
117
  checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
55
118
  end
@@ -100,7 +163,7 @@ module Steep
100
163
  else
101
164
  method_type.block.type
102
165
  end
103
- var_types[block_arg.children[0].name] = block_type
166
+ var_types[block_arg.children[0]] = block_type
104
167
  end
105
168
  end
106
169
 
@@ -123,12 +186,6 @@ module Steep
123
186
  super_method: super_method
124
187
  )
125
188
 
126
- if var_types
127
- var_types.each do |name, type|
128
- type_env.set(lvar: name, type: type)
129
- end
130
- end
131
-
132
189
  if definition
133
190
  definition.instance_variables.each do |name, decl|
134
191
  type_env.set(ivar: name, type: checker.factory.type(decl.type))
@@ -136,12 +193,27 @@ module Steep
136
193
  end
137
194
 
138
195
  type_env = type_env.with_annotations(
139
- lvar_types: annots.lvar_types,
140
196
  ivar_types: annots.ivar_types,
141
197
  const_types: annots.const_types,
142
198
  self_type: annots.self_type || self_type
143
199
  )
144
200
 
201
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
202
+ subtyping: checker,
203
+ self_type: annots.self_type || self_type
204
+ )
205
+
206
+ if var_types
207
+ lvar_env = lvar_env.update(
208
+ assigned_types: var_types.each.with_object({}) {|(var, type), hash|
209
+ arg_node = args.find {|arg| arg.children[0] == var }
210
+ hash[var.name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type, nodes: [arg_node].compact)
211
+ }
212
+ )
213
+ end
214
+
215
+ lvar_env = lvar_env.annotate(annots)
216
+
145
217
  self.class.new(
146
218
  checker: checker,
147
219
  source: source,
@@ -152,7 +224,8 @@ module Steep
152
224
  block_context: nil,
153
225
  break_context: nil,
154
226
  self_type: annots.self_type || self_type,
155
- type_env: type_env
227
+ type_env: type_env,
228
+ lvar_env: lvar_env
156
229
  ),
157
230
  typing: typing,
158
231
  )
@@ -162,6 +235,9 @@ module Steep
162
235
  new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
163
236
  new_namespace = nested_namespace_for_module(new_module_name)
164
237
 
238
+ const_context = [new_namespace] + self.module_context.const_env.context
239
+ module_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
240
+
165
241
  annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
166
242
  module_type = AST::Builtin::Module.instance_type
167
243
 
@@ -219,13 +295,6 @@ module Steep
219
295
  module_type = annots.module_type
220
296
  end
221
297
 
222
- const_context = if new_namespace.empty?
223
- nil
224
- else
225
- Names::Module.new(name: new_namespace.path.last, namespace: new_namespace.parent)
226
- end
227
- module_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
228
-
229
298
  module_context_ = TypeInference::Context::ModuleContext.new(
230
299
  instance_type: instance_type,
231
300
  module_type: annots.self_type || module_type,
@@ -242,6 +311,11 @@ module Steep
242
311
  const_env: module_const_env,
243
312
  signatures: checker.factory.env)
244
313
 
314
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
315
+ subtyping: checker,
316
+ self_type: module_context_.module_type
317
+ ).annotate(annots)
318
+
245
319
  self.class.new(
246
320
  checker: checker,
247
321
  source: source,
@@ -253,7 +327,8 @@ module Steep
253
327
  break_context: nil,
254
328
  module_context: module_context_,
255
329
  self_type: module_context_.module_type,
256
- type_env: module_type_env
330
+ type_env: module_type_env,
331
+ lvar_env: lvar_env
257
332
  )
258
333
  )
259
334
  end
@@ -318,11 +393,7 @@ module Steep
318
393
  module_type = annots.module_type
319
394
  end
320
395
 
321
- const_context = if new_namespace.empty?
322
- nil
323
- else
324
- Names::Module.new(name: new_namespace.path.last, namespace: new_namespace.parent)
325
- end
396
+ const_context = [new_namespace] + self.module_context.const_env.context
326
397
  class_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
327
398
 
328
399
  module_context = TypeInference::Context::ModuleContext.new(
@@ -341,51 +412,90 @@ module Steep
341
412
  const_env: class_const_env,
342
413
  signatures: checker.factory.env)
343
414
 
415
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
416
+ subtyping: checker,
417
+ self_type: module_context.module_type
418
+ ).annotate(annots)
419
+
420
+ class_body_context = TypeInference::Context.new(
421
+ method_context: nil,
422
+ block_context: nil,
423
+ module_context: module_context,
424
+ break_context: nil,
425
+ self_type: module_context.module_type,
426
+ type_env: class_type_env,
427
+ lvar_env: lvar_env
428
+ )
344
429
 
345
430
  self.class.new(
346
431
  checker: checker,
347
432
  source: source,
348
433
  annotations: annots,
349
434
  typing: typing,
350
- context: TypeInference::Context.new(
351
- method_context: nil,
352
- block_context: nil,
353
- module_context: module_context,
354
- break_context: nil,
355
- self_type: module_context.module_type,
356
- type_env: class_type_env
357
- )
435
+ context: class_body_context
358
436
  )
359
437
  end
360
438
 
361
439
  def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
362
440
  annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
363
441
 
364
- lvar_types = self.type_env.lvar_types.each.with_object({}) do |(var, type), env|
365
- if truthy_vars.member?(var)
366
- env[var] = unwrap(type)
367
- else
368
- env[var] = type
442
+ lvar_env = context.lvar_env
443
+
444
+ unless truthy_vars.empty?
445
+ lvar_env = lvar_env.yield_self do |env|
446
+ decls = env.declared_types.each.with_object({}) do |(name, entry), hash|
447
+ if truthy_vars.include?(name)
448
+ hash[name] = entry.update(type: unwrap(entry.type))
449
+ else
450
+ hash[name] = entry
451
+ end
452
+ end
453
+
454
+ assignments = env.assigned_types.each.with_object({}) do |(name, entry), hash|
455
+ if truthy_vars.include?(name)
456
+ hash[name] = entry.update(type: unwrap(entry.type))
457
+ else
458
+ hash[name] = entry
459
+ end
460
+ end
461
+
462
+ env.update(declared_types: decls, assigned_types: assignments)
369
463
  end
370
464
  end
371
465
 
372
- type_env = self.type_env.with_annotations(lvar_types: lvar_types, self_type: self_type) do |var, relation, result|
373
- raise "Unexpected annotate failure: #{relation}"
466
+ if type_case_override
467
+ lvar_env = type_case_override.inject(lvar_env) do |lvar_env, (name, type)|
468
+ lvar_env.assign!(name, node: node, type: type) do |declared_type, assigned_type, result|
469
+ relation = Subtyping::Relation.new(sub_type: assigned_type, super_type: declared_type)
470
+ typing.add_error(
471
+ Errors::IncompatibleTypeCase.new(
472
+ node: node,
473
+ var_name: name,
474
+ relation: relation,
475
+ result: result
476
+ )
477
+ )
478
+ end
479
+ end
374
480
  end
375
481
 
376
- if type_case_override
377
- type_env = type_env.with_annotations(lvar_types: type_case_override, self_type: self_type) do |var, relation, result|
378
- typing.add_error(
379
- Errors::IncompatibleTypeCase.new(node: node,
482
+ lvar_env = lvar_env.annotate(annots) do |var, outer_type, inner_type, result|
483
+ relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
484
+ typing.add_error(
485
+ Errors::IncompatibleAnnotation.new(node: node,
380
486
  var_name: var,
381
487
  relation: relation,
382
488
  result: result)
383
- )
384
- end
489
+ )
490
+ end
491
+
492
+ type_env = context.type_env
493
+
494
+ if type_case_override
495
+ type_env = type_env.with_annotations(self_type: self_type)
385
496
  end
386
497
 
387
498
  type_env = type_env.with_annotations(
388
- lvar_types: annots.lvar_types,
389
499
  ivar_types: annots.ivar_types,
390
500
  const_types: annots.const_types,
391
501
  gvar_types: {},
@@ -399,19 +509,18 @@ module Steep
399
509
  )
400
510
  end
401
511
 
402
- with(context: context.with(type_env: type_env, break_context: break_context))
512
+ update_context {|context|
513
+ context.with(type_env: type_env,
514
+ break_context: break_context,
515
+ lvar_env: lvar_env)
516
+ }
403
517
  end
404
518
 
405
- NOTHING = ::Object.new
519
+ def add_typing(node, type:, constr: self)
520
+ raise if constr.typing != self.typing
406
521
 
407
- def with(annotations: NOTHING, context: NOTHING)
408
- self.class.new(
409
- checker: checker,
410
- source: source,
411
- annotations: annotations.equal?(NOTHING) ? self.annotations : annotations,
412
- typing: typing,
413
- context: context.equal?(NOTHING) ? self.context : context
414
- )
522
+ typing.add_typing(node, type, nil)
523
+ Pair.new(type: type, constr: constr)
415
524
  end
416
525
 
417
526
  def synthesize(node, hint: nil)
@@ -420,43 +529,63 @@ module Steep
420
529
  case node.type
421
530
  when :begin, :kwbegin
422
531
  yield_self do
532
+ end_pos = node.loc.expression.end_pos
533
+
423
534
  *mid_nodes, last_node = each_child_node(node).to_a
424
- mid_nodes.each do |child|
425
- synthesize(child)
426
- end
427
535
  if last_node
428
- type = synthesize(last_node, hint: hint)
536
+ pair = mid_nodes.inject(Pair.new(type: AST::Builtin.nil_type, constr: self)) do |pair, node|
537
+ pair.constr.synthesize(node).yield_self {|p| pair + p }.tap do |new_pair|
538
+ if new_pair.constr.context != pair.constr.context
539
+ # update context
540
+ range = node.loc.expression.end_pos..end_pos
541
+ typing.add_context(range, context: new_pair.constr.context)
542
+ end
543
+ end
544
+ end
545
+
546
+ p = pair.constr.synthesize(last_node, hint: hint)
547
+ last_pair = pair + p
548
+ last_pair.constr.add_typing(node, type: last_pair.type, constr: last_pair.constr)
429
549
  else
430
- type = AST::Builtin.nil_type
550
+ add_typing(node, type: AST::Builtin.nil_type)
431
551
  end
432
-
433
- typing.add_typing(node, type, context)
434
552
  end
435
553
 
436
554
  when :lvasgn
437
555
  yield_self do
438
- var = node.children[0]
439
- rhs = node.children[1]
556
+ var, rhs = node.children
557
+ name = var.name
440
558
 
441
- case var.name
559
+ case name
442
560
  when :_, :__any__
443
- synthesize(rhs, hint: AST::Builtin.any_type)
444
- typing.add_typing(node, AST::Builtin.any_type, context)
561
+ synthesize(rhs, hint: AST::Builtin.any_type).yield_self do |pair|
562
+ add_typing(node, type: AST::Builtin.any_type, constr: pair.constr)
563
+ end
445
564
  when :__skip__
446
- typing.add_typing(node, AST::Builtin.any_type, context)
565
+ add_typing(node, type: AST::Builtin.any_type)
447
566
  else
448
- type_assignment(var, rhs, node, hint: hint)
567
+ rhs_result = synthesize(rhs, hint: hint || context.lvar_env.declared_types[name]&.type)
568
+ constr = rhs_result.constr.update_lvar_env do |lvar_env|
569
+ lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
570
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
571
+ lhs_type: declared_type,
572
+ rhs_type: actual_type,
573
+ result: result))
574
+ end
575
+ end
576
+
577
+ add_typing(node, type: rhs_result.type, constr: constr)
449
578
  end
450
579
  end
451
580
 
452
581
  when :lvar
453
582
  yield_self do
454
583
  var = node.children[0]
455
- type = type_env.get(lvar: var.name) do
456
- fallback_to_any node
584
+ if (type = context.lvar_env[var.name])
585
+ add_typing node, type: type
586
+ else
587
+ fallback_to_any(node)
457
588
  end
458
-
459
- typing.add_typing node, type, context
460
589
  end
461
590
 
462
591
  when :ivasgn
@@ -471,7 +600,7 @@ module Steep
471
600
  type = type_env.get(ivar: name) do
472
601
  fallback_to_any node
473
602
  end
474
- typing.add_typing(node, type, context)
603
+ add_typing(node, type: type)
475
604
  end
476
605
 
477
606
  when :send
@@ -484,7 +613,7 @@ module Steep
484
613
  module_type
485
614
  end
486
615
 
487
- typing.add_typing(node, type, context)
616
+ add_typing(node, type: type)
488
617
  else
489
618
  type_send(node, send_node: node, block_params: nil, block_body: nil)
490
619
  end
@@ -492,83 +621,58 @@ module Steep
492
621
 
493
622
  when :csend
494
623
  yield_self do
495
- type = if self_class?(node)
624
+ pair = if self_class?(node)
496
625
  module_type = expand_alias(module_context.module_type)
497
626
  type = if module_type.is_a?(AST::Types::Name::Class)
498
627
  AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
499
628
  else
500
629
  module_type
501
630
  end
502
- typing.add_typing(node, type, context)
631
+ add_typing(node, type: type)
503
632
  else
504
633
  type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true)
505
634
  end
506
635
 
507
- union_type(type, AST::Builtin.nil_type)
636
+ lvar_env = context.lvar_env.join(pair.context.lvar_env, context.lvar_env)
637
+ add_typing(node,
638
+ type: union_type(pair.type, AST::Builtin.nil_type),
639
+ constr: pair.constr.with_updated_context(lvar_env: lvar_env))
508
640
  end
509
641
 
510
642
  when :match_with_lvasgn
511
643
  each_child_node(node) do |child|
512
644
  synthesize(child)
513
645
  end
514
- typing.add_typing(node, AST::Builtin.any_type, context)
646
+ add_typing(node, type: AST::Builtin.any_type)
515
647
 
516
648
  when :op_asgn
517
649
  yield_self do
518
650
  lhs, op, rhs = node.children
519
651
 
520
- synthesize(rhs)
652
+ case lhs.type
653
+ when :lvasgn
654
+ var_node = lhs.updated(:lvar)
655
+ send_node = rhs.updated(:send, [var_node, op, rhs])
656
+ new_node = node.updated(:lvasgn, [lhs.children[0], send_node])
521
657
 
522
- lhs_type = case lhs.type
523
- when :lvasgn
524
- type_env.get(lvar: lhs.children.first.name) do
525
- break
526
- end
527
- when :ivasgn
528
- type_env.get(ivar: lhs.children.first) do
529
- break
530
- end
531
- else
532
- Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
533
- nil
534
- end
658
+ type, constr = synthesize(new_node, hint: hint)
535
659
 
536
- case
537
- when lhs_type == AST::Builtin.any_type
538
- typing.add_typing(node, lhs_type, context)
539
- when !lhs_type
540
- fallback_to_any(node)
541
- else
542
- lhs_interface = checker.factory.interface(lhs_type, private: false)
543
- op_method = lhs_interface.methods[op]
660
+ constr.add_typing(node, type: type)
544
661
 
545
- if op_method
546
- args = TypeInference::SendArgs.from_nodes([rhs])
547
- return_type, _ = type_method_call(node,
548
- receiver_type: lhs_type,
549
- method_name: op,
550
- method: op_method,
551
- args: args,
552
- block_params: nil,
553
- block_body: nil,
554
- topdown_hint: true)
662
+ when :ivasgn
663
+ var_node = lhs.updated(:ivar)
664
+ send_node = rhs.updated(:send, [var_node, op, rhs])
665
+ new_node = node.updated(:ivasgn, [lhs.children[0], send_node])
555
666
 
556
- result = check_relation(sub_type: return_type, super_type: lhs_type)
557
- if result.failure?
558
- typing.add_error(
559
- Errors::IncompatibleAssignment.new(
560
- node: node,
561
- lhs_type: lhs_type,
562
- rhs_type: return_type,
563
- result: result
564
- )
565
- )
566
- end
567
- else
568
- typing.add_error Errors::NoMethod.new(node: node, method: op, type: expand_self(lhs_type))
569
- end
667
+ type, constr = synthesize(new_node, hint: hint)
570
668
 
571
- typing.add_typing(node, lhs_type, context)
669
+ constr.add_typing(node, type: type)
670
+
671
+ else
672
+ Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
673
+
674
+ _, constr = synthesize(rhs)
675
+ constr.add_typing(node, type: AST::Builtin.any_type)
572
676
  end
573
677
  end
574
678
 
@@ -597,7 +701,7 @@ module Steep
597
701
  block_body: nil,
598
702
  topdown_hint: true)
599
703
 
600
- typing.add_typing node, return_type, context
704
+ add_typing node, type: return_type
601
705
  else
602
706
  fallback_to_any node do
603
707
  Errors::UnexpectedSuper.new(node: node, method: method_context.name)
@@ -619,49 +723,64 @@ module Steep
619
723
  end
620
724
 
621
725
  when :def
622
- new = for_new_method(node.children[0],
623
- node,
624
- args: node.children[1].children,
625
- self_type: module_context&.instance_type,
626
- definition: module_context&.instance_definition)
627
-
628
- each_child_node(node.children[1]) do |arg|
629
- new.synthesize(arg)
630
- end
631
-
632
- if node.children[2]
633
- return_type = expand_alias(new.method_context&.return_type)
634
- if return_type && !return_type.is_a?(AST::Types::Void)
635
- new.check(node.children[2], return_type) do |_, actual_type, result|
636
- typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
637
- expected: new.method_context&.return_type,
638
- actual: actual_type,
639
- result: result))
640
- end
641
- else
642
- new.synthesize(node.children[2])
726
+ yield_self do
727
+ name, args_node, body_node = node.children
728
+
729
+ new = for_new_method(name,
730
+ node,
731
+ args: args_node.children,
732
+ self_type: module_context&.instance_type,
733
+ definition: module_context&.instance_definition)
734
+ new.typing.add_context_for_node(node, context: new.context)
735
+ new.typing.add_context_for_body(node, context: new.context)
736
+
737
+ each_child_node(args_node) do |arg|
738
+ new.synthesize(arg)
643
739
  end
644
- else
645
- return_type = expand_alias(new.method_context&.return_type)
646
- if return_type && !return_type.is_a?(AST::Types::Void)
647
- result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
648
- if result.failure?
649
- typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
650
- expected: new.method_context&.return_type,
651
- actual: AST::Builtin.nil_type,
652
- result: result))
653
- end
740
+
741
+ body_pair = if body_node
742
+ return_type = expand_alias(new.method_context&.return_type)
743
+ if return_type && !return_type.is_a?(AST::Types::Void)
744
+ new.check(body_node, return_type) do |_, actual_type, result|
745
+ typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
746
+ expected: new.method_context&.return_type,
747
+ actual: actual_type,
748
+ result: result))
749
+ end
750
+ else
751
+ new.synthesize(body_node)
752
+ end
753
+ else
754
+ return_type = expand_alias(new.method_context&.return_type)
755
+ if return_type && !return_type.is_a?(AST::Types::Void)
756
+ result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
757
+ if result.failure?
758
+ typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
759
+ expected: new.method_context&.return_type,
760
+ actual: AST::Builtin.nil_type,
761
+ result: result))
762
+ end
763
+ end
764
+
765
+ Pair.new(type: AST::Builtin.nil_type, constr: new)
766
+ end
767
+
768
+ if body_node
769
+ begin_pos = body_node.loc.expression.end_pos
770
+ end_pos = node.loc.end.begin_pos
771
+
772
+ typing.add_context(begin_pos..end_pos, context: body_pair.context)
654
773
  end
655
- end
656
774
 
657
- if module_context
658
- module_context.defined_instance_methods << node.children[0]
659
- end
775
+ if module_context
776
+ module_context.defined_instance_methods << node.children[0]
777
+ end
660
778
 
661
- typing.add_typing(node, AST::Builtin.any_type, new.context)
779
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
780
+ end
662
781
 
663
782
  when :defs
664
- synthesize(node.children[0]).tap do |self_type|
783
+ synthesize(node.children[0]).type.tap do |self_type|
665
784
  self_type = expand_self(self_type)
666
785
  definition = case self_type
667
786
  when AST::Types::Name::Instance
@@ -677,6 +796,8 @@ module Steep
677
796
  args: node.children[2].children,
678
797
  self_type: self_type,
679
798
  definition: definition)
799
+ new.typing.add_context_for_node(node, context: new.context)
800
+ new.typing.add_context_for_body(node, context: new.context)
680
801
 
681
802
  each_child_node(node.children[2]) do |arg|
682
803
  new.synthesize(arg)
@@ -703,13 +824,20 @@ module Steep
703
824
  end
704
825
  end
705
826
 
706
- typing.add_typing(node, AST::Builtin::Symbol.instance_type, context)
827
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
707
828
 
708
829
  when :return
709
830
  yield_self do
710
831
  if node.children.size > 0
832
+ method_return_type = expand_alias(method_context&.return_type)
833
+
711
834
  return_types = node.children.map do |value|
712
- synthesize(value)
835
+ synthesize(value,
836
+ hint: if method_return_type.is_a?(AST::Types::Void)
837
+ nil
838
+ else
839
+ method_return_type
840
+ end).type
713
841
  end
714
842
 
715
843
  value_type = if return_types.size == 1
@@ -718,9 +846,9 @@ module Steep
718
846
  AST::Builtin::Array.instance_type(union_type(*return_types))
719
847
  end
720
848
 
721
- if (ret_type = expand_alias(method_context&.return_type))
722
- unless ret_type.is_a?(AST::Types::Void)
723
- result = check_relation(sub_type: value_type, super_type: ret_type)
849
+ if method_return_type
850
+ unless method_return_type.is_a?(AST::Types::Void)
851
+ result = check_relation(sub_type: value_type, super_type: method_return_type)
724
852
 
725
853
  if result.failure?
726
854
  typing.add_error(Errors::ReturnTypeMismatch.new(node: node,
@@ -732,7 +860,7 @@ module Steep
732
860
  end
733
861
  end
734
862
 
735
- typing.add_typing(node, AST::Builtin.any_type, context)
863
+ add_typing(node, type: AST::Builtin.bottom_type)
736
864
  end
737
865
 
738
866
  when :break
@@ -758,7 +886,7 @@ module Steep
758
886
  typing.add_error Errors::UnexpectedJump.new(node: node)
759
887
  end
760
888
 
761
- typing.add_typing(node, AST::Builtin.any_type, context)
889
+ add_typing(node, type: AST::Builtin.bottom_type)
762
890
 
763
891
  when :next
764
892
  value = node.children[0]
@@ -783,77 +911,99 @@ module Steep
783
911
  typing.add_error Errors::UnexpectedJump.new(node: node)
784
912
  end
785
913
 
786
- typing.add_typing(node, AST::Builtin.any_type, context)
914
+ add_typing(node, type: AST::Builtin.bottom_type)
787
915
 
788
916
  when :retry
789
917
  unless break_context
790
918
  typing.add_error Errors::UnexpectedJump.new(node: node)
791
919
  end
792
- typing.add_typing(node, AST::Builtin.any_type, context)
920
+ add_typing(node, type: AST::Builtin.bottom_type)
793
921
 
794
922
  when :arg, :kwarg, :procarg0
795
923
  yield_self do
796
924
  var = node.children[0]
797
- type = type_env.get(lvar: var.name) do
798
- fallback_to_any node
925
+ type = context.lvar_env[var.name]
926
+ unless type
927
+ type = AST::Builtin.any_type
928
+ Steep.logger.error { "Unknown arg type: #{node}" }
799
929
  end
800
- typing.add_typing(node, type, context)
930
+ add_typing(node, type: type)
801
931
  end
802
932
 
803
933
  when :optarg, :kwoptarg
804
934
  yield_self do
805
935
  var = node.children[0]
806
936
  rhs = node.children[1]
807
- type_assignment(var, rhs, node, hint: hint)
937
+
938
+ type = context.lvar_env[var.name]
939
+
940
+ node_type, constr = synthesize(rhs, hint: type)
941
+
942
+ constr_ = constr.update_lvar_env do |env|
943
+ env.assign(var.name, node: node, type: node_type) do |declared_type, type, result|
944
+ typing.add_error(
945
+ Errors::IncompatibleAssignment.new(node: node,
946
+ lhs_type: declared_type,
947
+ rhs_type: type,
948
+ result: result)
949
+ )
950
+ end
951
+ end
952
+
953
+ add_typing(node, type: constr_.context.lvar_env[var.name], constr: constr_)
808
954
  end
809
955
 
810
956
  when :restarg
811
957
  yield_self do
812
958
  var = node.children[0]
813
- type = type_env.get(lvar: var.name) do
959
+ type = context.lvar_env[var.name]
960
+ unless type
961
+ Steep.logger.error { "Unknown variable: #{node}" }
814
962
  typing.add_error Errors::FallbackAny.new(node: node)
815
- AST::Builtin::Array.instance_type(AST::Builtin.any_type)
963
+ type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
816
964
  end
817
965
 
818
- typing.add_typing(node, type, context)
966
+ add_typing(node, type: type)
819
967
  end
820
968
 
821
969
  when :kwrestarg
822
970
  yield_self do
823
971
  var = node.children[0]
824
- type = type_env.get(lvar: var.name) do
972
+ type = context.lvar_env[var.name]
973
+ unless type
974
+ Steep.logger.error { "Unknown variable: #{node}" }
825
975
  typing.add_error Errors::FallbackAny.new(node: node)
826
- AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
976
+ type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
827
977
  end
828
978
 
829
- typing.add_typing(node, type, context)
979
+ add_typing(node, type: type)
830
980
  end
831
981
 
832
982
  when :float
833
- typing.add_typing(node, AST::Builtin::Float.instance_type, context)
983
+ add_typing(node, type: AST::Builtin::Float.instance_type)
834
984
 
835
985
  when :nil
836
- typing.add_typing(node, AST::Builtin.nil_type, context)
986
+ add_typing(node, type: AST::Builtin.nil_type)
837
987
 
838
988
  when :int
839
989
  yield_self do
840
- literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
990
+ literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_) }
841
991
 
842
992
  if literal_type
843
- typing.add_typing(node, literal_type, context)
993
+ add_typing(node, type: literal_type)
844
994
  else
845
- typing.add_typing(node, AST::Builtin::Integer.instance_type, context)
995
+ add_typing(node, type: AST::Builtin::Integer.instance_type)
846
996
  end
847
997
  end
848
998
 
849
999
  when :sym
850
1000
  yield_self do
851
- literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
1001
+ literal_type = expand_alias(hint) {|hint| test_literal_type(node.children[0], hint) }
852
1002
 
853
1003
  if literal_type
854
- typing.add_typing(node, literal_type, context)
1004
+ add_typing(node, type: literal_type)
855
1005
  else
856
- typing.add_typing(node, AST::Builtin::Symbol.instance_type, context)
1006
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
857
1007
  end
858
1008
  end
859
1009
 
@@ -862,14 +1012,14 @@ module Steep
862
1012
  literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
863
1013
 
864
1014
  if literal_type
865
- typing.add_typing(node, literal_type, context)
1015
+ add_typing(node, type: literal_type)
866
1016
  else
867
- typing.add_typing(node, AST::Builtin::String.instance_type, context)
1017
+ add_typing(node, type: AST::Builtin::String.instance_type)
868
1018
  end
869
1019
  end
870
1020
 
871
1021
  when :true, :false
872
- typing.add_typing(node, AST::Types::Boolean.new, context)
1022
+ add_typing(node, type: AST::Types::Boolean.new)
873
1023
 
874
1024
  when :hash
875
1025
  yield_self do
@@ -887,14 +1037,14 @@ module Steep
887
1037
  case child.type
888
1038
  when :pair
889
1039
  key, value = child.children
890
- key_types << synthesize(key).yield_self do |type|
1040
+ key_types << synthesize(key).type.yield_self do |type|
891
1041
  select_super_type(type, key_hint)
892
1042
  end
893
- value_types << synthesize(value).yield_self do |type|
1043
+ value_types << synthesize(value).type.yield_self do |type|
894
1044
  select_super_type(type, value_hint)
895
1045
  end
896
1046
  when :kwsplat
897
- expand_alias(synthesize(child.children[0])) do |splat_type, original_type|
1047
+ expand_alias(synthesize(child.children[0]).type) do |splat_type, original_type|
898
1048
  if AST::Builtin::Hash.instance_type?(splat_type)
899
1049
  key_types << splat_type.args[0]
900
1050
  value_types << splat_type.args[1]
@@ -916,7 +1066,7 @@ module Steep
916
1066
  typing.add_error Errors::FallbackAny.new(node: node)
917
1067
  end
918
1068
 
919
- typing.add_typing(node, AST::Builtin::Hash.instance_type(key_type, value_type), context)
1069
+ add_typing(node, type: AST::Builtin::Hash.instance_type(key_type, value_type))
920
1070
  end
921
1071
 
922
1072
  when :dstr, :xstr
@@ -924,18 +1074,21 @@ module Steep
924
1074
  synthesize(child)
925
1075
  end
926
1076
 
927
- typing.add_typing(node, AST::Builtin::String.instance_type, context)
1077
+ add_typing(node, type: AST::Builtin::String.instance_type)
928
1078
 
929
1079
  when :dsym
930
1080
  each_child_node(node) do |child|
931
1081
  synthesize(child)
932
1082
  end
933
1083
 
934
- typing.add_typing(node, AST::Builtin::Symbol.instance_type, context)
1084
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
935
1085
 
936
1086
  when :class
937
1087
  yield_self do
938
1088
  for_class(node).tap do |constructor|
1089
+ constructor.typing.add_context_for_node(node, context: constructor.context)
1090
+ constructor.typing.add_context_for_body(node, context: constructor.context)
1091
+
939
1092
  constructor.synthesize(node.children[2]) if node.children[2]
940
1093
 
941
1094
  if constructor.module_context&.implement_name && !namespace_module?(node)
@@ -943,12 +1096,15 @@ module Steep
943
1096
  end
944
1097
  end
945
1098
 
946
- typing.add_typing(node, AST::Builtin.nil_type, context)
1099
+ add_typing(node, type: AST::Builtin.nil_type)
947
1100
  end
948
1101
 
949
1102
  when :module
950
1103
  yield_self do
951
1104
  for_module(node).yield_self do |constructor|
1105
+ constructor.typing.add_context_for_node(node, context: constructor.context)
1106
+ constructor.typing.add_context_for_body(node, context: constructor.context)
1107
+
952
1108
  constructor.synthesize(node.children[1]) if node.children[1]
953
1109
 
954
1110
  if constructor.module_context&.implement_name && !namespace_module?(node)
@@ -956,19 +1112,20 @@ module Steep
956
1112
  end
957
1113
  end
958
1114
 
959
- typing.add_typing(node, AST::Builtin.nil_type, context)
1115
+ add_typing(node, type: AST::Builtin.nil_type)
960
1116
  end
961
1117
 
962
1118
  when :self
963
- typing.add_typing node, AST::Types::Self.new, context
1119
+ add_typing node, type: AST::Types::Self.new
964
1120
 
965
1121
  when :const
966
1122
  const_name = Names::Module.from_node(node)
1123
+
967
1124
  if const_name
968
1125
  type = type_env.get(const: const_name) do
969
1126
  fallback_to_any node
970
1127
  end
971
- typing.add_typing node, type, context
1128
+ add_typing node, type: type
972
1129
  else
973
1130
  fallback_to_any node
974
1131
  end
@@ -977,7 +1134,8 @@ module Steep
977
1134
  yield_self do
978
1135
  const_name = Names::Module.from_node(node)
979
1136
  if const_name
980
- value_type = synthesize(node.children.last)
1137
+ const_type = type_env.get(const: const_name) {}
1138
+ value_type = synthesize(node.children.last, hint: const_type).type
981
1139
  type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
982
1140
  case error
983
1141
  when Subtyping::Result::Failure
@@ -991,9 +1149,9 @@ module Steep
991
1149
  end
992
1150
  end
993
1151
 
994
- typing.add_typing(node, type, context)
1152
+ add_typing(node, type: type)
995
1153
  else
996
- synthesize(node.children.last)
1154
+ synthesize(node.children.last).type
997
1155
  fallback_to_any(node)
998
1156
  end
999
1157
  end
@@ -1013,7 +1171,7 @@ module Steep
1013
1171
  end
1014
1172
  end
1015
1173
 
1016
- typing.add_typing(node, block_type.type.return_type, context)
1174
+ add_typing(node, type: block_type.type.return_type)
1017
1175
  else
1018
1176
  typing.add_error(Errors::UnexpectedYield.new(node: node))
1019
1177
  fallback_to_any node
@@ -1027,16 +1185,9 @@ module Steep
1027
1185
  if method_context&.method
1028
1186
  if method_context.super_method
1029
1187
  types = method_context.super_method.method_types.map {|method_type|
1030
- case method_type
1031
- when Ruby::Signature::MethodType
1032
- checker.factory.method_type(method_type, self_type: self_type).return_type
1033
- when :any
1034
- AST::Builtin.any_type
1035
- else
1036
- raise "Unexpected method_type: #{method_type.inspect}"
1037
- end
1188
+ checker.factory.method_type(method_type, self_type: self_type).return_type
1038
1189
  }
1039
- typing.add_typing(node, union_type(*types), context)
1190
+ add_typing(node, type: union_type(*types))
1040
1191
  else
1041
1192
  typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
1042
1193
  fallback_to_any node
@@ -1058,7 +1209,7 @@ module Steep
1058
1209
  end
1059
1210
  end
1060
1211
 
1061
- typing.add_typing(node, array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type), context)
1212
+ add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
1062
1213
  else
1063
1214
  is_tuple = nil
1064
1215
 
@@ -1068,7 +1219,7 @@ module Steep
1068
1219
  is_tuple &&= node.children.size >= hint.types.size
1069
1220
  is_tuple &&= hint.types.map.with_index do |child_type, index|
1070
1221
  child_node = node.children[index]
1071
- [synthesize(child_node, hint: child_type), child_type]
1222
+ [synthesize(child_node, hint: child_type).type, child_type]
1072
1223
  end.all? do |node_type, hint_type|
1073
1224
  result = check_relation(sub_type: node_type, super_type: hint_type)
1074
1225
  result.success?
@@ -1085,7 +1236,7 @@ module Steep
1085
1236
  element_types = node.children.flat_map do |e|
1086
1237
  if e.type == :splat
1087
1238
  Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
1088
- synthesize(e.children.first).yield_self do |type|
1239
+ synthesize(e.children.first).type.yield_self do |type|
1089
1240
  expand_alias(type) do |ty|
1090
1241
  case ty
1091
1242
  when AST::Types::Union
@@ -1105,155 +1256,237 @@ module Steep
1105
1256
  end
1106
1257
  end
1107
1258
  else
1108
- [select_super_type(synthesize(e), element_hint)]
1259
+ [select_super_type(synthesize(e).type, element_hint)]
1109
1260
  end
1110
1261
  end
1111
1262
  array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
1112
1263
  end
1113
1264
 
1114
- typing.add_typing(node, array_type, context)
1265
+ add_typing(node, type: array_type)
1115
1266
  end
1116
1267
  end
1117
1268
 
1118
1269
  when :and
1119
1270
  yield_self do
1120
1271
  left, right = node.children
1121
- left_type = synthesize(left)
1272
+ logic = TypeInference::Logic.new(subtyping: checker)
1273
+ truthy, falsey = logic.nodes(node: left)
1122
1274
 
1123
- truthy_vars = TypeConstruction.truthy_variables(left)
1124
- right_type, right_env = for_branch(right, truthy_vars: truthy_vars).yield_self do |constructor|
1125
- type = constructor.synthesize(right)
1126
- [type, constructor.type_env]
1127
- end
1275
+ left_type, constr = synthesize(left)
1276
+ truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1277
+ falsey_vars: falsey.vars,
1278
+ lvar_env: constr.context.lvar_env)
1128
1279
 
1129
- type_env.join!([right_env, TypeInference::TypeEnv.new(subtyping: checker,
1130
- const_env: nil)])
1280
+ right_type, constr = constr.update_lvar_env { truthy_env }.for_branch(right).synthesize(right)
1131
1281
 
1132
- if left_type.is_a?(AST::Types::Boolean)
1133
- typing.add_typing(node, union_type(left_type, right_type), context)
1134
- else
1135
- typing.add_typing(node, union_type(right_type, AST::Builtin.nil_type), context)
1136
- end
1282
+ type = if left_type.is_a?(AST::Types::Boolean)
1283
+ union_type(left_type, right_type)
1284
+ else
1285
+ union_type(right_type, AST::Builtin.nil_type)
1286
+ end
1287
+
1288
+ add_typing(node,
1289
+ type: type,
1290
+ constr: constr.update_lvar_env do
1291
+ if right_type.is_a?(AST::Types::Bot)
1292
+ falsey_env
1293
+ else
1294
+ context.lvar_env.join(falsey_env, constr.context.lvar_env)
1295
+ end
1296
+ end)
1137
1297
  end
1138
1298
 
1139
1299
  when :or
1140
1300
  yield_self do
1141
- c1, c2 = node.children
1142
- t1 = synthesize(c1, hint: hint)
1143
- t2 = synthesize(c2, hint: unwrap(t1))
1144
- type = union_type(unwrap(t1), t2)
1145
- typing.add_typing(node, type, context)
1301
+ left, right = node.children
1302
+ logic = TypeInference::Logic.new(subtyping: checker)
1303
+ truthy, falsey = logic.nodes(node: left)
1304
+
1305
+ left_type, constr = synthesize(left, hint: hint)
1306
+ truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1307
+ falsey_vars: falsey.vars,
1308
+ lvar_env: constr.context.lvar_env)
1309
+ left_type_t, _ = logic.partition_union(left_type)
1310
+
1311
+ right_type, constr = constr.update_lvar_env { falsey_env }.for_branch(right).synthesize(right, hint: left_type_t)
1312
+
1313
+ type = union_type(left_type_t, right_type)
1314
+
1315
+ add_typing(node,
1316
+ type: type,
1317
+ constr: constr.update_lvar_env do
1318
+ if right_type.is_a?(AST::Types::Bot)
1319
+ truthy_env
1320
+ else
1321
+ context.lvar_env.join(truthy_env, constr.context.lvar_env)
1322
+ end
1323
+ end)
1146
1324
  end
1147
1325
 
1148
1326
  when :if
1149
1327
  cond, true_clause, false_clause = node.children
1150
- synthesize cond
1151
1328
 
1152
- truthy_vars = TypeConstruction.truthy_variables(cond)
1329
+ cond_type, constr = synthesize(cond)
1330
+ logic = TypeInference::Logic.new(subtyping: checker)
1331
+
1332
+ truthys, falseys = logic.nodes(node: cond)
1333
+ truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
1334
+ falsey_vars: falseys.vars,
1335
+ lvar_env: constr.context.lvar_env)
1153
1336
 
1154
1337
  if true_clause
1155
- true_type, true_env = for_branch(true_clause, truthy_vars: truthy_vars).yield_self do |constructor|
1156
- type = constructor.synthesize(true_clause, hint: hint)
1157
- [type, constructor.type_env]
1158
- end
1338
+ true_pair = constr
1339
+ .update_lvar_env { truthy_env }
1340
+ .for_branch(true_clause)
1341
+ .tap {|constr| typing.add_context_for_node(true_clause, context: constr.context) }
1342
+ .synthesize(true_clause, hint: hint)
1159
1343
  end
1344
+
1160
1345
  if false_clause
1161
- false_type, false_env = for_branch(false_clause).yield_self do |constructor|
1162
- type = constructor.synthesize(false_clause, hint: hint)
1163
- [type, constructor.type_env]
1346
+ false_pair = constr
1347
+ .update_lvar_env { falsey_env }
1348
+ .for_branch(false_clause)
1349
+ .tap {|constr| typing.add_context_for_node(false_clause, context: constr.context) }
1350
+ .synthesize(false_clause, hint: hint)
1351
+ end
1352
+
1353
+ constr = constr.update_lvar_env do |env|
1354
+ envs = []
1355
+
1356
+ if true_pair
1357
+ unless true_pair.type.is_a?(AST::Types::Bot)
1358
+ envs << true_pair.context.lvar_env
1359
+ end
1360
+ else
1361
+ envs << truthy_env
1362
+ end
1363
+
1364
+ if false_pair
1365
+ unless false_pair.type.is_a?(AST::Types::Bot)
1366
+ envs << false_pair.context.lvar_env
1367
+ end
1368
+ else
1369
+ envs << falsey_env
1164
1370
  end
1371
+
1372
+ env.join(*envs)
1165
1373
  end
1166
1374
 
1167
- type_env.join!([true_env, false_env].compact)
1168
- typing.add_typing(node, union_type(true_type, false_type), context)
1375
+ add_typing(node,
1376
+ type: union_type(true_pair&.type || AST::Builtin.nil_type,
1377
+ false_pair&.type || AST::Builtin.nil_type),
1378
+ constr: constr)
1169
1379
 
1170
1380
  when :case
1171
1381
  yield_self do
1172
- cond, *whens = node.children
1382
+ cond, *whens, els = node.children
1383
+
1384
+ constr = self
1173
1385
 
1174
1386
  if cond
1175
- cond_type = expand_alias(synthesize(cond))
1387
+ cond_type, constr = synthesize(cond)
1388
+ cond_type = expand_alias(cond_type)
1176
1389
  if cond_type.is_a?(AST::Types::Union)
1177
1390
  var_names = TypeConstruction.value_variables(cond)
1178
1391
  var_types = cond_type.types.dup
1179
1392
  end
1180
1393
  end
1181
1394
 
1182
- pairs = whens.each.with_object([]) do |clause, pairs|
1183
- if clause&.type == :when
1184
- test_types = clause.children.take(clause.children.size - 1).map do |child|
1185
- expand_alias(synthesize(child, hint: hint))
1186
- end
1395
+ branch_pairs = []
1187
1396
 
1188
- if (body = clause.children.last)
1189
- if var_names && var_types && test_types.all? {|type| type.is_a?(AST::Types::Name::Class)}
1190
- var_types_in_body = test_types.flat_map {|test_type|
1191
- filtered_types = var_types.select {|var_type| var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name}
1192
- if filtered_types.empty?
1193
- to_instance_type(test_type)
1194
- else
1195
- filtered_types
1196
- end
1197
- }
1198
- var_types.reject! {|type|
1199
- var_types_in_body.any? {|test_type|
1200
- type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1201
- }
1202
- }
1203
-
1204
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1205
- hash[var_name] = union_type(*var_types_in_body)
1397
+ whens.each do |clause|
1398
+ *tests, body = clause.children
1399
+
1400
+ test_types = []
1401
+ clause_constr = constr
1402
+
1403
+ tests.each do |test|
1404
+ type, clause_constr = synthesize(test)
1405
+ test_types << expand_alias(type)
1406
+ end
1407
+
1408
+ if body
1409
+ if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Class) }
1410
+ var_types_in_body = test_types.flat_map do |test_type|
1411
+ filtered_types = var_types.select do |var_type|
1412
+ var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
1413
+ end
1414
+ if filtered_types.empty?
1415
+ to_instance_type(test_type)
1416
+ else
1417
+ filtered_types
1206
1418
  end
1207
- else
1208
- type_case_override = nil
1209
1419
  end
1210
1420
 
1211
- for_branch(body, type_case_override: type_case_override).yield_self do |body_construction|
1212
- type = body_construction.synthesize(body, hint: hint)
1213
- pairs << [type, body_construction.type_env]
1421
+ var_types.reject! do |type|
1422
+ var_types_in_body.any? do |test_type|
1423
+ type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1424
+ end
1425
+ end
1426
+
1427
+ var_type_in_body = union_type(*var_types_in_body)
1428
+ type_case_override = var_names.each.with_object({}) do |var_name, hash|
1429
+ hash[var_name] = var_type_in_body
1214
1430
  end
1431
+
1432
+ branch_pairs << clause_constr
1433
+ .for_branch(body, type_case_override: type_case_override)
1434
+ .synthesize(body, hint: hint)
1215
1435
  else
1216
- pairs << [AST::Builtin.nil_type, nil]
1436
+ branch_pairs << clause_constr.synthesize(body, hint: hint)
1217
1437
  end
1218
1438
  else
1219
- if clause
1220
- if var_types
1221
- if !var_types.empty?
1222
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1223
- hash[var_name] = union_type(*var_types)
1224
- end
1225
- var_types.clear
1226
- else
1227
- typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1228
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1229
- hash[var_name] = AST::Builtin.any_type
1230
- end
1231
- end
1232
- end
1439
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1440
+ end
1441
+ end
1233
1442
 
1234
- for_branch(clause, type_case_override: type_case_override).yield_self do |body_construction|
1235
- type = body_construction.synthesize(clause, hint: hint)
1236
- pairs << [type, body_construction.type_env]
1237
- end
1443
+ if els
1444
+ if var_names && var_types
1445
+ if var_types.empty?
1446
+ typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1238
1447
  end
1448
+
1449
+ else_override = var_names.each.with_object({}) do |var_name, hash|
1450
+ hash[var_name] = unless var_types.empty?
1451
+ union_type(*var_types)
1452
+ else
1453
+ AST::Builtin.any_type
1454
+ end
1455
+ end
1456
+ branch_pairs << constr
1457
+ .for_branch(els, type_case_override: else_override)
1458
+ .synthesize(els, hint: hint)
1459
+ else
1460
+ branch_pairs << constr.synthesize(els, hint: hint)
1239
1461
  end
1240
1462
  end
1241
1463
 
1242
- types = pairs.map(&:first)
1243
- envs = pairs.map(&:last)
1464
+ types = branch_pairs.map(&:type)
1465
+ constrs = branch_pairs.map(&:constr)
1244
1466
 
1245
- unless var_types&.empty? || whens.last
1467
+ unless var_types&.empty? || els
1246
1468
  types.push AST::Builtin.nil_type
1247
1469
  end
1248
1470
 
1249
- type_env.join!(envs.compact)
1250
- typing.add_typing(node, union_type(*types), context)
1471
+ constr = constr.update_lvar_env do |env|
1472
+ env.join(*constrs.map {|c| c.context.lvar_env })
1473
+ end
1474
+
1475
+ add_typing(node, type: union_type(*types), constr: constr)
1251
1476
  end
1252
1477
 
1253
1478
  when :rescue
1254
1479
  yield_self do
1255
1480
  body, *resbodies, else_node = node.children
1256
- body_type = synthesize(body) if body
1481
+ body_pair = synthesize(body) if body
1482
+
1483
+ body_constr = if body_pair
1484
+ self.update_lvar_env do |env|
1485
+ env.join(env, body_pair.context.lvar_env)
1486
+ end
1487
+ else
1488
+ self
1489
+ end
1257
1490
 
1258
1491
  resbody_pairs = resbodies.map do |resbody|
1259
1492
  exn_classes, assignment, body = resbody.children
@@ -1261,7 +1494,7 @@ module Steep
1261
1494
  if exn_classes
1262
1495
  case exn_classes.type
1263
1496
  when :array
1264
- exn_types = exn_classes.children.map {|child| synthesize(child)}
1497
+ exn_types = exn_classes.children.map {|child| synthesize(child).type }
1265
1498
  else
1266
1499
  Steep.logger.error "Unexpected exception list: #{exn_classes.type}"
1267
1500
  end
@@ -1294,27 +1527,28 @@ module Steep
1294
1527
  type_override[var_name] = AST::Builtin.any_type
1295
1528
  end
1296
1529
 
1297
- resbody_construction = for_branch(resbody, type_case_override: type_override)
1530
+ resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
1298
1531
 
1299
- type = if body
1300
- resbody_construction.synthesize(body)
1301
- else
1302
- AST::Builtin.nil_type
1303
- end
1304
- [type, resbody_construction.type_env]
1532
+ if body
1533
+ resbody_construction.synthesize(body)
1534
+ else
1535
+ Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
1536
+ end
1305
1537
  end
1306
- resbody_types, resbody_envs = resbody_pairs.transpose
1538
+
1539
+ resbody_types = resbody_pairs.map(&:type)
1540
+ resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
1307
1541
 
1308
1542
  if else_node
1309
- else_construction = for_branch(else_node)
1310
- else_type = else_construction.synthesize(else_node)
1311
- else_env = else_construction.type_env
1543
+ else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
1544
+ add_typing(node,
1545
+ type: union_type(*[else_pair.type, *resbody_types].compact),
1546
+ constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
1547
+ else
1548
+ add_typing(node,
1549
+ type: union_type(*[body_pair&.type, *resbody_types].compact),
1550
+ constr: update_lvar_env {|env| env.join(*resbody_envs, (body_pair&.constr || self).context.lvar_env) })
1312
1551
  end
1313
-
1314
- type_env.join!([*resbody_envs, else_env].compact)
1315
-
1316
- types = [body_type, *resbody_types, else_type].compact
1317
- typing.add_typing(node, union_type(*types), context)
1318
1552
  end
1319
1553
 
1320
1554
  when :resbody
@@ -1322,66 +1556,105 @@ module Steep
1322
1556
  klasses, asgn, body = node.children
1323
1557
  synthesize(klasses) if klasses
1324
1558
  synthesize(asgn) if asgn
1325
- body_type = synthesize(body) if body
1326
- typing.add_typing(node, body_type, context)
1559
+ body_type = synthesize(body).type if body
1560
+ add_typing(node, type: body_type)
1327
1561
  end
1328
1562
 
1329
1563
  when :ensure
1330
1564
  yield_self do
1331
1565
  body, ensure_body = node.children
1332
- body_type = synthesize(body) if body
1566
+ body_type = synthesize(body).type if body
1333
1567
  synthesize(ensure_body) if ensure_body
1334
- typing.add_typing(node, union_type(body_type), context)
1568
+ add_typing(node, type: union_type(body_type))
1335
1569
  end
1336
1570
 
1337
1571
  when :masgn
1338
1572
  type_masgn(node)
1339
1573
 
1340
- when :while, :while_post, :until, :until_post
1574
+ when :while, :until
1341
1575
  yield_self do
1342
1576
  cond, body = node.children
1577
+ _, constr = synthesize(cond)
1343
1578
 
1344
- synthesize(cond)
1345
- truthy_vars = node.type == :while ? TypeConstruction.truthy_variables(cond) : Set.new
1579
+ logic = TypeInference::Logic.new(subtyping: checker)
1580
+ truthy, falsey = logic.nodes(node: cond)
1581
+
1582
+ case node.type
1583
+ when :while
1584
+ body_env, exit_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1585
+ when :until
1586
+ exit_env, body_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1587
+ end
1346
1588
 
1347
1589
  if body
1348
- for_loop = for_branch(body,
1349
- truthy_vars: truthy_vars,
1350
- break_context: TypeInference::Context::BreakContext.new(
1351
- break_type: nil,
1352
- next_type: nil
1353
- ))
1354
- for_loop.synthesize(body)
1355
- type_env.join!([for_loop.type_env])
1590
+ _, body_constr = constr
1591
+ .update_lvar_env { body_env.pin_assignments }
1592
+ .for_branch(body,
1593
+ break_context: TypeInference::Context::BreakContext.new(
1594
+ break_type: nil,
1595
+ next_type: nil
1596
+ ))
1597
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1598
+ .synthesize(body)
1599
+
1600
+ constr = constr.update_lvar_env {|env| env.join(exit_env, body_constr.context.lvar_env) }
1601
+ else
1602
+ constr = constr.update_lvar_env { exit_env }
1356
1603
  end
1357
1604
 
1358
- typing.add_typing(node, AST::Builtin.any_type, context)
1605
+ add_typing(node, type: AST::Builtin.nil_type, constr: constr)
1606
+ end
1607
+
1608
+ when :while_post, :until_post
1609
+ yield_self do
1610
+ cond, body = node.children
1611
+
1612
+ cond_pair = synthesize(cond)
1613
+
1614
+ if body
1615
+ for_loop = cond_pair.constr
1616
+ .update_lvar_env {|env| env.pin_assignments }
1617
+ .for_branch(body,
1618
+ break_context: TypeInference::Context::BreakContext.new(
1619
+ break_type: nil,
1620
+ next_type: nil
1621
+ ))
1622
+
1623
+ typing.add_context_for_node(body, context: for_loop.context)
1624
+ body_pair = for_loop.synthesize(body)
1625
+
1626
+ constr = cond_pair.constr.update_lvar_env {|env| env.join(env, body_pair.context.lvar_env) }
1627
+
1628
+ add_typing(node, type: AST::Builtin.nil_type, constr: constr)
1629
+ else
1630
+ add_typing(node, type: AST::Builtin.nil_type, constr: cond_pair.constr)
1631
+ end
1359
1632
  end
1360
1633
 
1361
1634
  when :irange, :erange
1362
- types = node.children.map {|n| synthesize(n)}
1635
+ types = node.children.map {|n| synthesize(n).type }
1363
1636
  type = AST::Builtin::Range.instance_type(union_type(*types))
1364
- typing.add_typing(node, type, context)
1637
+ add_typing(node, type: type)
1365
1638
 
1366
1639
  when :regexp
1367
1640
  each_child_node(node) do |child|
1368
1641
  synthesize(child)
1369
1642
  end
1370
1643
 
1371
- typing.add_typing(node, AST::Builtin::Regexp.instance_type, context)
1644
+ add_typing(node, type: AST::Builtin::Regexp.instance_type)
1372
1645
 
1373
1646
  when :regopt
1374
1647
  # ignore
1375
- typing.add_typing(node, AST::Builtin.any_type, context)
1648
+ add_typing(node, type: AST::Builtin.any_type)
1376
1649
 
1377
1650
  when :nth_ref, :back_ref
1378
- typing.add_typing(node, AST::Builtin::String.instance_type, context)
1651
+ add_typing(node, type: AST::Builtin::String.instance_type)
1379
1652
 
1380
1653
  when :or_asgn, :and_asgn
1381
1654
  yield_self do
1382
1655
  _, rhs = node.children
1383
- rhs_type = synthesize(rhs)
1384
- typing.add_typing(node, rhs_type, context)
1656
+ rhs_type = synthesize(rhs).type
1657
+ add_typing(node, type: rhs_type)
1385
1658
  end
1386
1659
 
1387
1660
  when :defined?
@@ -1389,7 +1662,7 @@ module Steep
1389
1662
  synthesize(child)
1390
1663
  end
1391
1664
 
1392
- typing.add_typing(node, AST::Builtin.any_type, context)
1665
+ add_typing(node, type: AST::Builtin.any_type)
1393
1666
 
1394
1667
  when :gvasgn
1395
1668
  yield_self do
@@ -1415,7 +1688,7 @@ module Steep
1415
1688
  typing.add_error Errors::FallbackAny.new(node: node)
1416
1689
  end
1417
1690
 
1418
- typing.add_typing(node, type, context)
1691
+ add_typing(node, type: type)
1419
1692
  end
1420
1693
 
1421
1694
  when :block_pass
@@ -1443,9 +1716,9 @@ module Steep
1443
1716
  end
1444
1717
  end
1445
1718
 
1446
- type ||= synthesize(node.children[0], hint: hint)
1719
+ type ||= synthesize(node.children[0], hint: hint).type
1447
1720
 
1448
- typing.add_typing node, type, context
1721
+ add_typing node, type: type
1449
1722
  end
1450
1723
 
1451
1724
  when :blockarg
@@ -1454,7 +1727,7 @@ module Steep
1454
1727
  synthesize(child)
1455
1728
  end
1456
1729
 
1457
- typing.add_typing node, AST::Builtin.any_type, context
1730
+ add_typing node, type: AST::Builtin.any_type
1458
1731
  end
1459
1732
 
1460
1733
  when :splat, :sclass, :alias
@@ -1465,55 +1738,35 @@ module Steep
1465
1738
  synthesize(child)
1466
1739
  end
1467
1740
 
1468
- typing.add_typing node, AST::Builtin.any_type, context
1741
+ add_typing node, type: AST::Builtin.any_type
1469
1742
  end
1470
1743
 
1471
1744
  else
1472
1745
  raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
1746
+ end.tap do |pair|
1747
+ unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
1748
+ # Steep.logger.error { "result = #{pair.inspect}" }
1749
+ # Steep.logger.error { "node = #{node.type}" }
1750
+ raise "#synthesize should return an instance of Pair: #{pair.class}"
1751
+ end
1473
1752
  end
1474
1753
  end
1475
1754
  end
1476
1755
 
1477
1756
  def check(node, type, constraints: Subtyping::Constraints.empty)
1478
- type_ = synthesize(node, hint: type)
1757
+ pair = synthesize(node, hint: type)
1479
1758
 
1480
- result = check_relation(sub_type: type_, super_type: type, constraints: constraints)
1759
+ result = check_relation(sub_type: pair.type, super_type: type, constraints: constraints)
1481
1760
  if result.failure?
1482
- yield(type, type_, result)
1483
- end
1484
- end
1485
-
1486
- def type_assignment(var, rhs, node, hint: nil)
1487
- if rhs
1488
- expand_alias(synthesize(rhs, hint: type_env.lvar_types[var.name] || hint)) do |rhs_type|
1489
- node_type = assign_type_to_variable(var, rhs_type, node)
1490
- typing.add_typing(node, node_type, context)
1491
- end
1761
+ yield(type, pair.type, result)
1762
+ pair.with(type: type)
1492
1763
  else
1493
- raise
1494
- lhs_type = variable_type(var)
1495
-
1496
- if lhs_type
1497
- typing.add_typing(node, lhs_type, context)
1498
- else
1499
- fallback_to_any node
1500
- end
1501
- end
1502
- end
1503
-
1504
- def assign_type_to_variable(var, type, node)
1505
- name = var.name
1506
- type_env.assign(lvar: name, type: type, self_type: self_type) do |result|
1507
- var_type = type_env.get(lvar: name)
1508
- typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1509
- lhs_type: var_type,
1510
- rhs_type: type,
1511
- result: result))
1764
+ pair
1512
1765
  end
1513
1766
  end
1514
1767
 
1515
1768
  def type_ivasgn(name, rhs, node)
1516
- rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) })
1769
+ rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) }).type
1517
1770
  ivar_type = type_env.assign(ivar: name, type: rhs_type, self_type: self_type) do |error|
1518
1771
  case error
1519
1772
  when Subtyping::Result::Failure
@@ -1526,102 +1779,111 @@ module Steep
1526
1779
  fallback_to_any node
1527
1780
  end
1528
1781
  end
1529
- typing.add_typing(node, ivar_type, context)
1782
+ add_typing(node, type: ivar_type)
1530
1783
  end
1531
1784
 
1532
1785
  def type_masgn(node)
1533
1786
  lhs, rhs = node.children
1534
- rhs_original = synthesize(rhs)
1535
- rhs_type = expand_alias(rhs_original)
1787
+ rhs_pair = synthesize(rhs)
1788
+ rhs_type = expand_alias(rhs_pair.type)
1536
1789
 
1537
- case
1538
- when rhs.type == :array && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn} && lhs.children.size == rhs.children.size
1539
- pairs = lhs.children.zip(rhs.children)
1540
- pairs.each do |(l, r)|
1541
- case
1542
- when l.type == :lvasgn
1543
- type_assignment(l.children.first, r, l)
1544
- when l.type == :ivasgn
1545
- type_ivasgn(l.children.first, r, l)
1546
- end
1547
- end
1790
+ constr = rhs_pair.constr
1548
1791
 
1549
- typing.add_typing(node, rhs_type, context)
1550
-
1551
- when rhs_type.is_a?(AST::Types::Tuple) && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
1552
- lhs.children.each.with_index do |asgn, index|
1553
- type = rhs_type.types[index]
1554
-
1555
- case
1556
- when asgn.type == :lvasgn && asgn.children[0].name != :_
1557
- type ||= AST::Builtin.nil_type
1558
- type_env.assign(lvar: asgn.children[0].name, type: type, self_type: self_type) do |result|
1559
- var_type = type_env.get(lvar: asgn.children[0].name)
1560
- typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1561
- lhs_type: var_type,
1562
- rhs_type: type,
1563
- result: result))
1564
- end
1565
- when asgn.type == :ivasgn
1566
- type ||= AST::Builtin.nil_type
1567
- type_env.assign(ivar: asgn.children[0], type: type) do |result|
1568
- var_type = type_env.get(ivar: asgn.children[0])
1569
- typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1570
- lhs_type: var_type,
1571
- rhs_type: type,
1572
- result: result))
1792
+ if lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
1793
+ case
1794
+ when rhs.type == :array && lhs.children.size == rhs.children.size
1795
+ # a, @b = x, y
1796
+
1797
+ constr = lhs.children.zip(rhs.children).inject(constr) do |ctr, (lhs, rhs)|
1798
+ case lhs.type
1799
+ when :lvasgn
1800
+ name = lhs.children[0].name
1801
+ type = typing.type_of(node: rhs)
1802
+ env = ctr.context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
1803
+ typing.add_error(
1804
+ Errors::IncompatibleAssignment.new(node: lhs,
1805
+ lhs_type: declared_type,
1806
+ rhs_type: type,
1807
+ result: result)
1808
+ )
1809
+ end
1810
+ add_typing(lhs,
1811
+ type: type,
1812
+ constr: ctr.with_updated_context(lvar_env: env))
1813
+ when :ivasgn
1814
+ type_ivasgn(lhs.children.first, rhs, lhs)
1815
+ constr
1573
1816
  end
1574
1817
  end
1575
- end
1576
1818
 
1577
- typing.add_typing(node, rhs_type, context)
1819
+ add_typing(node, type: rhs_type, constr: constr)
1578
1820
 
1579
- when rhs_type.is_a?(AST::Types::Any)
1580
- fallback_to_any(node)
1821
+ when rhs_type.is_a?(AST::Types::Tuple)
1822
+ # a, @b = tuple
1581
1823
 
1582
- when AST::Builtin::Array.instance_type?(rhs_type)
1583
- element_type = rhs_type.args.first
1824
+ constr = lhs.children.zip(rhs_type.types).inject(constr) do |ctr, (lhs, type)|
1825
+ ty = type || AST::Builtin.nil_type
1584
1826
 
1585
- lhs.children.each do |assignment|
1586
- case assignment.type
1587
- when :lvasgn
1588
- assign_type_to_variable(assignment.children.first, element_type, assignment)
1589
- when :ivasgn
1590
- assignment.children.first.yield_self do |ivar|
1591
- type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
1827
+ case lhs.type
1828
+ when :lvasgn
1829
+ name = lhs.children[0].name
1830
+ env = ctr.context.lvar_env.assign(name, node: node, type: ty) do |declared_type, type, result|
1831
+ typing.add_error(
1832
+ Errors::IncompatibleAssignment.new(node: lhs,
1833
+ lhs_type: declared_type,
1834
+ rhs_type: type,
1835
+ result: result)
1836
+ )
1837
+ end
1838
+ add_typing(lhs,
1839
+ type: ty,
1840
+ constr: ctr.with_updated_context(lvar_env: env)).constr
1841
+ when :ivasgn
1842
+ ivar = lhs.children[0]
1843
+
1844
+ type_env.assign(ivar: ivar, type: ty, self_type: self_type) do |error|
1592
1845
  case error
1593
1846
  when Subtyping::Result::Failure
1594
- type = type_env.get(ivar: ivar)
1595
- typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
1596
- lhs_type: type,
1597
- rhs_type: element_type,
1847
+ ivar_type = type_env.get(ivar: ivar)
1848
+ typing.add_error(Errors::IncompatibleAssignment.new(node: lhs,
1849
+ lhs_type: ivar_type,
1850
+ rhs_type: ty,
1598
1851
  result: error))
1599
1852
  when nil
1600
1853
  fallback_to_any node
1601
1854
  end
1602
1855
  end
1856
+
1857
+ ctr
1603
1858
  end
1604
1859
  end
1605
- end
1606
1860
 
1607
- typing.add_typing node, rhs_type, context
1861
+ add_typing(node, type: rhs_type, constr: constr)
1608
1862
 
1609
- when rhs_type.is_a?(AST::Types::Union) &&
1610
- rhs_type.types.all? {|type| AST::Builtin::Array.instance_type?(type)}
1863
+ when AST::Builtin::Array.instance_type?(rhs_type)
1864
+ element_type = AST::Types::Union.build(types: [rhs_type.args.first, AST::Builtin.nil_type])
1611
1865
 
1612
- types = rhs_type.types.flat_map do |type|
1613
- type.args.first
1614
- end
1866
+ constr = lhs.children.inject(constr) do |ctr, assignment|
1867
+ case assignment.type
1868
+ when :lvasgn
1869
+ name = assignment.children[0].name
1870
+ env = ctr.context.lvar_env.assign(name, node: node, type: element_type) do |declared_type, type, result|
1871
+ typing.add_error(
1872
+ Errors::IncompatibleAssignment.new(node: assignment,
1873
+ lhs_type: declared_type,
1874
+ rhs_type: type,
1875
+ result: result)
1876
+ )
1877
+ end
1878
+
1879
+ add_typing(assignment,
1880
+ type: element_type,
1881
+ constr: ctr.with_updated_context(lvar_env: env)).constr
1615
1882
 
1616
- element_type = AST::Types::Union.build(types: types)
1883
+ when :ivasgn
1884
+ ivar = assignment.children[0]
1617
1885
 
1618
- lhs.children.each do |assignment|
1619
- case assignment.type
1620
- when :lvasgn
1621
- assign_type_to_variable(assignment.children.first, element_type, assignment)
1622
- when :ivasgn
1623
- assignment.children.first.yield_self do |ivar|
1624
- type_env.assign(ivar: ivar, type: element_type) do |error|
1886
+ type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
1625
1887
  case error
1626
1888
  when Subtyping::Result::Failure
1627
1889
  type = type_env.get(ivar: ivar)
@@ -1633,14 +1895,22 @@ module Steep
1633
1895
  fallback_to_any node
1634
1896
  end
1635
1897
  end
1898
+
1899
+ ctr
1636
1900
  end
1637
1901
  end
1638
- end
1639
1902
 
1640
- typing.add_typing node, rhs_type, context
1903
+ add_typing node, type: rhs_type, constr: constr
1904
+
1905
+ when rhs_type.is_a?(AST::Types::Any)
1906
+ fallback_to_any(node)
1641
1907
 
1908
+ else
1909
+ Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
1910
+ fallback_to_any(node)
1911
+ end
1642
1912
  else
1643
- Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
1913
+ Steep.logger.error("Unsupported masgn left hand side")
1644
1914
  fallback_to_any(node)
1645
1915
  end
1646
1916
  end
@@ -1655,7 +1925,8 @@ module Steep
1655
1925
  return_hint = type_hint.return_type
1656
1926
  end
1657
1927
 
1658
- block_type = type_block(block_param_hint: params_hint,
1928
+ block_pair = type_block(node: node,
1929
+ block_param_hint: params_hint,
1659
1930
  block_type_hint: return_hint,
1660
1931
  node_type_hint: nil,
1661
1932
  block_params: params,
@@ -1663,12 +1934,12 @@ module Steep
1663
1934
  block_annotations: block_annotations,
1664
1935
  topdown_hint: true)
1665
1936
 
1666
- typing.add_typing node, block_type, context
1937
+ add_typing node, type: block_pair.type
1667
1938
  end
1668
1939
 
1669
1940
  def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
1670
1941
  receiver, method_name, *arguments = send_node.children
1671
- receiver_type = receiver ? synthesize(receiver) : AST::Types::Self.new
1942
+ receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
1672
1943
 
1673
1944
  if unwrap
1674
1945
  receiver_type = unwrap(receiver_type)
@@ -1676,70 +1947,70 @@ module Steep
1676
1947
 
1677
1948
  receiver_type = expand_alias(receiver_type)
1678
1949
 
1679
- return_type = case receiver_type
1680
- when AST::Types::Any
1681
- typing.add_typing node, AST::Builtin.any_type, context
1682
-
1683
- when nil
1684
- fallback_to_any node
1685
-
1686
- when AST::Types::Void, AST::Types::Bot, AST::Types::Top
1687
- fallback_to_any node do
1688
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1689
- end
1690
-
1691
- else
1692
- case expanded_receiver_type = expand_self(receiver_type)
1693
- when AST::Types::Self
1694
- Steep.logger.error "`self` type cannot be resolved to concrete type"
1695
- fallback_to_any node do
1696
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1697
- end
1698
- else
1699
- begin
1700
- interface = checker.factory.interface(receiver_type,
1701
- private: !receiver,
1702
- self_type: expanded_receiver_type)
1703
-
1704
- method = interface.methods[method_name]
1705
-
1706
- if method
1707
- args = TypeInference::SendArgs.from_nodes(arguments)
1708
- return_type, _ = type_method_call(node,
1709
- method: method,
1710
- method_name: method_name,
1711
- args: args,
1712
- block_params: block_params,
1713
- block_body: block_body,
1714
- receiver_type: receiver_type,
1715
- topdown_hint: true)
1716
-
1717
- typing.add_typing node, return_type, context
1718
- else
1719
- fallback_to_any node do
1720
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
1721
- end
1722
- end
1723
- rescue => exn
1724
- $stderr.puts exn.inspect
1725
- exn.backtrace.each do |t|
1726
- $stderr.puts t
1727
- end
1950
+ pair = case receiver_type
1951
+ when AST::Types::Any
1952
+ add_typing node, type: AST::Builtin.any_type
1953
+
1954
+ when nil
1955
+ fallback_to_any node
1956
+
1957
+ when AST::Types::Void, AST::Types::Bot, AST::Types::Top
1958
+ fallback_to_any node do
1959
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1960
+ end
1961
+
1962
+ else
1963
+ case expanded_receiver_type = expand_self(receiver_type)
1964
+ when AST::Types::Self
1965
+ Steep.logger.error "`self` type cannot be resolved to concrete type"
1966
+ fallback_to_any node do
1967
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1968
+ end
1969
+ else
1970
+ begin
1971
+ interface = checker.factory.interface(receiver_type,
1972
+ private: !receiver,
1973
+ self_type: expanded_receiver_type)
1974
+
1975
+ method = interface.methods[method_name]
1976
+
1977
+ if method
1978
+ args = TypeInference::SendArgs.from_nodes(arguments)
1979
+ return_type, constr, _ = type_method_call(node,
1980
+ method: method,
1981
+ method_name: method_name,
1982
+ args: args,
1983
+ block_params: block_params,
1984
+ block_body: block_body,
1985
+ receiver_type: receiver_type,
1986
+ topdown_hint: true)
1987
+
1988
+ add_typing node, type: return_type, constr: constr
1989
+ else
1990
+ fallback_to_any node do
1991
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
1992
+ end
1993
+ end
1994
+ rescue => exn
1995
+ $stderr.puts exn.inspect
1996
+ exn.backtrace.each do |t|
1997
+ $stderr.puts t
1998
+ end
1728
1999
 
1729
- fallback_to_any node do
1730
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
1731
- end
1732
- end
1733
- end
1734
- end
2000
+ fallback_to_any node do
2001
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2002
+ end
2003
+ end
2004
+ end
2005
+ end
1735
2006
 
1736
- case return_type
2007
+ case pair.type
1737
2008
  when nil, Errors::Base
1738
2009
  arguments.each do |arg|
1739
2010
  unless typing.has_type?(arg)
1740
2011
  if arg.type == :splat
1741
- type = synthesize(arg.children[0])
1742
- typing.add_typing(arg, AST::Builtin::Array.instance_type(type), context)
2012
+ type = synthesize(arg.children[0]).type
2013
+ add_typing(arg, type: AST::Builtin::Array.instance_type(type))
1743
2014
  else
1744
2015
  synthesize(arg)
1745
2016
  end
@@ -1752,16 +2023,18 @@ module Steep
1752
2023
  params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
1753
2024
  pairs = params.each.map {|param| [param, AST::Builtin.any_type]}
1754
2025
 
1755
- for_block, _ = for_block(block_annotations: block_annotations,
1756
- param_pairs: pairs,
1757
- method_return_type: AST::Builtin.any_type,
1758
- typing: typing)
2026
+ for_block, _ = constr.for_block(block_annotations: block_annotations,
2027
+ param_pairs: pairs,
2028
+ method_return_type: AST::Builtin.any_type,
2029
+ typing: typing)
2030
+
2031
+ for_block.typing.add_context_for_body(node, context: for_block.context)
1759
2032
 
1760
2033
  for_block.synthesize(block_body)
1761
2034
  end
1762
2035
  end
1763
2036
  else
1764
- return_type
2037
+ pair
1765
2038
  end
1766
2039
  end
1767
2040
 
@@ -1782,6 +2055,8 @@ module Steep
1782
2055
  )
1783
2056
  end
1784
2057
 
2058
+ lvar_env = context.lvar_env.pin_assignments.annotate(block_annotations)
2059
+
1785
2060
  return_type = if block_annotations.break_type
1786
2061
  union_type(method_return_type, block_annotations.break_type)
1787
2062
  else
@@ -1809,7 +2084,8 @@ module Steep
1809
2084
  module_context: module_context,
1810
2085
  break_context: break_context,
1811
2086
  self_type: block_annotations.self_type || self_type,
1812
- type_env: block_type_env
2087
+ type_env: block_type_env,
2088
+ lvar_env: lvar_env
1813
2089
  )
1814
2090
  ), return_type]
1815
2091
  end
@@ -1823,70 +2099,72 @@ module Steep
1823
2099
  end
1824
2100
 
1825
2101
  def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
2102
+ node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
2103
+
1826
2104
  case
1827
2105
  when method.union?
1828
2106
  yield_self do
1829
2107
  results = method.types.map do |method|
1830
- typing.new_child do |child_typing|
1831
- type, error = with_new_typing(child_typing).type_method_call(node,
1832
- method_name: method_name,
1833
- receiver_type: receiver_type,
1834
- method: method,
1835
- args: args,
1836
- block_params: block_params,
1837
- block_body: block_body,
1838
- topdown_hint: false)
1839
- [
1840
- type,
1841
- child_typing,
1842
- error
1843
- ]
1844
- end
1845
- end
1846
-
1847
- if (type, typing, error = results.find {|_, _, error| error })
1848
- typing.save!
1849
- [type, error]
2108
+ typing.new_child(node_range) do |child_typing|
2109
+ with_new_typing(child_typing).type_method_call(node,
2110
+ method_name: method_name,
2111
+ receiver_type: receiver_type,
2112
+ method: method,
2113
+ args: args,
2114
+ block_params: block_params,
2115
+ block_body: block_body,
2116
+ topdown_hint: false)
2117
+ end
2118
+ end
2119
+
2120
+ if (type, constr, error = results.find {|_, _, error| error })
2121
+ constr.typing.save!
2122
+ [type,
2123
+ update_lvar_env { constr.context.lvar_env },
2124
+ error]
1850
2125
  else
1851
- _, typing, _ = results.first
1852
- typing.save!
2126
+ types = results.map(&:first)
2127
+
2128
+ _, constr, _ = results.first
2129
+ constr.typing.save!
1853
2130
 
1854
- [union_type(*results.map(&:first)), nil]
2131
+ [union_type(*types),
2132
+ update_lvar_env { constr.context.lvar_env },
2133
+ nil]
1855
2134
  end
1856
2135
  end
1857
2136
 
1858
2137
  when method.intersection?
1859
2138
  yield_self do
1860
2139
  results = method.types.map do |method|
1861
- typing.new_child do |child_typing|
1862
- type, error = with_new_typing(child_typing).type_method_call(node,
1863
- method_name: method_name,
1864
- receiver_type: receiver_type,
1865
- method: method,
1866
- args: args,
1867
- block_params: block_params,
1868
- block_body: block_body,
1869
- topdown_hint: false)
1870
- [
1871
- type,
1872
- child_typing,
1873
- error
1874
- ]
1875
- end
1876
- end
1877
-
1878
- successes = results.select {|_, _, error| !error }
2140
+ typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2141
+ with_new_typing(child_typing).type_method_call(node,
2142
+ method_name: method_name,
2143
+ receiver_type: receiver_type,
2144
+ method: method,
2145
+ args: args,
2146
+ block_params: block_params,
2147
+ block_body: block_body,
2148
+ topdown_hint: false)
2149
+ end
2150
+ end
2151
+
2152
+ successes = results.reject {|_, _, error| error }
1879
2153
  unless successes.empty?
1880
- types = successes.map {|type, typing, _| type }
1881
- typing = successes[0][1]
1882
- typing.save!
2154
+ types = successes.map(&:first)
2155
+ constr = successes[0][1]
2156
+ constr.typing.save!
1883
2157
 
1884
- [AST::Types::Intersection.build(types: types), nil]
2158
+ [AST::Types::Intersection.build(types: types),
2159
+ update_lvar_env { constr.context.lvar_env },
2160
+ nil]
1885
2161
  else
1886
- type, typing, error = results.first
1887
- typing.save!
2162
+ type, constr, error = results.first
2163
+ constr.typing.save!
1888
2164
 
1889
- [type, error]
2165
+ [type,
2166
+ update_lvar_env { constr.context.lvar_env },
2167
+ error]
1890
2168
  end
1891
2169
  end
1892
2170
 
@@ -1894,55 +2172,40 @@ module Steep
1894
2172
  yield_self do
1895
2173
  results = method.types.flat_map do |method_type|
1896
2174
  Steep.logger.tagged method_type.to_s do
1897
- case method_type
1898
- when Interface::MethodType
1899
- zips = args.zips(method_type.params, method_type.block&.type)
1900
-
1901
- zips.map do |arg_pairs|
1902
- typing.new_child do |child_typing|
1903
- result = self.with_new_typing(child_typing).try_method_type(
1904
- node,
1905
- receiver_type: receiver_type,
1906
- method_type: method_type,
1907
- args: args,
1908
- arg_pairs: arg_pairs,
1909
- block_params: block_params,
1910
- block_body: block_body,
1911
- child_typing: child_typing,
1912
- topdown_hint: topdown_hint
1913
- )
1914
-
1915
- [result, child_typing, method_type]
1916
- end
1917
- end
1918
- when :any
1919
- typing.new_child do |child_typing|
1920
- this = self.with_new_typing(child_typing)
1921
-
1922
- args.args.each do |arg|
1923
- this.synthesize(arg)
1924
- end
2175
+ zips = args.zips(method_type.params, method_type.block&.type)
2176
+
2177
+ zips.map do |arg_pairs|
2178
+ typing.new_child(node_range) do |child_typing|
2179
+ ret = self.with_new_typing(child_typing).try_method_type(
2180
+ node,
2181
+ receiver_type: receiver_type,
2182
+ method_type: method_type,
2183
+ args: args,
2184
+ arg_pairs: arg_pairs,
2185
+ block_params: block_params,
2186
+ block_body: block_body,
2187
+ child_typing: child_typing,
2188
+ topdown_hint: topdown_hint
2189
+ )
1925
2190
 
1926
- if block_body
1927
- this.synthesize(block_body)
1928
- end
2191
+ raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
1929
2192
 
1930
- child_typing.add_typing node, AST::Builtin.any_type, context
2193
+ result, constr = ret
1931
2194
 
1932
- [[AST::Builtin.any_type, child_typing, :any]]
2195
+ [result, constr, method_type]
1933
2196
  end
1934
2197
  end
1935
2198
  end
1936
2199
  end
1937
2200
 
1938
2201
  unless results.empty?
1939
- result, call_typing, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2202
+ result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
1940
2203
  else
1941
2204
  method_type = method.types.last
2205
+ constr = self.with_new_typing(typing.new_child(node_range))
1942
2206
  result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
1943
- call_typing = typing.new_child
1944
2207
  end
1945
- call_typing.save!
2208
+ constr.typing.save!
1946
2209
 
1947
2210
  case result
1948
2211
  when Errors::Base
@@ -1962,9 +2225,13 @@ module Steep
1962
2225
  type = AST::Builtin.any_type
1963
2226
  end
1964
2227
 
1965
- [type, result]
2228
+ [type,
2229
+ update_lvar_env { constr.context.lvar_env },
2230
+ result]
1966
2231
  else # Type
1967
- [result, nil]
2232
+ [result,
2233
+ update_lvar_env { constr.context.lvar_env },
2234
+ nil]
1968
2235
  end
1969
2236
  end
1970
2237
  end
@@ -1977,7 +2244,7 @@ module Steep
1977
2244
  when :hash
1978
2245
  keyword_hash_type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type,
1979
2246
  AST::Builtin.any_type)
1980
- typing.add_typing node, keyword_hash_type, context
2247
+ add_typing node, type: keyword_hash_type
1981
2248
 
1982
2249
  given_keys = Set.new()
1983
2250
 
@@ -2001,7 +2268,7 @@ module Steep
2001
2268
  params.rest_keywords
2002
2269
  end
2003
2270
 
2004
- typing.add_typing key_node, AST::Builtin::Symbol.instance_type, context
2271
+ add_typing key_node, type: AST::Builtin::Symbol.instance_type
2005
2272
 
2006
2273
  given_keys << key_symbol
2007
2274
 
@@ -2083,7 +2350,7 @@ module Steep
2083
2350
  hash_type = AST::Types::Record.new(elements: hash_elements)
2084
2351
  end
2085
2352
 
2086
- node_type = synthesize(node, hint: hash_type)
2353
+ node_type = synthesize(node, hint: hash_type).type
2087
2354
 
2088
2355
  check_relation(sub_type: node_type, super_type: hash_type).else do
2089
2356
  return Errors::ArgumentTypeMismatch.new(
@@ -2111,6 +2378,8 @@ module Steep
2111
2378
  context: context
2112
2379
  )
2113
2380
 
2381
+ constr = construction
2382
+
2114
2383
  method_type.instantiate(instantiation).yield_self do |method_type|
2115
2384
  constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
2116
2385
  variance = Subtyping::VariableVariance.from_method_type(method_type)
@@ -2120,23 +2389,20 @@ module Steep
2120
2389
  case pair
2121
2390
  when Array
2122
2391
  (arg_node, param_type) = pair
2123
-
2124
2392
  param_type = param_type.subst(instantiation)
2125
2393
 
2126
- arg_type = if arg_node.type == :splat
2127
- type = construction.synthesize(arg_node.children[0])
2128
- child_typing.add_typing(arg_node, type, context)
2129
- else
2130
- construction.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2131
- end
2394
+ arg_type, constr = if arg_node.type == :splat
2395
+ constr.synthesize(arg_node.children[0])
2396
+ else
2397
+ constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2398
+ end
2132
2399
 
2133
2400
  check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do |result|
2134
- return Errors::ArgumentTypeMismatch.new(
2135
- node: arg_node,
2136
- receiver_type: receiver_type,
2137
- expected: param_type,
2138
- actual: arg_type
2139
- )
2401
+ return [Errors::ArgumentTypeMismatch.new(node: arg_node,
2402
+ receiver_type: receiver_type,
2403
+ expected: param_type,
2404
+ actual: arg_type),
2405
+ constr]
2140
2406
  end
2141
2407
  else
2142
2408
  # keyword
@@ -2146,7 +2412,7 @@ module Steep
2146
2412
  constraints: constraints)
2147
2413
 
2148
2414
  if result.is_a?(Errors::Base)
2149
- return result
2415
+ return [result, constr]
2150
2416
  end
2151
2417
  end
2152
2418
  end
@@ -2161,10 +2427,9 @@ module Steep
2161
2427
  check_relation(sub_type: AST::Types::Proc.new(params: block_param_hint, return_type: AST::Types::Any.new),
2162
2428
  super_type: method_type.block.type,
2163
2429
  constraints: constraints).else do |result|
2164
- return Errors::IncompatibleBlockParameters.new(
2165
- node: node,
2166
- method_type: method_type
2167
- )
2430
+ return [Errors::IncompatibleBlockParameters.new(node: node,
2431
+ method_type: method_type),
2432
+ constr]
2168
2433
  end
2169
2434
  end
2170
2435
 
@@ -2175,50 +2440,53 @@ module Steep
2175
2440
 
2176
2441
  begin
2177
2442
  method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
2178
- block_type = construction.type_block(block_param_hint: method_type.block.type.params,
2179
- block_type_hint: method_type.block.type.return_type,
2180
- node_type_hint: method_type.return_type,
2181
- block_params: block_params_,
2182
- block_body: block_body,
2183
- block_annotations: block_annotations,
2184
- topdown_hint: topdown_hint)
2185
-
2186
- result = check_relation(sub_type: block_type.return_type,
2443
+ type, _ = constr.type_block(node: node,
2444
+ block_param_hint: method_type.block.type.params,
2445
+ block_type_hint: method_type.block.type.return_type,
2446
+ node_type_hint: method_type.return_type,
2447
+ block_params: block_params_,
2448
+ block_body: block_body,
2449
+ block_annotations: block_annotations,
2450
+ topdown_hint: topdown_hint)
2451
+
2452
+ result = check_relation(sub_type: type.return_type,
2187
2453
  super_type: method_type.block.type.return_type,
2188
2454
  constraints: constraints)
2189
2455
 
2190
2456
  case result
2191
2457
  when Subtyping::Result::Success
2192
2458
  method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)).yield_self do |ret_type|
2193
- if block_annotations.break_type
2194
- AST::Types::Union.new(types: [block_annotations.break_type, ret_type])
2195
- else
2196
- ret_type
2197
- end
2459
+ ty = if block_annotations.break_type
2460
+ AST::Types::Union.new(types: [block_annotations.break_type, ret_type])
2461
+ else
2462
+ ret_type
2463
+ end
2464
+ [ty, constr]
2198
2465
  end
2199
2466
 
2200
2467
  when Subtyping::Result::Failure
2201
- Errors::BlockTypeMismatch.new(node: node,
2202
- expected: method_type.block.type,
2203
- actual: block_type,
2204
- result: result)
2468
+ [Errors::BlockTypeMismatch.new(node: node,
2469
+ expected: method_type.block.type,
2470
+ actual: type,
2471
+ result: result),
2472
+ constr]
2205
2473
  end
2206
2474
  end
2207
2475
 
2208
2476
  rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2209
- Errors::UnsatisfiableConstraint.new(node: node,
2210
- method_type: method_type,
2211
- var: exn.var,
2212
- sub_type: exn.sub_type,
2213
- super_type: exn.super_type,
2214
- result: exn.result)
2477
+ [Errors::UnsatisfiableConstraint.new(node: node,
2478
+ method_type: method_type,
2479
+ var: exn.var,
2480
+ sub_type: exn.sub_type,
2481
+ super_type: exn.super_type,
2482
+ result: exn.result),
2483
+ constr]
2215
2484
  end
2216
2485
 
2217
2486
  when method_type.block && args.block_pass_arg
2218
2487
  begin
2219
2488
  method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
2220
- block_type = synthesize(args.block_pass_arg,
2221
- hint: topdown_hint ? method_type.block.type : nil)
2489
+ block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
2222
2490
  result = check_relation(
2223
2491
  sub_type: block_type,
2224
2492
  super_type: method_type.block.yield_self {|expected_block|
@@ -2233,40 +2501,58 @@ module Steep
2233
2501
 
2234
2502
  case result
2235
2503
  when Subtyping::Result::Success
2236
- method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars))
2504
+ [
2505
+ method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)),
2506
+ constr
2507
+ ]
2237
2508
 
2238
2509
  when Subtyping::Result::Failure
2239
- Errors::BlockTypeMismatch.new(node: node,
2240
- expected: method_type.block.type,
2241
- actual: block_type,
2242
- result: result)
2510
+ [
2511
+ Errors::BlockTypeMismatch.new(node: node,
2512
+ expected: method_type.block.type,
2513
+ actual: block_type,
2514
+ result: result),
2515
+ constr
2516
+ ]
2243
2517
  end
2244
2518
  end
2245
2519
 
2246
2520
  rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2247
- Errors::UnsatisfiableConstraint.new(node: node,
2248
- method_type: method_type,
2249
- var: exn.var,
2250
- sub_type: exn.sub_type,
2251
- super_type: exn.super_type,
2252
- result: exn.result)
2521
+ [
2522
+ Errors::UnsatisfiableConstraint.new(node: node,
2523
+ method_type: method_type,
2524
+ var: exn.var,
2525
+ sub_type: exn.sub_type,
2526
+ super_type: exn.super_type,
2527
+ result: exn.result),
2528
+ constr
2529
+ ]
2253
2530
  end
2254
2531
 
2255
2532
  when (!method_type.block || method_type.block.optional?) && !block_params && !block_body && !args.block_pass_arg
2256
2533
  # OK, without block
2257
- method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)).return_type
2534
+ [
2535
+ method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)).return_type,
2536
+ constr
2537
+ ]
2258
2538
 
2259
2539
  when !method_type.block && (block_params || args.block_pass_arg)
2260
- Errors::UnexpectedBlockGiven.new(
2261
- node: node,
2262
- method_type: method_type
2263
- )
2540
+ [
2541
+ Errors::UnexpectedBlockGiven.new(
2542
+ node: node,
2543
+ method_type: method_type
2544
+ ),
2545
+ constr
2546
+ ]
2264
2547
 
2265
2548
  when method_type.block && !method_type.block.optional? && !block_params && !block_body && !args.block_pass_arg
2266
- Errors::RequiredBlockMissing.new(
2267
- node: node,
2268
- method_type: method_type
2269
- )
2549
+ [
2550
+ Errors::RequiredBlockMissing.new(
2551
+ node: node,
2552
+ method_type: method_type
2553
+ ),
2554
+ constr
2555
+ ]
2270
2556
 
2271
2557
  else
2272
2558
  raise "Unexpected case condition"
@@ -2274,7 +2560,7 @@ module Steep
2274
2560
  end
2275
2561
  end
2276
2562
 
2277
- def type_block(block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
2563
+ def type_block(node:, block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
2278
2564
  block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
2279
2565
 
2280
2566
  param_types_hash = {}
@@ -2290,15 +2576,12 @@ module Steep
2290
2576
  end
2291
2577
  end
2292
2578
 
2293
- block_type_env = type_env.dup.tap do |env|
2294
- param_types_hash.each do |name, type|
2295
- env.set(lvar: name, type: type)
2296
- end
2297
-
2298
- block_annotations.lvar_types.each do |name, type|
2299
- env.set(lvar: name, type: type)
2579
+ lvar_env = context.lvar_env.pin_assignments.yield_self do |env|
2580
+ decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2581
+ hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2300
2582
  end
2301
- end
2583
+ env.update(declared_types: env.declared_types.merge(decls))
2584
+ end.annotate(block_annotations)
2302
2585
 
2303
2586
  break_type = if block_annotations.break_type
2304
2587
  union_type(node_type_hint, block_annotations.break_type)
@@ -2327,33 +2610,38 @@ module Steep
2327
2610
  module_context: module_context,
2328
2611
  break_context: break_context,
2329
2612
  self_type: block_annotations.self_type || self_type,
2330
- type_env: block_type_env
2613
+ type_env: type_env.dup,
2614
+ lvar_env: lvar_env
2331
2615
  )
2332
2616
  )
2333
2617
 
2618
+ for_block_body.typing.add_context_for_body(node, context: for_block_body.context)
2619
+
2334
2620
  if block_body
2335
- return_type = if (body_type = block_context.body_type)
2336
- for_block_body.check(block_body, body_type) do |expected, actual, result|
2337
- typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
2338
- expected: expected,
2339
- actual: actual,
2340
- result: result)
2621
+ body_pair = if (body_type = block_context.body_type)
2622
+ for_block_body.check(block_body, body_type) do |expected, actual, result|
2623
+ typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
2624
+ expected: expected,
2625
+ actual: actual,
2626
+ result: result)
2341
2627
 
2342
- end
2343
- body_type
2344
- else
2345
- for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
2346
2628
  end
2629
+ else
2630
+ for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
2631
+ end
2632
+
2633
+ range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
2634
+ typing.add_context(range, context: body_pair.context)
2347
2635
  else
2348
- return_type = AST::Builtin.any_type
2636
+ body_pair = Pair.new(type: AST::Builtin.nil_type, constr: for_block_body)
2349
2637
  end
2350
2638
 
2351
- AST::Types::Proc.new(
2352
- params: block_param_hint || block_params.params_type,
2353
- return_type: return_type
2354
- ).tap do |type|
2355
- Steep.logger.debug "block_type == #{type}"
2356
- end
2639
+ body_pair.with(
2640
+ type: AST::Types::Proc.new(
2641
+ params: block_param_hint || block_params.params_type,
2642
+ return_type: body_pair.type
2643
+ )
2644
+ )
2357
2645
  end
2358
2646
 
2359
2647
  def each_child_node(node)
@@ -2435,10 +2723,10 @@ module Steep
2435
2723
  end
2436
2724
 
2437
2725
  def nested_namespace_for_module(module_name)
2438
- if module_name.relative? && module_name.namespace.empty?
2439
- current_namespace.append(module_name.name)
2726
+ if module_name.relative?
2727
+ (current_namespace + module_name.namespace).append(module_name.name)
2440
2728
  else
2441
- current_namespace
2729
+ module_name
2442
2730
  end
2443
2731
  end
2444
2732
 
@@ -2457,6 +2745,7 @@ module Steep
2457
2745
  end
2458
2746
 
2459
2747
  def union_type(*types)
2748
+ raise if types.empty?
2460
2749
  AST::Types::Union.build(types: types)
2461
2750
  end
2462
2751
 
@@ -2545,7 +2834,7 @@ module Steep
2545
2834
  typing.add_error Errors::FallbackAny.new(node: node)
2546
2835
  end
2547
2836
 
2548
- typing.add_typing node, AST::Builtin.any_type, context
2837
+ add_typing node, type: AST::Builtin.any_type
2549
2838
  end
2550
2839
 
2551
2840
  def self_class?(node)
@@ -2591,21 +2880,6 @@ module Steep
2591
2880
  end
2592
2881
  end
2593
2882
 
2594
- def self.truthy_variables(node)
2595
- case node&.type
2596
- when :lvar
2597
- Set.new([node.children.first.name])
2598
- when :lvasgn
2599
- Set.new([node.children.first.name]) + truthy_variables(node.children[1])
2600
- when :and
2601
- truthy_variables(node.children[0]) + truthy_variables(node.children[1])
2602
- when :begin
2603
- truthy_variables(node.children.last)
2604
- else
2605
- Set.new()
2606
- end
2607
- end
2608
-
2609
2883
  def self.value_variables(node)
2610
2884
  case node&.type
2611
2885
  when :lvar
@@ -2685,7 +2959,7 @@ module Steep
2685
2959
  def try_hash_type(node, hint)
2686
2960
  case hint
2687
2961
  when AST::Types::Record
2688
- typing.new_child do |child_typing|
2962
+ typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2689
2963
  new_construction = with_new_typing(child_typing)
2690
2964
  elements = {}
2691
2965
 
@@ -2702,7 +2976,7 @@ module Steep
2702
2976
  end
2703
2977
 
2704
2978
  value_hint = hint.elements[key_value]
2705
- value_type = new_construction.synthesize(value, hint: value_hint)
2979
+ value_type = new_construction.synthesize(value, hint: value_hint).type
2706
2980
 
2707
2981
  if value_hint
2708
2982
  if check_relation(sub_type: value_type, super_type: value_hint).success?
@@ -2719,12 +2993,15 @@ module Steep
2719
2993
  child_typing.save!
2720
2994
 
2721
2995
  hash = AST::Types::Record.new(elements: elements)
2722
- typing.add_typing(node, hash, context)
2996
+ add_typing(node, type: hash)
2723
2997
  end
2724
2998
  when AST::Types::Union
2725
- hint.types.find do |type|
2726
- try_hash_type(node, type)
2999
+ hint.types.each do |type|
3000
+ if pair = try_hash_type(node, type)
3001
+ return pair
3002
+ end
2727
3003
  end
3004
+ nil
2728
3005
  end
2729
3006
  end
2730
3007
  end