mt-lang 0.3.38 → 0.3.40

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/docs/lsp-performance.md +347 -0
  3. data/lib/milk_tea/base.rb +1 -1
  4. data/lib/milk_tea/core/ast.rb +2 -2
  5. data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -6
  6. data/lib/milk_tea/core/bindings/module_binding.rb +1 -1
  7. data/lib/milk_tea/core/intrinsics.rb +23 -1
  8. data/lib/milk_tea/core/lowering/functions.rb +3 -0
  9. data/lib/milk_tea/core/lowering/resolve.rb +4 -65
  10. data/lib/milk_tea/core/lowering/utils.rb +0 -17
  11. data/lib/milk_tea/core/lowering.rb +1 -2
  12. data/lib/milk_tea/core/module_binder.rb +4 -15
  13. data/lib/milk_tea/core/module_loader.rb +0 -2
  14. data/lib/milk_tea/core/parser/declarations.rb +24 -17
  15. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -111
  16. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -2
  17. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +26 -17
  18. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +26 -42
  19. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -59
  20. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +0 -2
  21. data/lib/milk_tea/core/types/predicates.rb +57 -0
  22. data/lib/milk_tea/core/types.rb +0 -4
  23. data/lib/milk_tea/lsp/diagnostics.rb +15 -5
  24. data/lib/milk_tea/lsp/server/code_actions.rb +0 -4
  25. data/lib/milk_tea/lsp/server/completion.rb +100 -77
  26. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +4 -6
  27. data/lib/milk_tea/lsp/server/formatting.rb +13 -3
  28. data/lib/milk_tea/lsp/server/hover.rb +321 -41
  29. data/lib/milk_tea/lsp/server/lifecycle.rb +12 -0
  30. data/lib/milk_tea/lsp/server/references.rb +3 -1
  31. data/lib/milk_tea/lsp/server/semantic_tokens.rb +55 -16
  32. data/lib/milk_tea/lsp/server/text_documents.rb +2 -2
  33. data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -2
  34. data/lib/milk_tea/lsp/server/utilities.rb +4 -0
  35. data/lib/milk_tea/lsp/server.rb +9 -0
  36. data/lib/milk_tea/lsp/workspace/analysis.rb +14 -3
  37. data/lib/milk_tea/lsp/workspace/caches.rb +17 -1
  38. data/lib/milk_tea/lsp/workspace/collection.rb +4 -0
  39. data/lib/milk_tea/lsp/workspace/module_index.rb +134 -0
  40. data/lib/milk_tea/lsp/workspace/store.rb +9 -4
  41. data/lib/milk_tea/lsp/workspace.rb +8 -0
  42. data/lib/milk_tea/tooling/formatter.rb +2 -3
  43. data/lib/milk_tea/tooling/linter/fix_engine.rb +46 -0
  44. data/lib/milk_tea/tooling/linter/rules.rb +32 -0
  45. data/lib/milk_tea/tooling/linter.rb +4 -0
  46. data/lib/milk_tea/tooling.rb +0 -1
  47. metadata +4 -3
  48. data/lib/milk_tea/tooling/cst_formatter.rb +0 -13
@@ -42,7 +42,7 @@ module MilkTea
42
42
  end
43
43
 
44
44
  methods, private_methods = exported_methods(analysis, types)
45
- implemented_interfaces, private_implemented_interfaces = exported_interface_implementations(analysis, types, interfaces)
45
+ implemented_interfaces = exported_interface_implementations(analysis, types, interfaces)
46
46
 
47
47
  Bindings::ModuleBinding.new(
48
48
  name: analysis.module_name,
@@ -62,7 +62,6 @@ module MilkTea
62
62
  private_values:,
63
63
  private_functions:,
64
64
  private_methods:,
65
- private_implemented_interfaces:,
66
65
  )
67
66
  end
68
67
 
@@ -102,28 +101,18 @@ module MilkTea
102
101
 
103
102
  def exported_interface_implementations(analysis, exported_types, exported_interfaces)
104
103
  implemented_interfaces = {}
105
- private_implemented_interfaces = {}
106
104
 
107
105
  analysis.implemented_interfaces.each do |receiver_type, interfaces|
108
- public_interfaces = []
109
- hidden_interfaces = []
110
-
111
- interfaces.each do |interface|
112
- visible = exported_method_receiver?(receiver_type, analysis, exported_types) &&
106
+ public_interfaces = interfaces.select do |interface|
107
+ exported_method_receiver?(receiver_type, analysis, exported_types) &&
113
108
  exported_interface_binding?(interface, analysis, exported_interfaces) &&
114
109
  exported_interface_methods?(receiver_type, interface, analysis, exported_types)
115
- if visible
116
- public_interfaces << interface
117
- else
118
- hidden_interfaces << interface
119
- end
120
110
  end
121
111
 
122
112
  implemented_interfaces[receiver_type] = public_interfaces.freeze unless public_interfaces.empty?
123
- private_implemented_interfaces[receiver_type] = hidden_interfaces.freeze unless hidden_interfaces.empty?
124
113
  end
125
114
 
126
- [implemented_interfaces.freeze, private_implemented_interfaces.freeze]
115
+ implemented_interfaces.freeze
127
116
  end
128
117
 
129
118
  def exported_interface_methods?(receiver_type, interface, analysis, exported_types)
@@ -691,7 +691,6 @@ module MilkTea
691
691
  private_values: full_binding.private_values,
692
692
  private_functions: full_binding.private_functions,
693
693
  private_methods: full_binding.private_methods,
694
- private_implemented_interfaces: full_binding.private_implemented_interfaces,
695
694
  )
696
695
  end
697
696
  end
@@ -728,7 +727,6 @@ module MilkTea
728
727
  implemented_interfaces: {}, imports: {},
729
728
  private_types: {}, private_interfaces: {}, private_attributes: {},
730
729
  private_values: {}, private_functions: {}, private_methods: {},
731
- private_implemented_interfaces: {},
732
730
  )
733
731
  end
734
732
 
@@ -369,10 +369,11 @@ module MilkTea
369
369
  AST::AttributeDecl.new(name: name_token.lexeme, targets:, params:, visibility:, line:, column: name_token.column)
370
370
  end
371
371
 
372
- def parse_struct_decl(packed: false, alignment: nil, visibility: :private, attributes: [], inline_methods: true)
372
+ def parse_struct_decl(packed: false, alignment: nil, visibility: :private, attributes: [], qualified_parts: [])
373
373
  line = previous.line
374
374
  name_token = consume_name("expected struct name")
375
375
  name = name_token.lexeme
376
+ qualified_name = qualified_parts + [name]
376
377
  lifetime_params, type_params = parse_struct_decl_params
377
378
  implements = parse_implements_clause
378
379
  c_name = parse_optional_c_name
@@ -380,29 +381,33 @@ module MilkTea
380
381
  receiver_type_param_names = type_params.map(&:name)
381
382
  members = with_type_param_names(receiver_type_param_names) do
382
383
  parse_recoverable_block do
383
- parse_struct_member
384
+ parse_struct_member(qualified_name)
384
385
  end
385
386
  end
386
387
  fields = members.filter_map { |kind, member| member if kind == :field }
387
388
  events = members.filter_map { |kind, member| member if kind == :event }
388
389
  nested_types = members.filter_map { |kind, member| member if kind == :nested_type }
389
390
  methods = members.filter_map { |kind, member| member if kind == :method }
391
+ nested_extending_blocks = members.filter_map { |kind, _, blocks| blocks if kind == :nested_type }.flatten(1)
390
392
  struct_decl = AST::StructDecl.new(name:, type_params:, implements:, c_name:, fields:, events:, nested_types:, attributes:, packed:, alignment:, visibility:, lifetime_params:, line:, column: name_token.column)
391
393
 
392
- if inline_methods && methods.any?
393
- type_ref_args = type_params.map do |tp|
394
- AST::TypeArgument.new(
395
- value: AST::TypeRef.new(name: AST::QualifiedName.new(parts: [tp.name]), arguments: [], nullable: false, line: tp.line, column: tp.column),
396
- line: tp.line,
397
- column: tp.column,
398
- )
399
- end
400
- type_ref = AST::TypeRef.new(name: AST::QualifiedName.new(parts: [name]), arguments: type_ref_args, nullable: false, line: name_token.line, column: name_token.column)
401
- extending_block = AST::ExtendingBlock.new(type_name: type_ref, methods:, line: name_token.line, column: name_token.column)
402
- [struct_decl, extending_block]
403
- else
404
- struct_decl
394
+ extending_blocks = []
395
+ extending_blocks << inline_methods_extending_block(qualified_name, type_params, methods, name_token) if methods.any?
396
+ extending_blocks.concat(nested_extending_blocks)
397
+
398
+ extending_blocks.empty? ? struct_decl : [struct_decl, *extending_blocks]
399
+ end
400
+
401
+ def inline_methods_extending_block(qualified_name, type_params, methods, name_token)
402
+ type_ref_args = type_params.map do |tp|
403
+ AST::TypeArgument.new(
404
+ value: AST::TypeRef.new(name: AST::QualifiedName.new(parts: [tp.name]), arguments: [], nullable: false, line: tp.line, column: tp.column),
405
+ line: tp.line,
406
+ column: tp.column,
407
+ )
405
408
  end
409
+ type_ref = AST::TypeRef.new(name: AST::QualifiedName.new(parts: qualified_name), arguments: type_ref_args, nullable: false, line: name_token.line, column: name_token.column)
410
+ AST::ExtendingBlock.new(type_name: type_ref, methods:, line: name_token.line, column: name_token.column, inline: true)
406
411
  end
407
412
 
408
413
  def parse_struct_decl_params
@@ -459,7 +464,7 @@ module MilkTea
459
464
  result
460
465
  end
461
466
 
462
- def parse_struct_member
467
+ def parse_struct_member(qualified_name)
463
468
  field_attributes = parse_attribute_applications
464
469
 
465
470
  if check_method_start?
@@ -475,7 +480,9 @@ module MilkTea
475
480
 
476
481
  if check(:struct) && !check_next(:colon)
477
482
  advance
478
- return [:nested_type, parse_struct_decl(visibility:, attributes: field_attributes, inline_methods: false)]
483
+ result = parse_struct_decl(visibility:, attributes: field_attributes, qualified_parts: qualified_name)
484
+ nested_decl, *nested_blocks = result.is_a?(Array) ? result : [result]
485
+ return [:nested_type, nested_decl, nested_blocks]
479
486
  end
480
487
 
481
488
  raise error(visibility_token, "public is only allowed on struct events") if visibility == :public
@@ -129,53 +129,23 @@ module MilkTea
129
129
  def validate_async_statement!(statement)
130
130
  case statement
131
131
  when AST::ErrorBlockStmt
132
- if statement.header_expression
133
- context = case statement.header_type
134
- when :if then "if conditions"
135
- when :while then "while conditions"
136
- end
137
- validate_async_expression_support!(statement.header_expression, context:) if context
138
- end
139
- if statement.header_type == :for
140
- Array(statement.header_iterables).each do |iterable|
141
- validate_async_expression_support!(iterable, context: "for iterables")
142
- end
143
- end
144
132
  statement.body.each { |s| validate_async_statement!(s) }
145
133
  when AST::ErrorStmt
146
134
  nil
147
135
  when AST::LocalDecl
148
- validate_async_expression_support!(statement.value, context: "local initializer") if statement.value
149
136
  statement.else_body&.each { |s| validate_async_statement!(s) }
150
- when AST::Assignment
151
- validate_async_expression_support!(statement.target, context: "assignment target")
152
- validate_async_expression_support!(statement.value, context: "assignment")
153
- when AST::ExpressionStmt
154
- validate_async_expression_support!(statement.expression, context: "expression statement")
155
- when AST::ReturnStmt
156
- return unless statement.value
157
-
158
- validate_async_expression_support!(statement.value, context: "return statement")
137
+ when AST::Assignment, AST::ExpressionStmt, AST::ReturnStmt
138
+ nil
159
139
  when AST::IfStmt
160
140
  statement.branches.each do |branch|
161
- validate_async_expression_support!(branch.condition, context: "if conditions")
162
-
163
141
  branch.body.each { |s| validate_async_statement!(s) }
164
142
  end
165
143
  statement.else_body&.each { |s| validate_async_statement!(s) }
166
144
  when AST::WhileStmt
167
- validate_async_expression_support!(statement.condition, context: "while conditions")
168
-
169
145
  statement.body.each { |s| validate_async_statement!(s) }
170
146
  when AST::ForStmt
171
- statement.iterables.each do |iterable|
172
- validate_async_expression_support!(iterable, context: "for iterables")
173
- end
174
-
175
147
  statement.body.each { |s| validate_async_statement!(s) }
176
148
  when AST::MatchStmt
177
- validate_async_expression_support!(statement.expression, context: "match discriminants")
178
-
179
149
  statement.arms.each { |arm| arm.body.each { |s| validate_async_statement!(s) } }
180
150
  when AST::UnsafeStmt
181
151
  statement.body.each { |s| validate_async_statement!(s) }
@@ -191,85 +161,6 @@ module MilkTea
191
161
  end
192
162
  end
193
163
 
194
- def validate_async_expression_support!(expression, context:)
195
- unsupported_context = unsupported_await_position(expression)
196
- return unless unsupported_context
197
-
198
- raise_sema_error("await in async functions is not supported inside #{unsupported_context} yet")
199
- end
200
-
201
- def unsupported_await_position(expression)
202
- nil
203
- end
204
-
205
- def statement_contains_await?(statement)
206
- case statement
207
- when AST::ErrorBlockStmt
208
- (statement.header_expression && expression_contains_await?(statement.header_expression)) ||
209
- Array(statement.header_iterables).any? { |iterable| expression_contains_await?(iterable) } ||
210
- statements_contain_await?(statement.body)
211
- when AST::LocalDecl
212
- (statement.value && expression_contains_await?(statement.value)) ||
213
- (statement.else_body && statements_contain_await?(statement.else_body))
214
- when AST::Assignment
215
- expression_contains_await?(statement.target) || expression_contains_await?(statement.value)
216
- when AST::IfStmt
217
- statement.branches.any? { |branch| expression_contains_await?(branch.condition) || statements_contain_await?(branch.body) } ||
218
- (statement.else_body && statements_contain_await?(statement.else_body))
219
- when AST::MatchStmt
220
- expression_contains_await?(statement.expression) || statement.arms.any? { |arm| expression_contains_await?(arm.pattern) || statements_contain_await?(arm.body) }
221
- when AST::UnsafeStmt
222
- statements_contain_await?(statement.body)
223
- when AST::StaticAssert
224
- expression_contains_await?(statement.condition) || expression_contains_await?(statement.message)
225
- when AST::ForStmt
226
- statement.iterables.any? { |iterable| expression_contains_await?(iterable) } || statements_contain_await?(statement.body)
227
- when AST::WhileStmt
228
- expression_contains_await?(statement.condition) || statements_contain_await?(statement.body)
229
- when AST::ReturnStmt
230
- statement.value && expression_contains_await?(statement.value)
231
- when AST::DeferStmt
232
- statements_contain_await?(statement.body)
233
- when AST::ExpressionStmt
234
- expression_contains_await?(statement.expression)
235
- else
236
- false
237
- end
238
- end
239
-
240
- def statements_contain_await?(statements)
241
- statements.any? { |statement| statement_contains_await?(statement) }
242
- end
243
-
244
- def expression_contains_await?(expression)
245
- case expression
246
- when AST::AwaitExpr
247
- true
248
- when AST::Call, AST::Specialization
249
- expression_contains_await?(expression.callee) || expression.arguments.any? { |argument| expression_contains_await?(argument.value) }
250
- when AST::UnaryOp
251
- expression_contains_await?(expression.operand)
252
- when AST::BinaryOp
253
- expression_contains_await?(expression.left) || expression_contains_await?(expression.right)
254
- when AST::IfExpr
255
- expression_contains_await?(expression.condition) || expression_contains_await?(expression.then_expression) || expression_contains_await?(expression.else_expression)
256
- when AST::MatchExpr
257
- expression_contains_await?(expression.expression) || expression.arms.any? { |arm| expression_contains_await?(arm.pattern) || expression_contains_await?(arm.value) }
258
- when AST::UnsafeExpr
259
- expression_contains_await?(expression.expression)
260
- when AST::PrefixCast
261
- expression_contains_await?(expression.expression)
262
- when AST::MemberAccess
263
- expression_contains_await?(expression.receiver)
264
- when AST::IndexAccess
265
- expression_contains_await?(expression.receiver) || expression_contains_await?(expression.index)
266
- when AST::FormatString
267
- expression.parts.any? { |part| part.is_a?(AST::FormatExprPart) && expression_contains_await?(part.expression) }
268
- else
269
- false
270
- end
271
- end
272
-
273
164
  def suggest_name(wrong, candidates, max_distance: 2)
274
165
  return nil if wrong.nil? || wrong.to_s.empty? || candidates.nil? || candidates.empty?
275
166
 
@@ -1309,7 +1309,7 @@ module MilkTea
1309
1309
  return [:has_attribute, nil, nil] if callee.name == "has_attribute"
1310
1310
  return [:get, nil, nil] if callee.name == "get"
1311
1311
 
1312
- type = @ctx.types[callee.name]
1312
+ type = lookup_named_type(callee.name)
1313
1313
  return [:struct, type, nil] if type.is_a?(Types::Struct) || type.is_a?(Types::StringView) || task_type?(type) || type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
1314
1314
  if type.is_a?(Types::GenericStructDefinition) || type.is_a?(Types::GenericVariantDefinition)
1315
1315
  raise_sema_error("generic type #{callee.name} requires type arguments")
@@ -1396,7 +1396,6 @@ module MilkTea
1396
1396
  return [:array_as_span, field_receiver_type, callee.receiver]
1397
1397
  end
1398
1398
 
1399
- return [:callable_value, field_receiver_type.field(callee.member), nil] if aggregate_type?(field_receiver_type) && callable_type?(field_receiver_type.field(callee.member))
1400
1399
  return [:callable_value, field_receiver_type.field(callee.member), nil] if aggregate_type?(field_receiver_type) && callable_type?(field_receiver_type.field(callee.member))
1401
1400
 
1402
1401
  if (imported_module = imported_module_with_private_method(method_receiver_type, callee.member))
@@ -22,25 +22,31 @@ module MilkTea
22
22
  when AST::ExtendingBlock
23
23
  dispatch_receiver_type, receiver_type, receiver_type_param_names, receiver_type_param_constraints = resolve_methods_receiver_target(decl.type_name)
24
24
 
25
- decl.methods.each do |method|
26
- begin
27
- binding = with_error_node(method) do
28
- declare_function_binding(
29
- method,
30
- receiver_type:,
31
- declared_receiver_type: receiver_type,
32
- receiver_type_param_names:,
33
- receiver_type_param_constraints:,
34
- )
35
- end
36
- instance_method = receiver_type && method.kind != :static
37
- method_key = instance_method ? binding.name : "static:#{binding.name}"
38
- raise_sema_error("duplicate method #{decl.type_name}.#{binding.name}") if @ctx.methods[dispatch_receiver_type].key?(method_key)
25
+ previous_nested_types = @current_nested_types
26
+ @current_nested_types = method_receiver_nested_scope(receiver_type)
27
+ begin
28
+ decl.methods.each do |method|
29
+ begin
30
+ binding = with_error_node(method) do
31
+ declare_function_binding(
32
+ method,
33
+ receiver_type:,
34
+ declared_receiver_type: receiver_type,
35
+ receiver_type_param_names:,
36
+ receiver_type_param_constraints:,
37
+ )
38
+ end
39
+ instance_method = receiver_type && method.kind != :static
40
+ method_key = instance_method ? binding.name : "static:#{binding.name}"
41
+ raise_sema_error("duplicate method #{decl.type_name}.#{binding.name}") if @ctx.methods[dispatch_receiver_type].key?(method_key)
39
42
 
40
- @ctx.methods[dispatch_receiver_type][method_key] = binding
41
- rescue SemanticError => e
42
- collect_structural_error(e)
43
+ @ctx.methods[dispatch_receiver_type][method_key] = binding
44
+ rescue SemanticError => e
45
+ collect_structural_error(e)
46
+ end
43
47
  end
48
+ ensure
49
+ @current_nested_types = previous_nested_types
44
50
  end
45
51
  end
46
52
  end
@@ -604,6 +610,7 @@ module MilkTea
604
610
  previous_type_substitutions = @current_type_substitutions
605
611
  previous_specialization_owner = @current_specialization_owner
606
612
  previous_value_type_params = @current_value_type_params
613
+ previous_nested_types = @current_nested_types
607
614
  started_check = false
608
615
  return if binding.external
609
616
  return if @checked_function_bindings[binding.object_id]
@@ -614,6 +621,7 @@ module MilkTea
614
621
  @current_type_substitutions = binding.type_substitutions
615
622
  @current_specialization_owner = binding.specialization_owner
616
623
  @current_value_type_params = resolve_value_type_params(binding.ast.type_params)
624
+ @current_nested_types = method_receiver_nested_scope(binding.declared_receiver_type)
617
625
  with_error_node(binding.ast) do
618
626
  with_scope(binding.body_params) do |scopes|
619
627
  start_local_completion_frame(binding, scopes)
@@ -669,6 +677,7 @@ module MilkTea
669
677
  @current_type_substitutions = previous_type_substitutions
670
678
  @current_specialization_owner = previous_specialization_owner
671
679
  @current_value_type_params = previous_value_type_params
680
+ @current_nested_types = previous_nested_types
672
681
  @checking_function_bindings.delete(binding.object_id)
673
682
  end
674
683
 
@@ -236,7 +236,7 @@ module MilkTea
236
236
  end
237
237
  end
238
238
 
239
- def resolve_type_ref(type_ref, type_params: current_type_params, type_param_constraints: current_type_param_constraints, nested_types: nil)
239
+ def resolve_type_ref(type_ref, type_params: current_type_params, type_param_constraints: current_type_param_constraints, nested_types: current_nested_types)
240
240
  base = resolve_non_nullable_type(type_ref, type_params:, type_param_constraints:, nested_types:)
241
241
  return base if type_ref.is_a?(AST::FunctionType) || type_ref.is_a?(AST::ProcType) || type_ref.is_a?(AST::TupleType)
242
242
 
@@ -247,11 +247,11 @@ module MilkTea
247
247
 
248
248
  def resolve_non_nullable_type(type_ref, type_params: {}, type_param_constraints: {}, nested_types: nil)
249
249
  if type_ref.is_a?(AST::FunctionType)
250
- return resolve_function_type_ref(type_ref, type_params:, type_param_constraints:)
250
+ return resolve_function_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
251
251
  end
252
252
 
253
253
  if type_ref.is_a?(AST::ProcType)
254
- return resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:)
254
+ return resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
255
255
  end
256
256
 
257
257
  if type_ref.is_a?(AST::DynType)
@@ -259,13 +259,13 @@ module MilkTea
259
259
  end
260
260
 
261
261
  if type_ref.is_a?(AST::TupleType)
262
- return resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:)
262
+ return resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
263
263
  end
264
264
 
265
265
  parts = type_ref.name.parts
266
266
 
267
267
  if type_ref.arguments.any?
268
- return resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:)
268
+ return resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:, nested_types:)
269
269
  end
270
270
 
271
271
  if parts.length == 1 && type_ref.lifetime
@@ -279,18 +279,18 @@ module MilkTea
279
279
  resolve_multi_part_type_ref(type_ref, parts)
280
280
  end
281
281
 
282
- def resolve_function_type_ref(type_ref, type_params:, type_param_constraints:)
282
+ def resolve_function_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
283
283
  params = type_ref.params.map do |param|
284
- Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
284
+ Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:, nested_types:))
285
285
  end
286
- Types::Registry.function(nil, params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
286
+ Types::Registry.function(nil, params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:, nested_types:))
287
287
  end
288
288
 
289
- def resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:)
289
+ def resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
290
290
  params = type_ref.params.map do |param|
291
- Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
291
+ Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:, nested_types:))
292
292
  end
293
- Types::Registry.proc(params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
293
+ Types::Registry.proc(params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:, nested_types:))
294
294
  end
295
295
 
296
296
  def resolve_dyn_type_ref(type_ref)
@@ -302,25 +302,25 @@ module MilkTea
302
302
  type
303
303
  end
304
304
 
305
- def resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:)
305
+ def resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
306
306
  names = []
307
307
  element_types = []
308
308
  type_ref.element_types.each do |et|
309
309
  if et.is_a?(AST::Argument)
310
310
  names << et.name
311
- element_types << resolve_type_ref(et.value, type_params:, type_param_constraints:)
311
+ element_types << resolve_type_ref(et.value, type_params:, type_param_constraints:, nested_types:)
312
312
  else
313
313
  names << nil
314
- element_types << resolve_type_ref(et, type_params:, type_param_constraints:)
314
+ element_types << resolve_type_ref(et, type_params:, type_param_constraints:, nested_types:)
315
315
  end
316
316
  end
317
317
  has_named = names.any?
318
318
  Types::Registry.tuple(element_types, field_names: has_named ? names : nil)
319
319
  end
320
320
 
321
- def resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:)
321
+ def resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:, nested_types:)
322
322
  name = parts.join(".")
323
- arguments = type_ref.arguments.map { |argument| resolve_type_argument(argument.value, type_params:, type_param_constraints:) }
323
+ arguments = type_ref.arguments.map { |argument| resolve_type_argument(argument.value, type_params:, type_param_constraints:, nested_types:) }
324
324
 
325
325
  if name != "ref" && arguments.any? { |argument| contains_ref_type?(argument) && !stored_ref_supported_type?(argument) }
326
326
  raise_sema_error("ref types cannot be nested inside #{name}", type_ref)
@@ -434,12 +434,12 @@ module MilkTea
434
434
  value.is_a?(Types::Base) ? value : nil
435
435
  end
436
436
 
437
- def resolve_type_argument(argument, type_params: current_type_params, type_param_constraints: current_type_param_constraints)
437
+ def resolve_type_argument(argument, type_params: current_type_params, type_param_constraints: current_type_param_constraints, nested_types: current_nested_types)
438
438
  case argument
439
439
  when AST::TypeRef
440
- resolve_type_argument_ref(argument, type_params:, type_param_constraints:)
440
+ resolve_type_argument_ref(argument, type_params:, type_param_constraints:, nested_types:)
441
441
  when AST::FunctionType, AST::ProcType, AST::TupleType
442
- resolve_type_ref(argument, type_params:, type_param_constraints:)
442
+ resolve_type_ref(argument, type_params:, type_param_constraints:, nested_types:)
443
443
  when AST::IntegerLiteral, AST::FloatLiteral
444
444
  Types::LiteralTypeArg.new(argument.value)
445
445
  else
@@ -447,20 +447,20 @@ module MilkTea
447
447
  end
448
448
  end
449
449
 
450
- def resolve_type_argument_ref(type_ref, type_params:, type_param_constraints:)
451
- return resolve_type_ref(type_ref, type_params:, type_param_constraints:) unless literal_type_argument_name_candidate?(type_ref)
450
+ def resolve_type_argument_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
451
+ return resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:) unless literal_type_argument_name_candidate?(type_ref)
452
452
 
453
- result = try_resolve_type_ref(type_ref, type_params:, type_param_constraints:)
453
+ result = try_resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
454
454
  return result if result
455
455
 
456
456
  literal_type_argument = resolve_named_literal_type_argument(type_ref)
457
457
  return literal_type_argument if literal_type_argument
458
458
 
459
- resolve_type_ref(type_ref, type_params:, type_param_constraints:)
459
+ resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
460
460
  end
461
461
 
462
- def try_resolve_type_ref(type_ref, type_params:, type_param_constraints:)
463
- resolve_type_ref(type_ref, type_params:, type_param_constraints:)
462
+ def try_resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
463
+ resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
464
464
  rescue SemanticError
465
465
  nil
466
466
  end
@@ -867,10 +867,6 @@ module MilkTea
867
867
  Types.pointer_to(type)
868
868
  end
869
869
 
870
- def contains_type_var?(type)
871
- super
872
- end
873
-
874
870
  def resolve_nested_type_ref(parts)
875
871
  current = @ctx.types[parts.first]
876
872
  return nil unless current.is_a?(Types::Struct) || current.is_a?(Types::GenericStructDefinition)
@@ -975,18 +971,6 @@ module MilkTea
975
971
  nil
976
972
  end
977
973
 
978
- def collection_loop_type(type)
979
- super
980
- end
981
-
982
- def collection_loop_binding_type(iterable_type, element_type)
983
- super
984
- end
985
-
986
- def collection_loop_ref_element_type?(type)
987
- super
988
- end
989
-
990
974
  def iterator_loop_type(type)
991
975
  type = referenced_type(type) if ref_type?(type)
992
976
  iter_method = lookup_method(type, "iter")
@@ -1091,7 +1075,7 @@ module MilkTea
1091
1075
  when AST::Identifier
1092
1076
  return current_type_params[expression.name] if current_type_params.key?(expression.name)
1093
1077
 
1094
- @ctx.types[expression.name]
1078
+ lookup_named_type(expression.name)
1095
1079
  when AST::MemberAccess
1096
1080
  return nil unless expression.receiver.is_a?(AST::Identifier)
1097
1081
 
@@ -164,65 +164,6 @@ module MilkTea
164
164
  backing_type.integer_width == expected_type.integer_width
165
165
  end
166
166
 
167
- def common_numeric_type(left_type, right_type)
168
- left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
169
- right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
170
- return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
171
- return unless left_type.numeric? && right_type.numeric?
172
- return left_type if left_type == right_type
173
-
174
- return common_integer_type(left_type, right_type) if left_type.integer? && right_type.integer?
175
- return wider_float_type(left_type, right_type) if left_type.float? && right_type.float?
176
-
177
- float_type, integer_type = left_type.float? ? [left_type, right_type] : [right_type, left_type]
178
- return unless integer_type.integer? && integer_type.fixed_width_integer?
179
-
180
- float_type
181
- end
182
-
183
- def common_integer_type(left_type, right_type)
184
- left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
185
- right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
186
- return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
187
- return unless left_type.integer? && right_type.integer?
188
- return left_type if left_type == right_type
189
- return unless left_type.fixed_width_integer? && right_type.fixed_width_integer?
190
-
191
- # Same signedness: the wider type wins (both operands are losslessly
192
- # assignable to it).
193
- if left_type.signed_integer? == right_type.signed_integer?
194
- return left_type.integer_width >= right_type.integer_width ? left_type : right_type
195
- end
196
-
197
- # Mixed signed/unsigned: promote to the narrowest signed type that holds
198
- # both operands' full ranges, mirroring the lossless assignment rule. A
199
- # strictly-wider signed type covers an unsigned operand; equal-width or
200
- # wider unsigned operands widen to the next signed width. Mixing with a
201
- # 64-bit unsigned type has no safe signed common type, so callers fall
202
- # back to requiring an explicit cast.
203
- signed_type, unsigned_type = if left_type.signed_integer?
204
- [left_type, right_type]
205
- else
206
- [right_type, left_type]
207
- end
208
-
209
- return signed_type if signed_type.integer_width > unsigned_type.integer_width
210
-
211
- signed_type_above_width(unsigned_type.integer_width)
212
- end
213
-
214
- def signed_type_above_width(width)
215
- case width
216
- when 8 then @ctx.types.fetch("short")
217
- when 16 then @ctx.types.fetch("int")
218
- when 32 then @ctx.types.fetch("long")
219
- end
220
- end
221
-
222
- def wider_float_type(left_type, right_type)
223
- left_type.float_width >= right_type.float_width ? left_type : right_type
224
- end
225
-
226
167
  def pointer_arithmetic_result(operator, left_type, right_type)
227
168
  if pointer_type?(left_type) && integer_type?(right_type)
228
169
  require_unsafe!("pointer arithmetic requires unsafe") unless own_type?(left_type)
@@ -186,7 +186,6 @@ module MilkTea
186
186
  implemented_interfaces: {}, imports: {},
187
187
  private_types: {}, private_interfaces: {}, private_attributes: {},
188
188
  private_values: {}, private_functions: {}, private_methods: {},
189
- private_implemented_interfaces: {},
190
189
  )
191
190
  end
192
191
 
@@ -342,7 +341,6 @@ module MilkTea
342
341
  params: params.freeze,
343
342
  module_name: @ctx.module_name,
344
343
  builtin: false,
345
- ast: decl,
346
344
  )
347
345
  end
348
346
  end