mt-lang 0.3.31 → 0.3.33

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16833c6b95c7e580f12199a381802f47ac628b7252f4bc1647714098cbd4f824
4
- data.tar.gz: 296b0547096ceee9d394edc13df6f042e2b8ed6d42c98b4745e1b39885407b85
3
+ metadata.gz: d03b5daec92d1aeea437f63bd934696f684e524e76985470d416f0bea8d61002
4
+ data.tar.gz: f83f7c79a70a575e0827819865c75955be0c4c03bb6761570afc4bb0df1a75ff
5
5
  SHA512:
6
- metadata.gz: '080aa9b4ad981dce767373642fe8c81fef77bf4b4c364b60e2b5dc633e7e1a2f593187ebcc3903a15aebec587bd6989a844dfd8fd842fb8b61fc855a5ba9ce86'
7
- data.tar.gz: b9c60e1298c8fb8195401875f3d77358965741c1537cb674696d71ca1b5ef8f8ce5289d7a4e3491bbca24bd485481d6fd65df531a975237c08da888539c30b9e
6
+ metadata.gz: 7f30fbf67b0723afe3b16c14706b817c7b8adea64a0064cb2b7ecb0ff7935efab149a60eb84ced949bc7e6c5da922338d884ee20f1023a2f86ee78b47d2ee8c9
7
+ data.tar.gz: 4d879d9b77dce83a2900f04669c1d858f91c84d6cf101adedfce327b4a18be886f68425429e9dd630c00286d6f1ef53a2e97834ddcbaa30a79726cbe2c66193a
data/lib/milk_tea/base.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "pathname"
4
4
 
5
5
  module MilkTea
6
- VERSION = "0.3.31"
6
+ VERSION = "0.3.33"
7
7
 
8
8
  def self.root
9
9
  @root ||= Pathname.new(File.expand_path("../..", __dir__))
@@ -76,19 +76,12 @@ module MilkTea
76
76
  fields = Array(node["inner"]).select { |child| child["kind"] == "FieldDecl" }
77
77
  fields.each do |field|
78
78
  field_type = aggregate_field_type(field, owner_name: name, aggregate_node: node)
79
- mt_name, = bindgen_field_name(emitted_name(aggregate_field_name(field, aggregate_node: node)))
79
+ mt_name = emitted_name(aggregate_field_name(field, aggregate_node: node))
80
80
  lines << " #{mt_name}: #{field_type}"
81
81
  end
82
82
  lines
83
83
  end
84
84
 
85
- def bindgen_field_name(name)
86
- name = emitted_name(name)
87
- return [name, nil] unless Token::KEYWORDS.key?(name)
88
-
89
- ["#{name}_", nil]
90
- end
91
-
92
85
  def bindgen_param_name(name)
93
86
  name = emitted_name(name)
94
87
  return [name, nil] unless generated_binding_name_conflict?(name)
@@ -437,7 +437,7 @@ module MilkTea
437
437
  resolve_identifier: ->(id) { @variables[id.name] || @checker.evaluate_compile_time_const_value(id, scopes:) },
438
438
  resolve_member_access: ->(ma) { @checker.evaluate_compile_time_const_value(ma, scopes:) },
439
439
  resolve_type_ref: nil,
440
- resolve_call: nil,
440
+ resolve_call: ->(call_expr) { resolve_compile_time_call(call_expr, scopes:) },
441
441
  )
442
442
  end
443
443
  return nil unless arg_value
@@ -56,16 +56,10 @@ module MilkTea
56
56
  def build_statement(stmt, next_id, break_target:, continue_target:)
57
57
  case stmt
58
58
  when AST::LocalDecl
59
- if stmt.else_body
60
- reads, reads_info = read_identifiers_with_sites(stmt.value)
61
- writes = Set.new
62
- writes_info = []
63
- declaration_key = declaration_binding_key(stmt, stmt.name)
64
- if declaration_key && (stmt.value || @local_decl_without_initializer_writes)
65
- writes << declaration_key
66
- writes_info << { name: stmt.name, binding_key: declaration_key, line: stmt.line, column: stmt.column, origin: :declaration }
67
- end
59
+ reads, reads_info = read_identifiers_with_sites(stmt.value)
60
+ writes, writes_info = local_decl_write_targets(stmt, stmt.name)
68
61
 
62
+ if stmt.else_body
69
63
  success_id = add_linear_node(:local_decl, stmt, next_id, writes:, writes_info:)
70
64
  null_entry = build_block(stmt.else_body, next_id, break_target:, continue_target:)
71
65
  condition_id = @graph.add_node(
@@ -80,14 +74,6 @@ module MilkTea
80
74
  return condition_id
81
75
  end
82
76
 
83
- reads, reads_info = read_identifiers_with_sites(stmt.value)
84
- writes = Set.new
85
- writes_info = []
86
- declaration_key = declaration_binding_key(stmt, stmt.name)
87
- if declaration_key && (stmt.value || @local_decl_without_initializer_writes)
88
- writes << declaration_key
89
- writes_info << { name: stmt.name, binding_key: declaration_key, line: stmt.line, column: stmt.column, origin: :declaration }
90
- end
91
77
  add_linear_node(:local_decl, stmt, next_id, reads:, reads_info:, writes:, writes_info:)
92
78
  when AST::Assignment
93
79
  reads, reads_info = read_identifiers_with_sites(stmt.value)
@@ -213,13 +199,10 @@ module MilkTea
213
199
  build_block(stmt.body, next_id, break_target:, continue_target:)
214
200
  when AST::DeferStmt
215
201
  body_entry = build_block(stmt.body, next_id, break_target:, continue_target:)
216
- expression_reads, expression_reads_info = statement_list_reads_with_sites(stmt.body)
217
202
  defer_id = @graph.add_node(
218
203
  kind: :defer,
219
204
  statement: stmt,
220
205
  line: stmt.line,
221
- reads: expression_reads,
222
- reads_info: expression_reads_info,
223
206
  )
224
207
  @graph.add_edge(defer_id, body_entry)
225
208
  defer_id
@@ -315,66 +298,6 @@ module MilkTea
315
298
  [reads, reads_info]
316
299
  end
317
300
 
318
- def statement_list_reads_with_sites(statements)
319
- reads = Set.new
320
- reads_info = []
321
- statement_list_read_identifiers(statements, reads, reads_info)
322
- [reads, reads_info]
323
- end
324
-
325
- def statement_list_read_identifiers(statements, reads, reads_info)
326
- Array(statements).each do |statement|
327
- statement_read_identifiers(statement, reads, reads_info)
328
- end
329
- end
330
-
331
- def statement_read_identifiers(statement, reads, reads_info)
332
- case statement
333
- when AST::ExpressionStmt
334
- read_identifiers(statement.expression, reads, reads_info)
335
- when AST::DeferStmt
336
- statement_list_read_identifiers(statement.body, reads, reads_info)
337
- when AST::LocalDecl
338
- read_identifiers(statement.value, reads, reads_info)
339
- statement_list_read_identifiers(statement.else_body, reads, reads_info)
340
- when AST::Assignment
341
- read_identifiers(statement.target, reads, reads_info)
342
- read_identifiers(statement.value, reads, reads_info)
343
- when AST::ReturnStmt
344
- read_identifiers(statement.value, reads, reads_info)
345
- when AST::IfStmt
346
- statement.branches.each do |branch|
347
- read_identifiers(branch.condition, reads, reads_info)
348
- statement_list_read_identifiers(branch.body, reads, reads_info)
349
- end
350
- statement_list_read_identifiers(statement.else_body, reads, reads_info)
351
- when AST::WhileStmt
352
- read_identifiers(statement.condition, reads, reads_info)
353
- statement_list_read_identifiers(statement.body, reads, reads_info)
354
- when AST::ForStmt
355
- statement.iterables.each { |iterable| read_identifiers(iterable, reads, reads_info) }
356
- statement_list_read_identifiers(statement.body, reads, reads_info)
357
- when AST::UnsafeStmt
358
- statement_list_read_identifiers(statement.body, reads, reads_info)
359
- when AST::MatchStmt
360
- read_identifiers(statement.expression, reads, reads_info)
361
- statement.arms.each do |arm|
362
- read_identifiers(arm.pattern, reads, reads_info)
363
- statement_list_read_identifiers(arm.body, reads, reads_info)
364
- end
365
- when AST::StaticAssert
366
- read_identifiers(statement.condition, reads, reads_info)
367
- read_identifiers(statement.message, reads, reads_info)
368
- when AST::WhenStmt
369
- read_identifiers(statement.discriminant, reads, reads_info)
370
- statement.branches.each do |branch|
371
- read_identifiers(branch.pattern, reads, reads_info)
372
- statement_list_read_identifiers(branch.body, reads, reads_info)
373
- end
374
- statement_list_read_identifiers(statement.else_body, reads, reads_info)
375
- end
376
- end
377
-
378
301
  def read_identifiers(expression, names = Set.new, reads_info = [])
379
302
  case expression
380
303
  when nil
@@ -582,6 +505,18 @@ module MilkTea
582
505
  name
583
506
  end
584
507
 
508
+ def local_decl_write_targets(stmt, name)
509
+ writes = Set.new
510
+ writes_info = []
511
+ declaration_key = declaration_binding_key(stmt, name)
512
+ if declaration_key && (stmt.value || @local_decl_without_initializer_writes)
513
+ writes << declaration_key
514
+ writes_info << { name:, binding_key: declaration_key, line: stmt.line, column: stmt.column, origin: :declaration }
515
+ end
516
+ write_targets_from_expression(stmt.value, line: stmt.line, writes:, writes_info:)
517
+ [writes, writes_info]
518
+ end
519
+
585
520
  def add_null_test_refinements(cond_id, true_succ, false_succ, condition)
586
521
  pairs = null_check_pairs(condition, positive: true)
587
522
  return if pairs.empty?
@@ -324,7 +324,7 @@ module MilkTea
324
324
  newline_start = line_offset + line.length
325
325
  newline_end = has_newline ? (newline_start + 1) : newline_start
326
326
  if @grouping_depth.zero?
327
- if Token::LINE_CONTINUATION_OPERATORS.include?(@tokens.last&.type)
327
+ if Token::LINE_CONTINUATION_OPERATORS.include?(@tokens.last&.type) && !trailing_is_member_access?
328
328
  @continuation_pending = true
329
329
  else
330
330
  @tokens << build_token(:newline, "\n", nil, line_number, line.length + 1, start_offset: newline_start, end_offset: newline_end)
@@ -345,6 +345,10 @@ module MilkTea
345
345
  1
346
346
  end
347
347
 
348
+ def trailing_is_member_access?
349
+ @tokens.last&.type == :is && @tokens[-2]&.type == :dot
350
+ end
351
+
348
352
  def emit_newline(line, line_number, line_offset, has_newline)
349
353
  newline_start = line_offset + line.bytesize
350
354
  newline_end = has_newline ? (newline_start + 1) : newline_start
@@ -26,9 +26,9 @@ module MilkTea
26
26
 
27
27
  next if type == Types::BUILTIN_TYPE_META_TYPE
28
28
 
29
- if const_value && (decl.value.is_a?(AST::Call) || decl.value.is_a?(AST::Specialization))
29
+ if !const_value.nil? && (decl.value.is_a?(AST::Call) || decl.value.is_a?(AST::Specialization))
30
30
  value = lower_const_value_literal(type, const_value)
31
- elsif const_value && (decl.block_body || decl.value.is_a?(AST::ExpressionList))
31
+ elsif !const_value.nil? && (decl.block_body || decl.value.is_a?(AST::ExpressionList))
32
32
  if const_value.is_a?(Array) && const_value.empty? && decl.value.is_a?(AST::ExpressionList) && !decl.value.elements.empty?
33
33
  value = lower_static_storage_initializer(decl.value, env: empty_env, expected_type: type)
34
34
  else
@@ -38,12 +38,46 @@ module MilkTea
38
38
  raise LoweringError.new("constant #{decl.name} has no compile-time value", line: decl.line, column: decl.column)
39
39
  else
40
40
  value = lower_static_storage_initializer(decl.value, env: empty_env, expected_type: type)
41
+ if (decl.value.is_a?(AST::Call) || decl.value.is_a?(AST::Specialization)) && static_initializer_ir_has_call?(value)
42
+ raise LoweringError.new("constant #{decl.name} initializer is not a compile-time value", line: decl.line, column: decl.column, path: @ctx.current_analysis_path)
43
+ end
41
44
  end
42
45
 
43
46
  IR::Constant.new(name: decl.name, linkage_name: value_c_name(decl.name), type:, value:, line: decl.line, path: @ctx.current_analysis_path)
44
47
  end
45
48
  end
46
49
 
50
+ def static_initializer_ir_has_call?(node)
51
+ case node
52
+ when IR::Call
53
+ true
54
+ when IR::AggregateLiteral
55
+ node.fields.any? { |field| static_initializer_ir_has_call?(field.value) }
56
+ when IR::ArrayLiteral
57
+ node.elements.any? { |element| static_initializer_ir_has_call?(element) }
58
+ when IR::VariantLiteral
59
+ node.fields.any? { |field| static_initializer_ir_has_call?(field.value) }
60
+ when IR::Binary
61
+ static_initializer_ir_has_call?(node.left) || static_initializer_ir_has_call?(node.right)
62
+ when IR::Unary
63
+ static_initializer_ir_has_call?(node.operand)
64
+ when IR::Conditional
65
+ static_initializer_ir_has_call?(node.condition) || static_initializer_ir_has_call?(node.then_expression) || static_initializer_ir_has_call?(node.else_expression)
66
+ when IR::Cast
67
+ static_initializer_ir_has_call?(node.expression)
68
+ when IR::AddressOf
69
+ static_initializer_ir_has_call?(node.expression)
70
+ when IR::Member
71
+ static_initializer_ir_has_call?(node.receiver)
72
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
73
+ static_initializer_ir_has_call?(node.receiver) || static_initializer_ir_has_call?(node.index)
74
+ when IR::ReinterpretExpr
75
+ static_initializer_ir_has_call?(node.expression)
76
+ else
77
+ false
78
+ end
79
+ end
80
+
47
81
  def lower_const_value_literal(type, const_value)
48
82
  case const_value
49
83
  when Integer
@@ -1323,10 +1323,10 @@ module MilkTea
1323
1323
  IR::FloatLiteral.new(value: expression.value, type:)
1324
1324
  when AST::SizeofExpr
1325
1325
  target_type = resolve_type_ref_with_fallback(expression.type, env:)
1326
- target_type ? IR::SizeofExpr.new(target_type:, type:) : raise(LoweringError, "size_of argument is not a concrete type")
1326
+ target_type ? IR::SizeofExpr.new(target_type:, type:) : raise(LoweringError.new("size_of argument is not a concrete type", line: expression.line, column: expression.column, path: @ctx.current_analysis_path))
1327
1327
  when AST::AlignofExpr
1328
1328
  target_type = resolve_type_ref_with_fallback(expression.type, env:)
1329
- target_type ? IR::AlignofExpr.new(target_type:, type:) : raise(LoweringError, "align_of argument is not a concrete type")
1329
+ target_type ? IR::AlignofExpr.new(target_type:, type:) : raise(LoweringError.new("align_of argument is not a concrete type", line: expression.line, column: expression.column, path: @ctx.current_analysis_path))
1330
1330
  when AST::OffsetofExpr
1331
1331
  target_type = resolve_type_ref(expression.type)
1332
1332
  if !@bypass_sema_type_cache && (precomputed = @ctx.const_values[@ctx.ast.node_ids[expression.object_id]])
@@ -1348,6 +1348,8 @@ module MilkTea
1348
1348
  binding = lookup_value(expression.name, env)
1349
1349
  if binding
1350
1350
  lower_bound_identifier(binding, expected_type:)
1351
+ elsif (value_param = value_param_literal(expression.name, type))
1352
+ value_param
1351
1353
  elsif @ctx.functions.key?(expression.name)
1352
1354
  function_binding = @ctx.functions.fetch(expression.name)
1353
1355
  raise LoweringError.new("generic function #{expression.name} cannot be used as a value", line: 0, column: 0, path: @ctx.current_analysis_path) if function_binding.type_params.any?
@@ -1699,13 +1701,24 @@ module MilkTea
1699
1701
  return unless expression
1700
1702
 
1701
1703
  ct_value = compile_time_const_value(expression, env:)
1702
- if ct_value.is_a?(Types::Struct) || ct_value.is_a?(Types::Primitive) ||
1703
- ct_value.is_a?(Types::Union) || ct_value.is_a?(Types::Nullable) ||
1704
- ct_value.is_a?(Types::StructInstance)
1704
+ if sized_layout_ct_value?(ct_value)
1705
1705
  ct_value
1706
1706
  end
1707
1707
  end
1708
1708
 
1709
+ def sized_layout_ct_value?(type)
1710
+ case type
1711
+ when Types::Primitive, Types::Struct, Types::StructInstance, Types::Union, Types::Enum, Types::Flags, Types::Variant, Types::Span, Types::StringView, Types::Task, Types::Event, Types::Subscription
1712
+ true
1713
+ when Types::Nullable
1714
+ true
1715
+ when Types::GenericInstance
1716
+ pointer_type?(type) || array_type?(type) || str_buffer_type?(type)
1717
+ else
1718
+ false
1719
+ end
1720
+ end
1721
+
1709
1722
  def build_expression_from_qualified_name(qualified_name)
1710
1723
  parts = qualified_name.parts
1711
1724
  return unless parts.length >= 1
@@ -117,7 +117,9 @@ module MilkTea
117
117
  env = empty_env
118
118
  parameter_setup = []
119
119
  previous_type_substitutions = @ctx.current_type_substitutions
120
+ previous_value_type_params = @ctx.current_value_type_params
120
121
  @ctx.current_type_substitutions = binding.type_substitutions
122
+ @ctx.current_value_type_params = resolve_value_type_params(decl.type_params)
121
123
 
122
124
  return lower_async_function_decl(binding, receiver_type:) if binding.async
123
125
 
@@ -176,6 +178,15 @@ module MilkTea
176
178
  )
177
179
  ensure
178
180
  @ctx.current_type_substitutions = previous_type_substitutions
181
+ @ctx.current_value_type_params = previous_value_type_params
182
+ end
183
+
184
+ def resolve_value_type_params(type_params)
185
+ type_params.each_with_object({}) do |type_param, map|
186
+ next unless type_param.is_a?(AST::ValueTypeParam)
187
+
188
+ map[type_param.name] = resolve_type_ref(type_param.type, type_params: current_type_params)
189
+ end
179
190
  end
180
191
 
181
192
  def lower_async_function_decl(binding, receiver_type: nil)
@@ -9,6 +9,7 @@ module MilkTea
9
9
  attr_accessor :methods, :attributes, :attribute_applications, :implemented_interfaces
10
10
  attr_accessor :struct_types, :union_types, :opaque_types
11
11
  attr_accessor :current_type_substitutions
12
+ attr_accessor :current_value_type_params
12
13
  attr_accessor :resolved_expr_types
13
14
  attr_accessor :resolved_call_kinds
14
15
  attr_accessor :const_values
@@ -27,6 +28,7 @@ module MilkTea
27
28
  @attribute_applications = {}
28
29
  @implemented_interfaces = {}
29
30
  @current_type_substitutions = nil
31
+ @current_value_type_params = nil
30
32
  @resolved_expr_types = {}
31
33
  @resolved_call_kinds = {}
32
34
  @const_values = {}
@@ -699,7 +699,7 @@ module MilkTea
699
699
  end
700
700
 
701
701
  def infer_expression_type(expression, env:, expected_type: nil)
702
- if !@bypass_sema_type_cache && expected_type.nil? && (id = @ctx.ast.node_ids[expression.object_id]) && (resolved = @ctx.resolved_expr_types[id])
702
+ if !@bypass_sema_type_cache && expected_type.nil? && !expression.is_a?(AST::Identifier) && (id = @ctx.ast.node_ids[expression.object_id]) && (resolved = @ctx.resolved_expr_types[id])
703
703
  return resolved
704
704
  end
705
705
 
@@ -740,6 +740,9 @@ module MilkTea
740
740
  when AST::Identifier
741
741
  binding = lookup_value(expression.name, env)
742
742
  return binding[:type] if binding
743
+ if (value_param_type = value_param_declared_type(expression.name))
744
+ return value_param_type
745
+ end
743
746
  return function_type_for_name(expression.name) if @ctx.functions.key?(expression.name)
744
747
 
745
748
  raise LoweringError.new("unknown identifier #{expression.name}", line: expression.line, column: expression.column)
@@ -2437,6 +2440,25 @@ module MilkTea
2437
2440
  @ctx.current_type_substitutions || {}
2438
2441
  end
2439
2442
 
2443
+ def value_param_substitution(name)
2444
+ substitution = current_type_params[name]
2445
+ substitution.is_a?(Types::LiteralTypeArg) ? substitution : nil
2446
+ end
2447
+
2448
+ def value_param_declared_type(name)
2449
+ return nil unless value_param_substitution(name)
2450
+
2451
+ @ctx.current_value_type_params&.[](name)
2452
+ end
2453
+
2454
+ def value_param_literal(name, expected_type = nil)
2455
+ substitution = value_param_substitution(name)
2456
+ return nil unless substitution && substitution.value.is_a?(Integer)
2457
+
2458
+ type = @ctx.current_value_type_params&.[](name) || expected_type || @ctx.types.fetch("int")
2459
+ IR::IntegerLiteral.new(value: substitution.value, type:)
2460
+ end
2461
+
2440
2462
  def resolve_type_ref(type_ref, type_params: current_type_params)
2441
2463
  if type_ref.is_a?(AST::FunctionType)
2442
2464
  params = type_ref.params.map do |param|
@@ -454,7 +454,7 @@ module MilkTea
454
454
  match(:async)
455
455
  match(:editable) if check(:editable)
456
456
  match(:static) if check(:static)
457
- result = check(:function)
457
+ result = check(:function) && !check_next(:colon)
458
458
  @current = saved
459
459
  result
460
460
  end
@@ -468,11 +468,13 @@ module MilkTea
468
468
 
469
469
  visibility, visibility_token = parse_visibility
470
470
 
471
- if match(:event)
471
+ if check(:event) && !check_next(:colon)
472
+ advance
472
473
  return [:event, parse_event_decl(visibility:, attributes: field_attributes)]
473
474
  end
474
475
 
475
- if match(:struct)
476
+ if check(:struct) && !check_next(:colon)
477
+ advance
476
478
  return [:nested_type, parse_struct_decl(visibility:, attributes: field_attributes, inline_methods: false)]
477
479
  end
478
480
 
@@ -741,7 +743,10 @@ module MilkTea
741
743
  end
742
744
 
743
745
  def parse_visibility
744
- return [:public, previous] if match(:public)
746
+ if check(:public) && !check_next(:colon)
747
+ advance
748
+ return [:public, previous]
749
+ end
745
750
 
746
751
  [:private, nil]
747
752
  end
@@ -31,6 +31,7 @@ module MilkTea
31
31
  receiver_type = infer_lvalue_receiver(
32
32
  expression.receiver,
33
33
  scopes:,
34
+ allow_ref_identifier: true,
34
35
  allow_pointer_identifier: true,
35
36
  require_mutable_pointer: true,
36
37
  allow_span_param_identifier: true,
@@ -333,6 +334,10 @@ module MilkTea
333
334
  return binding.type
334
335
  end
335
336
 
337
+ if (value_param_type = current_value_type_params[expression.name])
338
+ return value_param_type
339
+ end
340
+
336
341
  if @ctx.top_level_functions.key?(expression.name)
337
342
  raise_sema_error("generic function #{expression.name} must be called") if @ctx.top_level_functions.fetch(expression.name).type_params.any?
338
343
 
@@ -615,6 +615,7 @@ module MilkTea
615
615
 
616
616
  previous_type_substitutions = @current_type_substitutions
617
617
  previous_specialization_owner = @current_specialization_owner
618
+ previous_value_type_params = @current_value_type_params
618
619
  started_check = false
619
620
  return if binding.external
620
621
  return if @checked_function_bindings[binding.object_id]
@@ -624,6 +625,7 @@ module MilkTea
624
625
  started_check = true
625
626
  @current_type_substitutions = binding.type_substitutions
626
627
  @current_specialization_owner = binding.specialization_owner
628
+ @current_value_type_params = resolve_value_type_params(binding.ast.type_params)
627
629
  with_error_node(binding.ast) do
628
630
  with_scope(binding.body_params) do |scopes|
629
631
  start_local_completion_frame(binding, scopes)
@@ -678,8 +680,21 @@ module MilkTea
678
680
  @nullability_flow_result = nil
679
681
  @current_type_substitutions = previous_type_substitutions
680
682
  @current_specialization_owner = previous_specialization_owner
683
+ @current_value_type_params = previous_value_type_params
681
684
  @checking_function_bindings.delete(binding.object_id)
682
685
  end
686
+
687
+ def resolve_value_type_params(type_params)
688
+ type_params.each_with_object({}) do |type_param, map|
689
+ next unless type_param.is_a?(AST::ValueTypeParam)
690
+
691
+ map[type_param.name] = resolve_type_ref(
692
+ type_param.type,
693
+ type_params: current_type_params,
694
+ type_param_constraints: current_type_param_constraints,
695
+ )
696
+ end
697
+ end
683
698
  end
684
699
  end
685
700
  end
@@ -7,6 +7,10 @@ module MilkTea
7
7
  @current_type_substitutions || {}
8
8
  end
9
9
 
10
+ def current_value_type_params
11
+ @current_value_type_params || {}
12
+ end
13
+
10
14
  def current_type_param_constraints
11
15
  @current_type_param_constraints || {}
12
16
  end
@@ -463,9 +467,13 @@ module MilkTea
463
467
  resolve_imported_module_const_value(type_ref.name.parts.first, type_ref.name.parts.last)
464
468
  end
465
469
 
466
- return unless value.is_a?(Integer) || value.is_a?(Float)
470
+ return if value.nil?
471
+ return Types::LiteralTypeArg.new(value) if value.is_a?(Integer) || value.is_a?(Float)
472
+ return value if value.is_a?(Types::Base)
467
473
 
468
- Types::LiteralTypeArg.new(value)
474
+ nil
475
+ rescue SemanticError
476
+ nil
469
477
  end
470
478
 
471
479
  def resolve_current_module_const_value(name)
@@ -657,12 +665,8 @@ module MilkTea
657
665
  return false unless expression
658
666
 
659
667
  ct_value = evaluate_compile_time_const_value(expression, scopes:)
660
- if ct_value.is_a?(Types::Struct) || ct_value.is_a?(Types::Primitive) ||
661
- ct_value.is_a?(Types::Union) || ct_value.is_a?(Types::Nullable) ||
662
- ct_value.is_a?(Types::StructInstance)
663
- if sized_layout_type?(ct_value)
664
- return true
665
- end
668
+ if sized_layout_type?(ct_value)
669
+ return true
666
670
  end
667
671
 
668
672
  false