mt-lang 0.3.24 → 0.3.26

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -1
  3. data/lib/milk_tea/core/bindings/attribute_binding.rb +51 -49
  4. data/lib/milk_tea/core/bindings/function_binding.rb +3 -1
  5. data/lib/milk_tea/core/bindings/module_binding.rb +42 -40
  6. data/lib/milk_tea/core/bindings/value_binding.rb +16 -14
  7. data/lib/milk_tea/core/bindings.rb +4 -9
  8. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +11 -11
  9. data/lib/milk_tea/core/c_backend/expressions.rb +11 -11
  10. data/lib/milk_tea/core/c_backend/feature_detection.rb +15 -19
  11. data/lib/milk_tea/core/c_backend/format_helpers.rb +1 -1
  12. data/lib/milk_tea/core/c_backend/reinterpret.rb +10 -10
  13. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1 -1
  14. data/lib/milk_tea/core/c_backend/statements.rb +20 -20
  15. data/lib/milk_tea/core/c_backend/type_declaration.rb +4 -4
  16. data/lib/milk_tea/core/c_backend/type_system.rb +1 -1
  17. data/lib/milk_tea/core/c_backend.rb +3 -3
  18. data/lib/milk_tea/core/compile_time.rb +41 -70
  19. data/lib/milk_tea/core/control_flow/builder.rb +3 -3
  20. data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
  21. data/lib/milk_tea/core/control_flow/graph.rb +1 -1
  22. data/lib/milk_tea/core/control_flow/termination.rb +1 -1
  23. data/lib/milk_tea/core/cst.rb +16 -0
  24. data/lib/milk_tea/core/flow_scope.rb +13 -0
  25. data/lib/milk_tea/core/lexer/character_classes.rb +2 -2
  26. data/lib/milk_tea/core/lexer/format_strings.rb +5 -5
  27. data/lib/milk_tea/core/lexer/heredocs.rb +6 -6
  28. data/lib/milk_tea/core/lexer/indentation.rb +4 -4
  29. data/lib/milk_tea/core/lexer/numbers.rb +1 -1
  30. data/lib/milk_tea/core/lexer/strings.rb +4 -4
  31. data/lib/milk_tea/core/lexer/symbols.rb +3 -3
  32. data/lib/milk_tea/core/lexer/trivia.rb +4 -4
  33. data/lib/milk_tea/core/lexer.rb +17 -17
  34. data/lib/milk_tea/core/lowering/async/analysis.rb +210 -208
  35. data/lib/milk_tea/core/lowering/async/async_lowering.rb +1406 -0
  36. data/lib/milk_tea/core/lowering/async/frame_builder.rb +615 -613
  37. data/lib/milk_tea/core/lowering/async/normalization.rb +410 -408
  38. data/lib/milk_tea/core/lowering/block.rb +982 -980
  39. data/lib/milk_tea/core/lowering/calls.rb +1360 -1358
  40. data/lib/milk_tea/core/lowering/declarations.rb +175 -173
  41. data/lib/milk_tea/core/lowering/dyn.rb +171 -169
  42. data/lib/milk_tea/core/lowering/events.rb +946 -944
  43. data/lib/milk_tea/core/lowering/expressions.rb +1514 -1512
  44. data/lib/milk_tea/core/lowering/foreign_cstr.rb +180 -178
  45. data/lib/milk_tea/core/lowering/functions.rb +186 -184
  46. data/lib/milk_tea/core/lowering/loops.rb +1004 -1002
  47. data/lib/milk_tea/core/lowering/lowering_context.rb +1 -1
  48. data/lib/milk_tea/core/lowering/proc.rb +355 -353
  49. data/lib/milk_tea/core/lowering/resolve.rb +2127 -2125
  50. data/lib/milk_tea/core/lowering/scans.rb +162 -168
  51. data/lib/milk_tea/core/lowering/str_buffer.rb +104 -102
  52. data/lib/milk_tea/core/lowering/utils.rb +964 -963
  53. data/lib/milk_tea/core/lowering.rb +22 -22
  54. data/lib/milk_tea/core/module_binder.rb +1 -1
  55. data/lib/milk_tea/core/module_loader.rb +2 -2
  56. data/lib/milk_tea/core/parser/attributes.rb +1 -1
  57. data/lib/milk_tea/core/parser/blocks.rb +2 -2
  58. data/lib/milk_tea/core/parser/declarations.rb +15 -15
  59. data/lib/milk_tea/core/parser/expressions.rb +20 -20
  60. data/lib/milk_tea/core/parser/recovery.rb +1 -1
  61. data/lib/milk_tea/core/parser/statements.rb +3 -3
  62. data/lib/milk_tea/core/parser/types.rb +4 -4
  63. data/lib/milk_tea/core/parser.rb +39 -21
  64. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +6 -6
  65. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +5 -5
  66. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -2
  67. data/lib/milk_tea/core/semantic_analyzer/calls.rb +1 -1
  68. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +4 -4
  69. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +37 -37
  70. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +4 -4
  71. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +4 -4
  72. data/lib/milk_tea/core/semantic_analyzer/generics.rb +4 -4
  73. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +7 -7
  74. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +59 -59
  75. data/lib/milk_tea/core/semantic_analyzer/statements.rb +3 -3
  76. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +1 -1
  77. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +12 -12
  78. data/lib/milk_tea/core/types/layout.rb +3 -1
  79. data/lib/milk_tea/core/types/visitor.rb +351 -349
  80. data/lib/milk_tea/core.rb +0 -2
  81. data/lib/milk_tea/tooling/cli/commands/bindgen.rb +1 -1
  82. data/lib/milk_tea/tooling/cli/commands/check.rb +5 -5
  83. data/lib/milk_tea/tooling/cli/commands/debug.rb +3 -3
  84. data/lib/milk_tea/tooling/cli/commands/deps.rb +1 -1
  85. data/lib/milk_tea/tooling/cli/commands/emit_c.rb +2 -2
  86. data/lib/milk_tea/tooling/cli/commands/format.rb +6 -6
  87. data/lib/milk_tea/tooling/cli/commands/lint.rb +3 -3
  88. data/lib/milk_tea/tooling/cli/commands/lower.rb +3 -3
  89. data/lib/milk_tea/tooling/cli/commands/parse.rb +3 -3
  90. data/lib/milk_tea/tooling/cli/commands/test.rb +3 -3
  91. data/lib/milk_tea/tooling/cli/commands/toolchain.rb +1 -1
  92. data/lib/milk_tea/tooling/cli.rb +22 -34
  93. data/lib/milk_tea/tooling/linter/flow_rules.rb +3 -3
  94. metadata +4 -5
  95. data/lib/milk_tea/core/cst_builder.rb +0 -19
  96. data/lib/milk_tea/core/lowering/async/lowering.rb +0 -1404
  97. data/lib/milk_tea/core/token_stream.rb +0 -30
@@ -3,438 +3,440 @@
3
3
  require_relative "predicates"
4
4
 
5
5
  module MilkTea
6
- class TypeVisitor
7
- def initialize
8
- @visited = {}
9
- end
6
+ module Types
7
+ class Visitor
8
+ def initialize
9
+ @visited = {}
10
+ end
10
11
 
11
- def visit(type)
12
- return if type.nil?
13
- return if @visited[type.object_id]
12
+ def visit(type)
13
+ return if type.nil?
14
+ return if @visited[type.object_id]
14
15
 
15
- @visited[type.object_id] = true
16
- dispatch(type)
17
- end
18
-
19
- def dispatch(type)
20
- case type
21
- when Types::Nullable then visit_nullable(type)
22
- when Types::GenericInstance then visit_generic_instance(type)
23
- when Types::Span then visit_span(type)
24
- when Types::Task then visit_task(type)
25
- when Types::GenericStructDefinition then visit_generic_struct_definition(type)
26
- when Types::GenericVariantDefinition then visit_generic_variant_definition(type)
27
- when Types::Struct then visit_struct(type)
28
- when Types::Union then visit_union(type)
29
- when Types::StructInstance then visit_struct_instance(type)
30
- when Types::Variant then visit_variant(type)
31
- when Types::VariantInstance then visit_variant_instance(type)
32
- when Types::VariantArmPayload then visit_variant_arm_payload(type)
33
- when Types::Proc then visit_proc(type)
34
- when Types::Function then visit_function(type)
35
- when Types::Parameter then visit_parameter(type)
36
- when Types::TypeVar then visit_type_var(type)
37
- when Types::Null then visit_null(type)
38
- when Types::Tuple then visit_tuple(type)
39
- when Types::Dyn then visit_dyn(type)
40
- when Types::SoA then visit_soa(type)
41
- when Types::Simd then visit_simd(type)
42
- when Types::Event then visit_event(type)
43
- when Types::LifetimeRef then visit_lifetime_ref(type)
44
- else visit_default(type)
16
+ @visited[type.object_id] = true
17
+ dispatch(type)
45
18
  end
46
- end
47
19
 
48
- def visit_children(type)
49
- type.children.each { |child| visit(child) }
50
- end
20
+ def dispatch(type)
21
+ case type
22
+ when Types::Nullable then visit_nullable(type)
23
+ when Types::GenericInstance then visit_generic_instance(type)
24
+ when Types::Span then visit_span(type)
25
+ when Types::Task then visit_task(type)
26
+ when Types::GenericStructDefinition then visit_generic_struct_definition(type)
27
+ when Types::GenericVariantDefinition then visit_generic_variant_definition(type)
28
+ when Types::Struct then visit_struct(type)
29
+ when Types::Union then visit_union(type)
30
+ when Types::StructInstance then visit_struct_instance(type)
31
+ when Types::Variant then visit_variant(type)
32
+ when Types::VariantInstance then visit_variant_instance(type)
33
+ when Types::VariantArmPayload then visit_variant_arm_payload(type)
34
+ when Types::Proc then visit_proc(type)
35
+ when Types::Function then visit_function(type)
36
+ when Types::Parameter then visit_parameter(type)
37
+ when Types::TypeVar then visit_type_var(type)
38
+ when Types::Null then visit_null(type)
39
+ when Types::Tuple then visit_tuple(type)
40
+ when Types::Dyn then visit_dyn(type)
41
+ when Types::SoA then visit_soa(type)
42
+ when Types::Simd then visit_simd(type)
43
+ when Types::Event then visit_event(type)
44
+ when Types::LifetimeRef then visit_lifetime_ref(type)
45
+ else visit_default(type)
46
+ end
47
+ end
51
48
 
52
- def visit_nullable(type); visit_children(type); end
53
- def visit_generic_instance(type); visit_children(type); end
54
- def visit_span(type); visit_children(type); end
55
- def visit_task(type); visit_children(type); end
56
- def visit_generic_struct_definition(type); visit_children(type); end
57
- def visit_generic_variant_definition(type); visit_children(type); end
58
- def visit_struct(type); visit_children(type); end
59
- def visit_union(type); visit_children(type); end
60
- def visit_struct_instance(type); visit_children(type); end
61
- def visit_variant(type); visit_children(type); end
62
- def visit_variant_instance(type); visit_children(type); end
63
- def visit_variant_arm_payload(type); visit_children(type); end
64
- def visit_proc(type); visit_children(type); end
65
- def visit_function(type); visit_children(type); end
66
- def visit_parameter(type); visit_children(type); end
67
- def visit_tuple(type); visit_children(type); end
68
- def visit_dyn(type); visit_children(type); end
69
- def visit_soa(type); visit_children(type); end
70
- def visit_simd(type); visit_children(type); end
71
- def visit_event(type); visit_children(type); end
72
-
73
- def visit_type_var(type); end
74
- def visit_null(type); end
75
- def visit_lifetime_ref(type); end
76
- def visit_default(type); end
77
- end
49
+ def visit_children(type)
50
+ type.children.each { |child| visit(child) }
51
+ end
78
52
 
79
- class ContainsTypeVarVisitor < TypeVisitor
80
- def initialize
81
- super
82
- @found = false
83
- end
53
+ def visit_nullable(type); visit_children(type); end
54
+ def visit_generic_instance(type); visit_children(type); end
55
+ def visit_span(type); visit_children(type); end
56
+ def visit_task(type); visit_children(type); end
57
+ def visit_generic_struct_definition(type); visit_children(type); end
58
+ def visit_generic_variant_definition(type); visit_children(type); end
59
+ def visit_struct(type); visit_children(type); end
60
+ def visit_union(type); visit_children(type); end
61
+ def visit_struct_instance(type); visit_children(type); end
62
+ def visit_variant(type); visit_children(type); end
63
+ def visit_variant_instance(type); visit_children(type); end
64
+ def visit_variant_arm_payload(type); visit_children(type); end
65
+ def visit_proc(type); visit_children(type); end
66
+ def visit_function(type); visit_children(type); end
67
+ def visit_parameter(type); visit_children(type); end
68
+ def visit_tuple(type); visit_children(type); end
69
+ def visit_dyn(type); visit_children(type); end
70
+ def visit_soa(type); visit_children(type); end
71
+ def visit_simd(type); visit_children(type); end
72
+ def visit_event(type); visit_children(type); end
73
+
74
+ def visit_type_var(type); end
75
+ def visit_null(type); end
76
+ def visit_lifetime_ref(type); end
77
+ def visit_default(type); end
78
+ end
79
+
80
+ class ContainsTypeVarVisitor < Visitor
81
+ def initialize
82
+ super
83
+ @found = false
84
+ end
84
85
 
85
- def found?
86
- @found
87
- end
86
+ def found?
87
+ @found
88
+ end
88
89
 
89
- def visit_type_var(type)
90
- @found = true
90
+ def visit_type_var(type)
91
+ @found = true
92
+ end
91
93
  end
92
- end
93
94
 
94
- class ContainsRefTypeVisitor < TypeVisitor
95
- def initialize(allow_lifetimes: [])
96
- super()
97
- @found = false
98
- @allow_lifetimes = allow_lifetimes
99
- end
95
+ class ContainsRefTypeVisitor < Visitor
96
+ def initialize(allow_lifetimes: [])
97
+ super()
98
+ @found = false
99
+ @allow_lifetimes = allow_lifetimes
100
+ end
100
101
 
101
- def found?
102
- @found
103
- end
102
+ def found?
103
+ @found
104
+ end
104
105
 
105
- def visit_generic_instance(type)
106
- if type.name == "ref" && [1, 2].include?(type.arguments.length)
107
- if type.arguments.length == 2
108
- lt = type.arguments.first
109
- if lt.is_a?(String) && @allow_lifetimes.include?(lt)
110
- visit_children(type)
111
- return
106
+ def visit_generic_instance(type)
107
+ if type.name == "ref" && [1, 2].include?(type.arguments.length)
108
+ if type.arguments.length == 2
109
+ lt = type.arguments.first
110
+ if lt.is_a?(String) && @allow_lifetimes.include?(lt)
111
+ visit_children(type)
112
+ return
113
+ end
112
114
  end
115
+ @found = true
116
+ return
113
117
  end
114
- @found = true
115
- return
118
+ visit_children(type)
116
119
  end
117
- visit_children(type)
118
120
  end
119
- end
120
121
 
121
- class ContainsProcTypeVisitor < TypeVisitor
122
- def initialize
123
- super
124
- @found = false
125
- end
122
+ class ContainsProcTypeVisitor < Visitor
123
+ def initialize
124
+ super
125
+ @found = false
126
+ end
126
127
 
127
- def found?
128
- @found
129
- end
128
+ def found?
129
+ @found
130
+ end
130
131
 
131
- def visit_proc(type)
132
- @found = true
133
- end
132
+ def visit_proc(type)
133
+ @found = true
134
+ end
134
135
 
135
- def visit_generic_instance(type)
136
- if type.name == "array" && type.arguments.first && !type.arguments.first.is_a?(Types::LiteralTypeArg)
137
- visit(type.arguments.first)
136
+ def visit_generic_instance(type)
137
+ if type.name == "array" && type.arguments.first && !type.arguments.first.is_a?(Types::LiteralTypeArg)
138
+ visit(type.arguments.first)
139
+ end
138
140
  end
139
141
  end
140
- end
141
142
 
142
- class ContainsCallableRefTypeVisitor < TypeVisitor
143
- def initialize
144
- super
145
- @found = false
146
- end
143
+ class ContainsCallableRefTypeVisitor < Visitor
144
+ def initialize
145
+ super
146
+ @found = false
147
+ end
147
148
 
148
- def found?
149
- @found
150
- end
149
+ def found?
150
+ @found
151
+ end
151
152
 
152
- def visit_proc(type)
153
- checker = ContainsRefTypeVisitor.new
154
- checker.visit(type)
155
- @found = true if checker.found?
153
+ def visit_proc(type)
154
+ checker = ContainsRefTypeVisitor.new
155
+ checker.visit(type)
156
+ @found = true if checker.found?
157
+ end
158
+ alias visit_function visit_proc
156
159
  end
157
- alias visit_function visit_proc
158
- end
159
160
 
160
- class StoredRefSupportedVisitor < TypeVisitor
161
- include Types::Predicates
161
+ class StoredRefSupportedVisitor < Visitor
162
+ include Types::Predicates
162
163
 
163
- def initialize(allow_lifetimes: [])
164
- super()
165
- @supported = true
166
- @allow_lifetimes = allow_lifetimes
167
- end
164
+ def initialize(allow_lifetimes: [])
165
+ super()
166
+ @supported = true
167
+ @allow_lifetimes = allow_lifetimes
168
+ end
168
169
 
169
- def result?
170
- @supported
171
- end
170
+ def result?
171
+ @supported
172
+ end
172
173
 
173
- def visit_generic_instance(type)
174
- if ref_type?(type)
175
- lt = ref_lifetime(type)
176
- if lt && @allow_lifetimes.include?(lt)
177
- visit_children(type)
174
+ def visit_generic_instance(type)
175
+ if ref_type?(type)
176
+ lt = ref_lifetime(type)
177
+ if lt && @allow_lifetimes.include?(lt)
178
+ visit_children(type)
179
+ return
180
+ end
181
+ @supported = false
178
182
  return
179
183
  end
180
- @supported = false
181
- return
184
+ visit_children(type)
182
185
  end
183
- visit_children(type)
184
- end
185
-
186
- def visit_proc(type)
187
- @supported = false unless callable_param_ref_supported?(type)
188
- end
189
- alias visit_function visit_proc
190
186
 
191
- def visit_children(type)
192
- type.children.each do |child|
193
- visit(child)
194
- return unless @supported
187
+ def visit_proc(type)
188
+ @supported = false unless callable_param_ref_supported?(type)
195
189
  end
196
- end
197
- end
198
-
199
- class SendableCheckVisitor < TypeVisitor
200
- def initialize
201
- super
202
- @sendable = true
203
- end
190
+ alias visit_function visit_proc
204
191
 
205
- def sendable?
206
- @sendable
207
- end
208
-
209
- def visit_children(type)
210
- type.children.each do |child|
211
- visit(child)
212
- return unless @sendable
192
+ def visit_children(type)
193
+ type.children.each do |child|
194
+ visit(child)
195
+ return unless @supported
196
+ end
213
197
  end
214
198
  end
215
199
 
216
- def visit_event(type)
217
- @sendable = false
218
- end
219
-
220
- def visit_dyn(type)
221
- @sendable = false
222
- end
223
-
224
- def visit_span(type)
225
- @sendable = false
226
- end
200
+ class SendableCheckVisitor < Visitor
201
+ def initialize
202
+ super
203
+ @sendable = true
204
+ end
227
205
 
228
- def visit_proc(type)
229
- @sendable = false
230
- end
206
+ def sendable?
207
+ @sendable
208
+ end
231
209
 
232
- def visit_function(type); end
210
+ def visit_children(type)
211
+ type.children.each do |child|
212
+ visit(child)
213
+ return unless @sendable
214
+ end
215
+ end
233
216
 
234
- def visit_generic_instance(type)
235
- case type.name
236
- when "ptr", "const_ptr", "own", "ref"
237
- @sendable = false
238
- when "array"
239
- el = type.arguments.first
240
- visit(el) unless el.is_a?(Types::LiteralTypeArg)
241
- when "str_buffer", "atomic"
242
- # sendable
243
- else
217
+ def visit_event(type)
244
218
  @sendable = false
245
219
  end
246
- end
247
220
 
248
- def visit_struct(type)
249
- if type.respond_to?(:has_events?) && type.has_events?
221
+ def visit_dyn(type)
250
222
  @sendable = false
251
- return
252
223
  end
253
- visit_children(type)
254
- end
255
- alias visit_struct_instance visit_struct
256
224
 
257
- def visit_default(type)
258
- case type
259
- when Types::Primitive
260
- @sendable = false if type.name == "str"
261
- when Types::Error, Types::Opaque, Types::StringView
225
+ def visit_span(type)
262
226
  @sendable = false
263
227
  end
264
- end
265
- end
266
228
 
267
- class SubstituteTypeVisitor
268
- def initialize(substitutions)
269
- @substitutions = substitutions
270
- end
229
+ def visit_proc(type)
230
+ @sendable = false
231
+ end
271
232
 
272
- def apply(type)
273
- case type
274
- when Types::TypeVar
275
- @substitutions.fetch(type.name, type)
276
- when Types::LifetimeRef
277
- @substitutions.fetch(type.name, type)
278
- when Types::Nullable
279
- substituted = apply(type.base)
280
- substituted.equal?(type.base) ? type : Types::Registry.nullable(substituted)
281
- when Types::GenericInstance
282
- new_args = type.arguments.map do |arg|
283
- arg.is_a?(Types::LiteralTypeArg) ? arg : apply(arg)
284
- end
285
- type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : Types::Registry.generic_instance(type.name, new_args)
286
- when Types::Span
287
- substituted = apply(type.element_type)
288
- substituted.equal?(type.element_type) ? type : Types::Registry.span(substituted)
289
- when Types::Task
290
- substituted = apply(type.result_type)
291
- substituted.equal?(type.result_type) ? type : Types::Registry.task(substituted)
292
- when Types::Event
293
- new_payload = type.payload_type ? apply(type.payload_type) : nil
294
- if new_payload.equal?(type.payload_type)
295
- type
233
+ def visit_function(type); end
234
+
235
+ def visit_generic_instance(type)
236
+ case type.name
237
+ when "ptr", "const_ptr", "own", "ref"
238
+ @sendable = false
239
+ when "array"
240
+ el = type.arguments.first
241
+ visit(el) unless el.is_a?(Types::LiteralTypeArg)
242
+ when "str_buffer", "atomic"
243
+ # sendable
296
244
  else
297
- Types::Event.new(type.name, capacity: type.capacity, payload_type: new_payload, module_name: type.module_name, visibility: type.visibility, owner_type_name: type.owner_type_name)
245
+ @sendable = false
298
246
  end
299
- when Types::Proc
300
- changed = false
301
- new_params = type.params.map do |param|
302
- new_param_type = apply(param.type)
303
- new_boundary = param.boundary_type ? apply(param.boundary_type) : nil
304
- changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type)
305
- Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
247
+ end
248
+
249
+ def visit_struct(type)
250
+ if type.respond_to?(:has_events?) && type.has_events?
251
+ @sendable = false
252
+ return
306
253
  end
307
- new_return = apply(type.return_type)
308
- changed = true unless new_return.equal?(type.return_type)
309
- changed ? Types::Registry.proc(params: new_params, return_type: new_return) : type
310
- when Types::Function
311
- changed = false
312
- new_params = type.params.map do |param|
313
- new_param_type = apply(param.type)
314
- new_boundary = param.boundary_type ? apply(param.boundary_type) : nil
315
- changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type)
316
- Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
254
+ visit_children(type)
255
+ end
256
+ alias visit_struct_instance visit_struct
257
+
258
+ def visit_default(type)
259
+ case type
260
+ when Types::Primitive
261
+ @sendable = false if type.name == "str"
262
+ when Types::Error, Types::Opaque, Types::StringView
263
+ @sendable = false
317
264
  end
318
- new_return = apply(type.return_type)
319
- changed = true unless new_return.equal?(type.return_type)
320
- new_receiver = type.receiver_type ? apply(type.receiver_type) : nil
321
- changed = true unless new_receiver.equal?(type.receiver_type)
322
- changed ? Types::Registry.function(type.name, params: new_params, return_type: new_return, receiver_type: new_receiver, receiver_editable: type.receiver_editable, variadic: type.variadic, external: type.external) : type
323
- when Types::StructInstance
324
- new_args = type.arguments.map { |arg| apply(arg) }
325
- type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
326
- when Types::VariantInstance
327
- new_args = type.arguments.map { |arg| apply(arg) }
328
- type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
329
- else
330
- type
331
265
  end
332
266
  end
333
- end
334
-
335
- class ContainsArrayStorageVisitor < TypeVisitor
336
- def initialize
337
- super
338
- @found = false
339
- end
340
267
 
341
- def found?
342
- @found
343
- end
268
+ class SubstituteTypeVisitor
269
+ def initialize(substitutions)
270
+ @substitutions = substitutions
271
+ end
344
272
 
345
- def dispatch(type)
346
- case type
347
- when Types::Nullable, Types::Struct, Types::StructInstance
348
- visit_children(type)
349
- when Types::GenericInstance
350
- if type.name == "array"
351
- @found = true
273
+ def apply(type)
274
+ case type
275
+ when Types::TypeVar
276
+ @substitutions.fetch(type.name, type)
277
+ when Types::LifetimeRef
278
+ @substitutions.fetch(type.name, type)
279
+ when Types::Nullable
280
+ substituted = apply(type.base)
281
+ substituted.equal?(type.base) ? type : Types::Registry.nullable(substituted)
282
+ when Types::GenericInstance
283
+ new_args = type.arguments.map do |arg|
284
+ arg.is_a?(Types::LiteralTypeArg) ? arg : apply(arg)
285
+ end
286
+ type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : Types::Registry.generic_instance(type.name, new_args)
287
+ when Types::Span
288
+ substituted = apply(type.element_type)
289
+ substituted.equal?(type.element_type) ? type : Types::Registry.span(substituted)
290
+ when Types::Task
291
+ substituted = apply(type.result_type)
292
+ substituted.equal?(type.result_type) ? type : Types::Registry.task(substituted)
293
+ when Types::Event
294
+ new_payload = type.payload_type ? apply(type.payload_type) : nil
295
+ if new_payload.equal?(type.payload_type)
296
+ type
297
+ else
298
+ Types::Event.new(type.name, capacity: type.capacity, payload_type: new_payload, module_name: type.module_name, visibility: type.visibility, owner_type_name: type.owner_type_name)
299
+ end
300
+ when Types::Proc
301
+ changed = false
302
+ new_params = type.params.map do |param|
303
+ new_param_type = apply(param.type)
304
+ new_boundary = param.boundary_type ? apply(param.boundary_type) : nil
305
+ changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type)
306
+ Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
307
+ end
308
+ new_return = apply(type.return_type)
309
+ changed = true unless new_return.equal?(type.return_type)
310
+ changed ? Types::Registry.proc(params: new_params, return_type: new_return) : type
311
+ when Types::Function
312
+ changed = false
313
+ new_params = type.params.map do |param|
314
+ new_param_type = apply(param.type)
315
+ new_boundary = param.boundary_type ? apply(param.boundary_type) : nil
316
+ changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type)
317
+ Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
318
+ end
319
+ new_return = apply(type.return_type)
320
+ changed = true unless new_return.equal?(type.return_type)
321
+ new_receiver = type.receiver_type ? apply(type.receiver_type) : nil
322
+ changed = true unless new_receiver.equal?(type.receiver_type)
323
+ changed ? Types::Registry.function(type.name, params: new_params, return_type: new_return, receiver_type: new_receiver, receiver_editable: type.receiver_editable, variadic: type.variadic, external: type.external) : type
324
+ when Types::StructInstance
325
+ new_args = type.arguments.map { |arg| apply(arg) }
326
+ type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
327
+ when Types::VariantInstance
328
+ new_args = type.arguments.map { |arg| apply(arg) }
329
+ type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
330
+ else
331
+ type
352
332
  end
353
333
  end
354
334
  end
355
335
 
356
- def visit_children(type)
357
- type.children.each do |child|
358
- visit(child)
359
- return if @found
336
+ class ContainsArrayStorageVisitor < Visitor
337
+ def initialize
338
+ super
339
+ @found = false
360
340
  end
361
- end
362
- end
363
341
 
364
- class ProcStorageSupportedVisitor < TypeVisitor
365
- def initialize
366
- super
367
- @supported = true
368
- end
342
+ def found?
343
+ @found
344
+ end
369
345
 
370
- def result?
371
- @supported
372
- end
346
+ def dispatch(type)
347
+ case type
348
+ when Types::Nullable, Types::Struct, Types::StructInstance
349
+ visit_children(type)
350
+ when Types::GenericInstance
351
+ if type.name == "array"
352
+ @found = true
353
+ end
354
+ end
355
+ end
373
356
 
374
- def dispatch(type)
375
- case type
376
- when Types::Nullable, Types::GenericInstance, Types::Struct, Types::Union,
377
- Types::StructInstance, Types::Variant, Types::VariantInstance, Types::VariantArmPayload,
378
- Types::Tuple, Types::Span
379
- visit_children(type)
380
- when Types::Proc
381
- when Types::Task, Types::Function, Types::Dyn, Types::SoA
382
- @supported = false
357
+ def visit_children(type)
358
+ type.children.each do |child|
359
+ visit(child)
360
+ return if @found
361
+ end
383
362
  end
384
363
  end
385
364
 
386
- def visit_children(type)
387
- type.children.each do |child|
388
- visit(child)
389
- return unless @supported
365
+ class ProcStorageSupportedVisitor < Visitor
366
+ def initialize
367
+ super
368
+ @supported = true
390
369
  end
391
- end
392
- end
393
370
 
394
- class ValidateSpecializedTypeVisitor < TypeVisitor
395
- def initialize(function_name:, context:, on_error:, on_generic_instance: nil)
396
- super()
397
- @function_name = function_name
398
- @context = context
399
- @on_error = on_error
400
- @on_generic_instance = on_generic_instance
401
- end
371
+ def result?
372
+ @supported
373
+ end
402
374
 
403
- def visit_type_var(type)
404
- @on_error.call("cannot infer type argument #{type.name} for function #{@function_name}")
405
- end
375
+ def dispatch(type)
376
+ case type
377
+ when Types::Nullable, Types::GenericInstance, Types::Struct, Types::Union,
378
+ Types::StructInstance, Types::Variant, Types::VariantInstance, Types::VariantArmPayload,
379
+ Types::Tuple, Types::Span
380
+ visit_children(type)
381
+ when Types::Proc
382
+ when Types::Task, Types::Function, Types::Dyn, Types::SoA
383
+ @supported = false
384
+ end
385
+ end
406
386
 
407
- def visit_generic_instance(type)
408
- @on_generic_instance&.call(type.name, type.arguments)
409
- visit_children(type)
387
+ def visit_children(type)
388
+ type.children.each do |child|
389
+ visit(child)
390
+ return unless @supported
391
+ end
392
+ end
410
393
  end
411
394
 
412
- def visit_proc(type)
413
- type.params.each do |param|
414
- with_context("#{@context} parameter #{param.name}") { visit(param.type) }
395
+ class ValidateSpecializedTypeVisitor < Visitor
396
+ def initialize(function_name:, context:, on_error:, on_generic_instance: nil)
397
+ super()
398
+ @function_name = function_name
399
+ @context = context
400
+ @on_error = on_error
401
+ @on_generic_instance = on_generic_instance
402
+ end
403
+
404
+ def visit_type_var(type)
405
+ @on_error.call("cannot infer type argument #{type.name} for function #{@function_name}")
406
+ end
407
+
408
+ def visit_generic_instance(type)
409
+ @on_generic_instance&.call(type.name, type.arguments)
410
+ visit_children(type)
415
411
  end
416
- with_context("#{@context} return type") { visit(type.return_type) }
417
- end
418
412
 
419
- def visit_function(type)
420
- type.params.each do |param|
421
- with_context("#{@context} parameter #{param.name}") { visit(param.type) }
422
- if param.boundary_type
423
- with_context("#{@context} boundary parameter #{param.name}") { visit(param.boundary_type) }
413
+ def visit_proc(type)
414
+ type.params.each do |param|
415
+ with_context("#{@context} parameter #{param.name}") { visit(param.type) }
424
416
  end
417
+ with_context("#{@context} return type") { visit(type.return_type) }
425
418
  end
426
- with_context("#{@context} return type") { visit(type.return_type) }
427
- if type.receiver_type
428
- with_context("#{@context} receiver type") { visit(type.receiver_type) }
419
+
420
+ def visit_function(type)
421
+ type.params.each do |param|
422
+ with_context("#{@context} parameter #{param.name}") { visit(param.type) }
423
+ if param.boundary_type
424
+ with_context("#{@context} boundary parameter #{param.name}") { visit(param.boundary_type) }
425
+ end
426
+ end
427
+ with_context("#{@context} return type") { visit(type.return_type) }
428
+ if type.receiver_type
429
+ with_context("#{@context} receiver type") { visit(type.receiver_type) }
430
+ end
429
431
  end
430
- end
431
432
 
432
- def with_context(new_context)
433
- old = @context
434
- @context = new_context
435
- yield
436
- ensure
437
- @context = old
433
+ def with_context(new_context)
434
+ old = @context
435
+ @context = new_context
436
+ yield
437
+ ensure
438
+ @context = old
439
+ end
438
440
  end
439
441
  end
440
442
  end