steep 0.13.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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