mt-lang 0.3.4 → 0.3.5

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.
@@ -1,423 +1,426 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- class SemanticAnalyzer::Checker
5
- private
6
-
7
- def infer_receiver_type_substitutions(binding, receiver_type)
8
- declared_receiver_type = binding.declared_receiver_type
9
- return {} unless declared_receiver_type
10
- case declared_receiver_type
11
- when Types::Nullable
12
- unless receiver_type.is_a?(Types::Nullable)
13
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
14
- end
4
+ class SemanticAnalyzer
5
+ class Checker
6
+ private
7
+
8
+ def infer_receiver_type_substitutions(binding, receiver_type)
9
+ declared_receiver_type = binding.declared_receiver_type
10
+ return {} unless declared_receiver_type
11
+ case declared_receiver_type
12
+ when Types::Nullable
13
+ unless receiver_type.is_a?(Types::Nullable)
14
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
15
+ end
15
16
 
16
- infer_receiver_type_substitutions(
17
- binding.with(declared_receiver_type: declared_receiver_type.base),
18
- receiver_type.base,
19
- )
20
- when Types::StructInstance
21
- return {} unless declared_receiver_type.definition.is_a?(Types::GenericStructDefinition)
17
+ infer_receiver_type_substitutions(
18
+ binding.with(declared_receiver_type: declared_receiver_type.base),
19
+ receiver_type.base,
20
+ )
21
+ when Types::StructInstance
22
+ return {} unless declared_receiver_type.definition.is_a?(Types::GenericStructDefinition)
22
23
 
23
- unless receiver_type.is_a?(Types::StructInstance) && receiver_type.definition == declared_receiver_type.definition
24
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
25
- end
24
+ unless receiver_type.is_a?(Types::StructInstance) && receiver_type.definition == declared_receiver_type.definition
25
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
26
+ end
26
27
 
27
- declared_receiver_type.definition.type_params.zip(receiver_type.arguments).to_h
28
- when Types::VariantInstance
29
- return {} unless declared_receiver_type.definition.is_a?(Types::GenericVariantDefinition)
28
+ declared_receiver_type.definition.type_params.zip(receiver_type.arguments).to_h
29
+ when Types::VariantInstance
30
+ return {} unless declared_receiver_type.definition.is_a?(Types::GenericVariantDefinition)
30
31
 
31
- unless receiver_type.is_a?(Types::VariantInstance) && receiver_type.definition == declared_receiver_type.definition
32
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
33
- end
32
+ unless receiver_type.is_a?(Types::VariantInstance) && receiver_type.definition == declared_receiver_type.definition
33
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
34
+ end
34
35
 
35
- declared_receiver_type.definition.type_params.zip(receiver_type.arguments).to_h
36
- when Types::GenericInstance
37
- unless receiver_type.is_a?(Types::GenericInstance) && receiver_type.name == declared_receiver_type.name && receiver_type.arguments.length == declared_receiver_type.arguments.length
38
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
39
- end
36
+ declared_receiver_type.definition.type_params.zip(receiver_type.arguments).to_h
37
+ when Types::GenericInstance
38
+ unless receiver_type.is_a?(Types::GenericInstance) && receiver_type.name == declared_receiver_type.name && receiver_type.arguments.length == declared_receiver_type.arguments.length
39
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
40
+ end
40
41
 
41
- declared_receiver_type.arguments.zip(receiver_type.arguments).each_with_object({}) do |(declared_argument, actual_argument), substitutions|
42
- if declared_argument.is_a?(Types::TypeVar)
43
- substitutions[declared_argument.name] = actual_argument
44
- elsif declared_argument != actual_argument
42
+ declared_receiver_type.arguments.zip(receiver_type.arguments).each_with_object({}) do |(declared_argument, actual_argument), substitutions|
43
+ if declared_argument.is_a?(Types::TypeVar)
44
+ substitutions[declared_argument.name] = actual_argument
45
+ elsif declared_argument != actual_argument
46
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
47
+ end
48
+ end
49
+ when Types::Span
50
+ return {} unless receiver_type.is_a?(Types::Span)
51
+
52
+ substitutions = {}
53
+ if declared_receiver_type.element_type.is_a?(Types::TypeVar)
54
+ substitutions[declared_receiver_type.element_type.name] = receiver_type.element_type
55
+ elsif declared_receiver_type.element_type != receiver_type.element_type
45
56
  raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
46
57
  end
58
+ substitutions
59
+ when Types::Task
60
+ return {} unless receiver_type.is_a?(Types::Task)
61
+
62
+ substitutions = {}
63
+ if declared_receiver_type.result_type.is_a?(Types::TypeVar)
64
+ substitutions[declared_receiver_type.result_type.name] = receiver_type.result_type
65
+ elsif declared_receiver_type.result_type != receiver_type.result_type
66
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
67
+ end
68
+ substitutions
69
+ when Types::SoA
70
+ return {} unless receiver_type.is_a?(Types::SoA)
71
+
72
+ substitutions = {}
73
+ if declared_receiver_type.element_type.is_a?(Types::TypeVar)
74
+ substitutions[declared_receiver_type.element_type.name] = receiver_type.element_type
75
+ elsif declared_receiver_type.element_type != receiver_type.element_type
76
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
77
+ end
78
+ substitutions
79
+ when Types::Simd
80
+ return {} unless receiver_type.is_a?(Types::Simd)
81
+
82
+ substitutions = {}
83
+ if declared_receiver_type.element_type.is_a?(Types::TypeVar)
84
+ substitutions[declared_receiver_type.element_type.name] = receiver_type.element_type
85
+ elsif declared_receiver_type.element_type != receiver_type.element_type
86
+ raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
87
+ end
88
+ substitutions
89
+ else
90
+ {}
47
91
  end
48
- when Types::Span
49
- return {} unless receiver_type.is_a?(Types::Span)
50
-
51
- substitutions = {}
52
- if declared_receiver_type.element_type.is_a?(Types::TypeVar)
53
- substitutions[declared_receiver_type.element_type.name] = receiver_type.element_type
54
- elsif declared_receiver_type.element_type != receiver_type.element_type
55
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
56
- end
57
- substitutions
58
- when Types::Task
59
- return {} unless receiver_type.is_a?(Types::Task)
60
-
61
- substitutions = {}
62
- if declared_receiver_type.result_type.is_a?(Types::TypeVar)
63
- substitutions[declared_receiver_type.result_type.name] = receiver_type.result_type
64
- elsif declared_receiver_type.result_type != receiver_type.result_type
65
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
66
- end
67
- substitutions
68
- when Types::SoA
69
- return {} unless receiver_type.is_a?(Types::SoA)
70
-
71
- substitutions = {}
72
- if declared_receiver_type.element_type.is_a?(Types::TypeVar)
73
- substitutions[declared_receiver_type.element_type.name] = receiver_type.element_type
74
- elsif declared_receiver_type.element_type != receiver_type.element_type
75
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
76
- end
77
- substitutions
78
- when Types::Simd
79
- return {} unless receiver_type.is_a?(Types::Simd)
80
-
81
- substitutions = {}
82
- if declared_receiver_type.element_type.is_a?(Types::TypeVar)
83
- substitutions[declared_receiver_type.element_type.name] = receiver_type.element_type
84
- elsif declared_receiver_type.element_type != receiver_type.element_type
85
- raise_sema_error("cannot use method #{binding.name} with receiver #{receiver_type}")
86
- end
87
- substitutions
88
- else
89
- {}
90
92
  end
91
- end
92
93
 
93
- def callable_receiver_type_for_specialization(callee, scopes:)
94
- return unless callee.is_a?(AST::MemberAccess)
94
+ def callable_receiver_type_for_specialization(callee, scopes:)
95
+ return unless callee.is_a?(AST::MemberAccess)
95
96
 
96
- resolve_type_expression(callee.receiver)
97
- end
97
+ resolve_type_expression(callee.receiver)
98
+ end
98
99
 
99
- def resolve_type_member(type, name)
100
- case type
101
- when Types::Enum, Types::Flags
102
- type.member(name)
103
- when Types::Variant
104
- return type if type.arm_names.include?(name) && !type.has_payload?(name)
100
+ def resolve_type_member(type, name)
101
+ case type
102
+ when Types::Enum, Types::Flags
103
+ type.member(name)
104
+ when Types::Variant
105
+ return type if type.arm_names.include?(name) && !type.has_payload?(name)
105
106
 
106
- nil
107
+ nil
108
+ end
107
109
  end
108
- end
109
110
 
110
- def function_type_for_name(name)
111
- @ctx.top_level_functions.fetch(name).type
112
- end
113
-
114
- def resolve_specialized_callable_binding(expression, scopes:)
115
- callable_kind = :function
116
- receiver = nil
117
- receiver_type = nil
118
- binding = case expression.callee
119
- when AST::Identifier
120
- @ctx.top_level_functions[expression.callee.name]
121
- when AST::MemberAccess
122
- if expression.callee.receiver.is_a?(AST::Identifier) && @ctx.imports.key?(expression.callee.receiver.name)
123
- imported_module = @ctx.imports.fetch(expression.callee.receiver.name)
124
- imported_function = imported_module.functions[expression.callee.member]
125
- if imported_function.nil? && imported_module.private_function?(expression.callee.member)
126
- raise_sema_error("#{expression.callee.receiver.name}.#{expression.callee.member} is private to module #{imported_module.name}")
127
- end
111
+ def function_type_for_name(name)
112
+ @ctx.top_level_functions.fetch(name).type
113
+ end
128
114
 
129
- imported_function
130
- elsif (type_expr = resolve_type_expression(expression.callee.receiver))
131
- associated_function = lookup_method(type_expr, expression.callee.member)
132
- if associated_function&.type&.receiver_type.nil?
133
- receiver_type = type_expr
134
- associated_function
135
- else
136
- if (imported_module = imported_module_with_private_method(type_expr, expression.callee.member))
137
- raise_sema_error("#{type_expr}.#{expression.callee.member} is private to module #{imported_module.name}")
115
+ def resolve_specialized_callable_binding(expression, scopes:)
116
+ callable_kind = :function
117
+ receiver = nil
118
+ receiver_type = nil
119
+ binding = case expression.callee
120
+ when AST::Identifier
121
+ @ctx.top_level_functions[expression.callee.name]
122
+ when AST::MemberAccess
123
+ if expression.callee.receiver.is_a?(AST::Identifier) && @ctx.imports.key?(expression.callee.receiver.name)
124
+ imported_module = @ctx.imports.fetch(expression.callee.receiver.name)
125
+ imported_function = imported_module.functions[expression.callee.member]
126
+ if imported_function.nil? && imported_module.private_function?(expression.callee.member)
127
+ raise_sema_error("#{expression.callee.receiver.name}.#{expression.callee.member} is private to module #{imported_module.name}")
138
128
  end
139
129
 
140
- nil
141
- end
142
- else
143
- receiver_type = infer_method_receiver_type(expression.callee.receiver, scopes:, member_name: expression.callee.member)
144
- method = lookup_method(receiver_type, expression.callee.member)
145
- if method
146
- callable_kind = :method
147
- receiver = expression.callee.receiver
148
- method
149
- else
150
- if (imported_module = imported_module_with_private_method(receiver_type, expression.callee.member))
151
- raise_sema_error("#{receiver_type}.#{expression.callee.member} is private to module #{imported_module.name}")
130
+ imported_function
131
+ elsif (type_expr = resolve_type_expression(expression.callee.receiver))
132
+ associated_function = lookup_method(type_expr, expression.callee.member)
133
+ if associated_function&.type&.receiver_type.nil?
134
+ receiver_type = type_expr
135
+ associated_function
136
+ else
137
+ if (imported_module = imported_module_with_private_method(type_expr, expression.callee.member))
138
+ raise_sema_error("#{type_expr}.#{expression.callee.member} is private to module #{imported_module.name}")
139
+ end
140
+
141
+ nil
152
142
  end
143
+ else
144
+ receiver_type = infer_method_receiver_type(expression.callee.receiver, scopes:, member_name: expression.callee.member)
145
+ method = lookup_method(receiver_type, expression.callee.member)
146
+ if method
147
+ callable_kind = :method
148
+ receiver = expression.callee.receiver
149
+ method
150
+ else
151
+ if (imported_module = imported_module_with_private_method(receiver_type, expression.callee.member))
152
+ raise_sema_error("#{receiver_type}.#{expression.callee.member} is private to module #{imported_module.name}")
153
+ end
153
154
 
154
- nil
155
+ nil
156
+ end
155
157
  end
156
158
  end
157
- end
158
- return nil unless binding
159
-
160
- type_arguments = resolve_specialization_type_arguments(expression)
161
- [callable_kind, instantiate_function_binding_with_receiver(binding, type_arguments, receiver_type:), receiver]
162
- end
159
+ return nil unless binding
163
160
 
164
- def resolve_specialization_type_arguments(expression)
165
- expression.arguments.map do |argument|
166
- resolve_type_argument(argument.value, type_params: current_type_params)
161
+ type_arguments = resolve_specialization_type_arguments(expression)
162
+ [callable_kind, instantiate_function_binding_with_receiver(binding, type_arguments, receiver_type:), receiver]
167
163
  end
168
- end
169
-
170
- def specialize_function_binding(binding, arguments, scopes:, receiver_type: nil)
171
- return binding if binding.type_params.empty?
172
164
 
173
- type_arguments = infer_function_type_arguments(binding, arguments, scopes:, receiver_type:)
174
- instantiate_function_binding(binding, type_arguments)
175
- end
176
-
177
- def instantiate_function_binding_with_receiver(binding, explicit_type_arguments, receiver_type: nil)
178
- if binding.type_params.empty?
179
- raise_sema_error("function #{binding.name} is not generic and cannot be specialized")
165
+ def resolve_specialization_type_arguments(expression)
166
+ expression.arguments.map do |argument|
167
+ resolve_type_argument(argument.value, type_params: current_type_params)
168
+ end
180
169
  end
181
170
 
182
- receiver_substitutions = infer_receiver_type_substitutions(binding, receiver_type)
183
- remaining_type_params = binding.type_params.reject { |name| receiver_substitutions.key?(name) }
184
- unless remaining_type_params.length == explicit_type_arguments.length
185
- raise_sema_error("function #{binding.name} expects #{remaining_type_params.length} type arguments, got #{explicit_type_arguments.length}")
171
+ def specialize_function_binding(binding, arguments, scopes:, receiver_type: nil)
172
+ return binding if binding.type_params.empty?
173
+
174
+ type_arguments = infer_function_type_arguments(binding, arguments, scopes:, receiver_type:)
175
+ instantiate_function_binding(binding, type_arguments)
186
176
  end
187
177
 
188
- substitutions = receiver_substitutions.dup
189
- remaining_type_params.zip(explicit_type_arguments).each do |name, type_argument|
190
- raise_sema_error("generic function #{binding.name} cannot be instantiated with ref types") if contains_ref_type?(type_argument)
178
+ def instantiate_function_binding_with_receiver(binding, explicit_type_arguments, receiver_type: nil)
179
+ if binding.type_params.empty?
180
+ raise_sema_error("function #{binding.name} is not generic and cannot be specialized")
181
+ end
191
182
 
192
- substitutions[name] = type_argument
193
- end
183
+ receiver_substitutions = infer_receiver_type_substitutions(binding, receiver_type)
184
+ remaining_type_params = binding.type_params.reject { |name| receiver_substitutions.key?(name) }
185
+ unless remaining_type_params.length == explicit_type_arguments.length
186
+ raise_sema_error("function #{binding.name} expects #{remaining_type_params.length} type arguments, got #{explicit_type_arguments.length}")
187
+ end
194
188
 
195
- type_arguments = binding.type_params.map do |name|
196
- inferred = substitutions[name]
197
- raise_sema_error("cannot infer type argument #{name} for function #{binding.name}") unless inferred
189
+ substitutions = receiver_substitutions.dup
190
+ remaining_type_params.zip(explicit_type_arguments).each do |name, type_argument|
191
+ raise_sema_error("generic function #{binding.name} cannot be instantiated with ref types") if contains_ref_type?(type_argument)
198
192
 
199
- inferred
200
- end
193
+ substitutions[name] = type_argument
194
+ end
201
195
 
202
- instantiate_function_binding(binding, type_arguments)
203
- end
196
+ type_arguments = binding.type_params.map do |name|
197
+ inferred = substitutions[name]
198
+ raise_sema_error("cannot infer type argument #{name} for function #{binding.name}") unless inferred
204
199
 
205
- def instantiate_function_binding(binding, type_arguments)
206
- if binding.type_params.empty?
207
- raise_sema_error("function #{binding.name} is not generic and cannot be specialized")
208
- end
200
+ inferred
201
+ end
209
202
 
210
- unless binding.type_params.length == type_arguments.length
211
- raise_sema_error("function #{binding.name} expects #{binding.type_params.length} type arguments, got #{type_arguments.length}")
203
+ instantiate_function_binding(binding, type_arguments)
212
204
  end
213
205
 
214
- if type_arguments.any? { |type_argument| contains_ref_type?(type_argument) }
215
- raise_sema_error("generic function #{binding.name} cannot be instantiated with ref types")
216
- end
206
+ def instantiate_function_binding(binding, type_arguments)
207
+ if binding.type_params.empty?
208
+ raise_sema_error("function #{binding.name} is not generic and cannot be specialized")
209
+ end
217
210
 
218
- key = type_arguments.freeze
219
- return binding.instances.fetch(key) if binding.instances.key?(key)
220
-
221
- substitutions = binding.type_params.zip(type_arguments).to_h
222
- validate_function_type_param_constraints!(binding, substitutions)
223
- type = substitute_type(binding.type, substitutions)
224
- body_params = binding.body_params.map { |param| substitute_value_binding(param, substitutions) }
225
- validate_specialized_function_binding!(binding.name, type, body_params)
226
-
227
- instance = FunctionBinding.new(
228
- name: binding.name,
229
- type:,
230
- body_params:,
231
- body_return_type: substitute_type(binding.body_return_type, substitutions),
232
- ast: binding.ast,
233
- external: binding.external,
234
- async: binding.async,
235
- type_params: [].freeze,
236
- type_param_constraints: {}.freeze,
237
- instances: {},
238
- type_arguments: key,
239
- owner: binding.owner,
240
- specialization_owner: @current_specialization_owner || (binding.owner == self ? nil : self),
241
- type_substitutions: substitutions.freeze,
242
- declared_receiver_type: binding.declared_receiver_type ? substitute_type(binding.declared_receiver_type, substitutions) : nil,
243
- )
244
- binding.instances[key] = instance
245
- end
211
+ unless binding.type_params.length == type_arguments.length
212
+ raise_sema_error("function #{binding.name} expects #{binding.type_params.length} type arguments, got #{type_arguments.length}")
213
+ end
246
214
 
247
- def validate_function_type_param_constraints!(binding, substitutions)
248
- binding.type_param_constraints.each do |name, constraints|
249
- actual_type = substitutions[name]
250
- raise_sema_error("cannot infer type argument #{name} for function #{binding.name}") unless actual_type
215
+ if type_arguments.any? { |type_argument| contains_ref_type?(type_argument) }
216
+ raise_sema_error("generic function #{binding.name} cannot be instantiated with ref types")
217
+ end
251
218
 
252
- validate_type_param_constraint_binding!(constraints, actual_type, context: "function #{binding.name}")
219
+ key = type_arguments.freeze
220
+ return binding.instances.fetch(key) if binding.instances.key?(key)
221
+
222
+ substitutions = binding.type_params.zip(type_arguments).to_h
223
+ validate_function_type_param_constraints!(binding, substitutions)
224
+ type = substitute_type(binding.type, substitutions)
225
+ body_params = binding.body_params.map { |param| substitute_value_binding(param, substitutions) }
226
+ validate_specialized_function_binding!(binding.name, type, body_params)
227
+
228
+ instance = FunctionBinding.new(
229
+ name: binding.name,
230
+ type:,
231
+ body_params:,
232
+ body_return_type: substitute_type(binding.body_return_type, substitutions),
233
+ ast: binding.ast,
234
+ external: binding.external,
235
+ async: binding.async,
236
+ type_params: [].freeze,
237
+ type_param_constraints: {}.freeze,
238
+ instances: {},
239
+ type_arguments: key,
240
+ owner: binding.owner,
241
+ specialization_owner: @current_specialization_owner || (binding.owner == self ? nil : self),
242
+ type_substitutions: substitutions.freeze,
243
+ declared_receiver_type: binding.declared_receiver_type ? substitute_type(binding.declared_receiver_type, substitutions) : nil,
244
+ )
245
+ binding.instances[key] = instance
253
246
  end
254
- end
255
247
 
256
- def infer_function_type_arguments(binding, arguments, scopes:, receiver_type: nil)
257
- expected_params = binding.type.params
258
- unless call_arity_matches?(binding.type, arguments.length)
259
- raise_sema_error(arity_error_message(binding.type, binding.name, arguments.length))
260
- end
248
+ def validate_function_type_param_constraints!(binding, substitutions)
249
+ binding.type_param_constraints.each do |name, constraints|
250
+ actual_type = substitutions[name]
251
+ raise_sema_error("cannot infer type argument #{name} for function #{binding.name}") unless actual_type
261
252
 
262
- substitutions = infer_receiver_type_substitutions(binding, receiver_type)
263
- expected_params.each_with_index do |parameter, index|
264
- argument = arguments.fetch(index)
265
- candidate_type = substitute_type(parameter.type, substitutions)
266
- expected_argument_type = if callable_type?(candidate_type)
267
- candidate_type
268
- elsif contains_type_var?(candidate_type)
269
- nil
270
- else
271
- candidate_type
272
- end
273
- actual_type = foreign_argument_actual_type(parameter, argument, scopes:, function_name: binding.name, expected_type: expected_argument_type)
274
- collect_type_substitutions(parameter.type, actual_type, substitutions, binding.name)
253
+ validate_type_param_constraint_binding!(constraints, actual_type, context: "function #{binding.name}")
254
+ end
275
255
  end
276
256
 
277
- binding.type_params.map do |name|
278
- inferred = substitutions[name]
279
- raise_sema_error("cannot infer type argument #{name} for function #{binding.name}") unless inferred
257
+ def infer_function_type_arguments(binding, arguments, scopes:, receiver_type: nil)
258
+ expected_params = binding.type.params
259
+ unless call_arity_matches?(binding.type, arguments.length)
260
+ raise_sema_error(arity_error_message(binding.type, binding.name, arguments.length))
261
+ end
280
262
 
281
- raise_sema_error("generic function #{binding.name} cannot be instantiated with ref types") if contains_ref_type?(inferred)
263
+ substitutions = infer_receiver_type_substitutions(binding, receiver_type)
264
+ expected_params.each_with_index do |parameter, index|
265
+ argument = arguments.fetch(index)
266
+ candidate_type = substitute_type(parameter.type, substitutions)
267
+ expected_argument_type = if callable_type?(candidate_type)
268
+ candidate_type
269
+ elsif contains_type_var?(candidate_type)
270
+ nil
271
+ else
272
+ candidate_type
273
+ end
274
+ actual_type = foreign_argument_actual_type(parameter, argument, scopes:, function_name: binding.name, expected_type: expected_argument_type)
275
+ collect_type_substitutions(parameter.type, actual_type, substitutions, binding.name)
276
+ end
282
277
 
283
- inferred
284
- end
285
- end
278
+ binding.type_params.map do |name|
279
+ inferred = substitutions[name]
280
+ raise_sema_error("cannot infer type argument #{name} for function #{binding.name}") unless inferred
286
281
 
287
- def collect_type_substitutions(pattern_type, actual_type, substitutions, function_name)
288
- case pattern_type
289
- when Types::TypeVar
290
- existing = substitutions[pattern_type.name]
291
- if existing && existing != actual_type
292
- raise_sema_error("conflicting type argument #{pattern_type.name} for function #{function_name}: got #{existing} and #{actual_type}")
293
- end
282
+ raise_sema_error("generic function #{binding.name} cannot be instantiated with ref types") if contains_ref_type?(inferred)
294
283
 
295
- substitutions[pattern_type.name] ||= actual_type
296
- when Types::Nullable
297
- candidate = actual_type.is_a?(Types::Nullable) ? actual_type.base : actual_type
298
- collect_type_substitutions(pattern_type.base, candidate, substitutions, function_name)
299
- when Types::GenericInstance
300
- if ref_type?(pattern_type) && !ref_type?(actual_type)
301
- collect_type_substitutions(referenced_type(pattern_type), actual_type, substitutions, function_name)
302
- return
284
+ inferred
303
285
  end
286
+ end
304
287
 
305
- if own_type?(actual_type) && (mutable_pointer_type?(pattern_type) || const_pointer_type?(pattern_type))
306
- collect_type_substitutions(pointee_type(pattern_type), owned_referent_type(actual_type), substitutions, function_name)
307
- return
308
- end
288
+ def collect_type_substitutions(pattern_type, actual_type, substitutions, function_name)
289
+ case pattern_type
290
+ when Types::TypeVar
291
+ existing = substitutions[pattern_type.name]
292
+ if existing && existing != actual_type
293
+ raise_sema_error("conflicting type argument #{pattern_type.name} for function #{function_name}: got #{existing} and #{actual_type}")
294
+ end
309
295
 
310
- return unless actual_type.is_a?(Types::GenericInstance)
311
- return unless actual_type.name == pattern_type.name && actual_type.arguments.length == pattern_type.arguments.length
296
+ substitutions[pattern_type.name] ||= actual_type
297
+ when Types::Nullable
298
+ candidate = actual_type.is_a?(Types::Nullable) ? actual_type.base : actual_type
299
+ collect_type_substitutions(pattern_type.base, candidate, substitutions, function_name)
300
+ when Types::GenericInstance
301
+ if ref_type?(pattern_type) && !ref_type?(actual_type)
302
+ collect_type_substitutions(referenced_type(pattern_type), actual_type, substitutions, function_name)
303
+ return
304
+ end
312
305
 
313
- pattern_type.arguments.zip(actual_type.arguments).each do |expected_argument, actual_argument|
314
- next if expected_argument.is_a?(Types::LiteralTypeArg)
306
+ if own_type?(actual_type) && (mutable_pointer_type?(pattern_type) || const_pointer_type?(pattern_type))
307
+ collect_type_substitutions(pointee_type(pattern_type), owned_referent_type(actual_type), substitutions, function_name)
308
+ return
309
+ end
315
310
 
316
- collect_type_substitutions(expected_argument, actual_argument, substitutions, function_name)
317
- end
318
- when Types::VariantInstance
319
- return unless actual_type.is_a?(Types::VariantInstance)
320
- return unless actual_type.definition == pattern_type.definition || (actual_type.name == pattern_type.name && actual_type.arguments.length == pattern_type.arguments.length)
311
+ return unless actual_type.is_a?(Types::GenericInstance)
312
+ return unless actual_type.name == pattern_type.name && actual_type.arguments.length == pattern_type.arguments.length
321
313
 
322
- pattern_type.arguments.zip(actual_type.arguments).each do |expected_argument, actual_argument|
323
- next if expected_argument.is_a?(Types::LiteralTypeArg)
314
+ pattern_type.arguments.zip(actual_type.arguments).each do |expected_argument, actual_argument|
315
+ next if expected_argument.is_a?(Types::LiteralTypeArg)
324
316
 
325
- collect_type_substitutions(expected_argument, actual_argument, substitutions, function_name)
326
- end
327
- when Types::Span
328
- return unless actual_type.is_a?(Types::Span)
329
-
330
- collect_type_substitutions(pattern_type.element_type, actual_type.element_type, substitutions, function_name)
331
- when Types::Task
332
- return unless actual_type.is_a?(Types::Task)
333
-
334
- collect_type_substitutions(pattern_type.result_type, actual_type.result_type, substitutions, function_name)
335
- when Types::Proc
336
- if task_root_proc_type?(pattern_type) && actual_type.is_a?(Types::Task)
337
- collect_type_substitutions(pattern_type.return_type, actual_type, substitutions, function_name)
338
- return
339
- end
317
+ collect_type_substitutions(expected_argument, actual_argument, substitutions, function_name)
318
+ end
319
+ when Types::VariantInstance
320
+ return unless actual_type.is_a?(Types::VariantInstance)
321
+ return unless actual_type.definition == pattern_type.definition || (actual_type.name == pattern_type.name && actual_type.arguments.length == pattern_type.arguments.length)
340
322
 
341
- actual_params = case actual_type
342
- when Types::Proc
343
- return unless actual_type.params.length == pattern_type.params.length
323
+ pattern_type.arguments.zip(actual_type.arguments).each do |expected_argument, actual_argument|
324
+ next if expected_argument.is_a?(Types::LiteralTypeArg)
344
325
 
345
- actual_type.params
346
- when Types::Function
347
- return if actual_type.receiver_type || actual_type.variadic
348
- return unless actual_type.params.length == pattern_type.params.length
326
+ collect_type_substitutions(expected_argument, actual_argument, substitutions, function_name)
327
+ end
328
+ when Types::Span
329
+ return unless actual_type.is_a?(Types::Span)
330
+
331
+ collect_type_substitutions(pattern_type.element_type, actual_type.element_type, substitutions, function_name)
332
+ when Types::Task
333
+ return unless actual_type.is_a?(Types::Task)
334
+
335
+ collect_type_substitutions(pattern_type.result_type, actual_type.result_type, substitutions, function_name)
336
+ when Types::Proc
337
+ if task_root_proc_type?(pattern_type) && actual_type.is_a?(Types::Task)
338
+ collect_type_substitutions(pattern_type.return_type, actual_type, substitutions, function_name)
339
+ return
340
+ end
349
341
 
350
- actual_type.params
351
- else
352
- return
353
- end
342
+ actual_params = case actual_type
343
+ when Types::Proc
344
+ return unless actual_type.params.length == pattern_type.params.length
354
345
 
355
- pattern_type.params.zip(actual_params).each do |expected_param, actual_param|
356
- collect_type_substitutions(expected_param.type, actual_param.type, substitutions, function_name)
357
- end
358
- collect_type_substitutions(pattern_type.return_type, actual_type.return_type, substitutions, function_name)
359
- when Types::StructInstance
360
- return unless actual_type.is_a?(Types::StructInstance)
361
- return unless actual_type.definition == pattern_type.definition && actual_type.arguments.length == pattern_type.arguments.length
346
+ actual_type.params
347
+ when Types::Function
348
+ return if actual_type.receiver_type || actual_type.variadic
349
+ return unless actual_type.params.length == pattern_type.params.length
362
350
 
363
- pattern_type.arguments.zip(actual_type.arguments).each do |expected_argument, actual_argument|
364
- collect_type_substitutions(expected_argument, actual_argument, substitutions, function_name)
365
- end
366
- when Types::Function
367
- return unless actual_type.is_a?(Types::Function)
368
- return unless actual_type.params.length == pattern_type.params.length
351
+ actual_type.params
352
+ else
353
+ return
354
+ end
369
355
 
370
- pattern_type.params.zip(actual_type.params).each do |expected_param, actual_param|
371
- collect_type_substitutions(expected_param.type, actual_param.type, substitutions, function_name)
356
+ pattern_type.params.zip(actual_params).each do |expected_param, actual_param|
357
+ collect_type_substitutions(expected_param.type, actual_param.type, substitutions, function_name)
358
+ end
359
+ collect_type_substitutions(pattern_type.return_type, actual_type.return_type, substitutions, function_name)
360
+ when Types::StructInstance
361
+ return unless actual_type.is_a?(Types::StructInstance)
362
+ return unless actual_type.definition == pattern_type.definition && actual_type.arguments.length == pattern_type.arguments.length
363
+
364
+ pattern_type.arguments.zip(actual_type.arguments).each do |expected_argument, actual_argument|
365
+ collect_type_substitutions(expected_argument, actual_argument, substitutions, function_name)
366
+ end
367
+ when Types::Function
368
+ return unless actual_type.is_a?(Types::Function)
369
+ return unless actual_type.params.length == pattern_type.params.length
370
+
371
+ pattern_type.params.zip(actual_type.params).each do |expected_param, actual_param|
372
+ collect_type_substitutions(expected_param.type, actual_param.type, substitutions, function_name)
373
+ end
374
+ collect_type_substitutions(pattern_type.return_type, actual_type.return_type, substitutions, function_name)
372
375
  end
373
- collect_type_substitutions(pattern_type.return_type, actual_type.return_type, substitutions, function_name)
374
376
  end
375
- end
376
377
 
377
- def substitute_value_binding(binding, substitutions)
378
- ValueBinding.new(
379
- id: binding.id,
380
- name: binding.name,
381
- storage_type: substitute_type(binding.storage_type, substitutions),
382
- flow_type: binding.flow_type ? substitute_type(binding.flow_type, substitutions) : nil,
383
- mutable: binding.mutable,
384
- kind: binding.kind,
385
- const_value: binding.const_value,
386
- )
387
- end
378
+ def substitute_value_binding(binding, substitutions)
379
+ ValueBinding.new(
380
+ id: binding.id,
381
+ name: binding.name,
382
+ storage_type: substitute_type(binding.storage_type, substitutions),
383
+ flow_type: binding.flow_type ? substitute_type(binding.flow_type, substitutions) : nil,
384
+ mutable: binding.mutable,
385
+ kind: binding.kind,
386
+ const_value: binding.const_value,
387
+ )
388
+ end
388
389
 
389
- def validate_specialized_function_binding!(function_name, function_type, body_params)
390
- function_type.params.each do |param|
391
- validate_specialized_function_type!(param.type, function_name:, context: "parameter #{param.name}")
392
- validate_specialized_function_type!(param.boundary_type, function_name:, context: "boundary parameter #{param.name}") if param.boundary_type
390
+ def validate_specialized_function_binding!(function_name, function_type, body_params)
391
+ function_type.params.each do |param|
392
+ validate_specialized_function_type!(param.type, function_name:, context: "parameter #{param.name}")
393
+ validate_specialized_function_type!(param.boundary_type, function_name:, context: "boundary parameter #{param.name}") if param.boundary_type
394
+ end
395
+ validate_specialized_function_type!(function_type.return_type, function_name:, context: "return type")
396
+ validate_specialized_function_type!(function_type.receiver_type, function_name:, context: "receiver type") if function_type.receiver_type
397
+
398
+ body_params.each do |param|
399
+ validate_specialized_function_type!(param.type, function_name:, context: "body parameter #{param.name}")
400
+ end
393
401
  end
394
- validate_specialized_function_type!(function_type.return_type, function_name:, context: "return type")
395
- validate_specialized_function_type!(function_type.receiver_type, function_name:, context: "receiver type") if function_type.receiver_type
396
402
 
397
- body_params.each do |param|
398
- validate_specialized_function_type!(param.type, function_name:, context: "body parameter #{param.name}")
403
+ def validate_specialized_function_type!(type, function_name:, context:)
404
+ ValidateSpecializedTypeVisitor.new(
405
+ function_name:,
406
+ context:,
407
+ on_error: ->(msg) { raise_sema_error(msg) },
408
+ on_generic_instance: ->(name, args) { validate_generic_type!(name, args) },
409
+ ).visit(type)
399
410
  end
400
- end
401
411
 
402
- def validate_specialized_function_type!(type, function_name:, context:)
403
- ValidateSpecializedTypeVisitor.new(
404
- function_name:,
405
- context:,
406
- on_error: ->(msg) { raise_sema_error(msg) },
407
- on_generic_instance: ->(name, args) { validate_generic_type!(name, args) },
408
- ).visit(type)
409
- end
412
+ def substitute_type(type, substitutions)
413
+ SubstituteTypeVisitor.new(substitutions).apply(type)
414
+ end
410
415
 
411
- def substitute_type(type, substitutions)
412
- SubstituteTypeVisitor.new(substitutions).apply(type)
413
- end
416
+ def bitwise_type?(type)
417
+ type.respond_to?(:bitwise?) && type.bitwise?
418
+ end
414
419
 
415
- def bitwise_type?(type)
416
- type.respond_to?(:bitwise?) && type.bitwise?
420
+ def callable_type?(type)
421
+ type.is_a?(Types::Function) || type.is_a?(Types::Proc)
422
+ end
417
423
  end
418
424
 
419
- def callable_type?(type)
420
- type.is_a?(Types::Function) || type.is_a?(Types::Proc)
421
- end
422
425
  end
423
426
  end