mt-lang 0.3.5 → 0.3.7

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.
@@ -21,7 +21,7 @@ module MilkTea
21
21
  case kind
22
22
  when :function
23
23
  if callee_binding && foreign_function_binding?(callee_binding)
24
- raise LoweringError, "consuming foreign calls must be top-level expression statements" if foreign_call_consumes_binding?(callee_binding)
24
+ raise LoweringError.new("consuming foreign calls must be top-level expression statements", line: 0, column: 0, path: @ctx.current_analysis_path) if foreign_call_consumes_binding?(callee_binding)
25
25
 
26
26
  return lower_foreign_call_inline(expression, callee_binding, env:, type:)
27
27
  end
@@ -287,7 +287,7 @@ module MilkTea
287
287
  elsif receiver_type.is_a?(Types::Span)
288
288
  IR::NullableSpanIndex.new(receiver:, index:, receiver_type:, type:)
289
289
  else
290
- raise LoweringError, "get expects an array or span, got #{receiver_type}"
290
+ raise LoweringError.new("get expects an array or span, got #{receiver_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
291
291
  end
292
292
  when :ref_of
293
293
  argument = expression.arguments.fetch(0)
@@ -311,7 +311,7 @@ module MilkTea
311
311
  when :dyn_method
312
312
  lower_dyn_method_call(expression, receiver, callee_type, env:, type:)
313
313
  else
314
- raise LoweringError, "unsupported call kind #{kind}"
314
+ raise LoweringError.new("unsupported call kind #{kind}", line: 0, column: 0, path: @ctx.current_analysis_path)
315
315
  end
316
316
  end
317
317
 
@@ -488,7 +488,7 @@ module MilkTea
488
488
  def lower_foreign_call_components(foreign_call, env:, expected_type:, statement_position:)
489
489
  call = foreign_call.fetch(:call)
490
490
  binding = foreign_call.fetch(:binding)
491
- raise LoweringError, "consuming foreign calls must be top-level expression statements" if foreign_call_consumes_binding?(binding) && !statement_position
491
+ raise LoweringError.new("consuming foreign calls must be top-level expression statements", line: 0, column: 0, path: @ctx.current_analysis_path) if foreign_call_consumes_binding?(binding) && !statement_position
492
492
 
493
493
  previous_type_substitutions = @ctx.current_type_substitutions
494
494
  @ctx.current_type_substitutions = binding.type_substitutions
@@ -540,7 +540,7 @@ module MilkTea
540
540
  return [lowered, nil]
541
541
  end
542
542
 
543
- raise LoweringError, "consuming foreign calls must return void" unless release_assignments.empty?
543
+ raise LoweringError.new("consuming foreign calls must return void", line: 0, column: 0, path: @ctx.current_analysis_path) unless release_assignments.empty?
544
544
 
545
545
  if discard_result
546
546
  lowered << IR::ExpressionStmt.new(expression: lowered_call)
@@ -583,12 +583,12 @@ module MilkTea
583
583
 
584
584
  argument = call.arguments.fetch(index)
585
585
  unless argument.value.is_a?(AST::Identifier)
586
- raise LoweringError, "consuming foreign calls require bare nullable local or parameter bindings"
586
+ raise LoweringError.new("consuming foreign calls require bare nullable local or parameter bindings", line: 0, column: 0, path: @ctx.current_analysis_path)
587
587
  end
588
588
 
589
589
  lowered_binding = lookup_value(argument.value.name, env)
590
590
  unless lowered_binding && lowered_binding[:storage_type].is_a?(Types::Nullable) && lowered_binding[:storage_type].base == parameter.type
591
- raise LoweringError, "consuming foreign calls require bare nullable local or parameter bindings"
591
+ raise LoweringError.new("consuming foreign calls require bare nullable local or parameter bindings", line: 0, column: 0, path: @ctx.current_analysis_path)
592
592
  end
593
593
 
594
594
  lowered_binding.merge(name: argument.value.name)
@@ -757,14 +757,14 @@ module MilkTea
757
757
  converted = foreign_identity_projection_expression(lowered_value, parameter.boundary_type)
758
758
  return converted if converted
759
759
 
760
- raise LoweringError, "unsupported foreign boundary mapping #{parameter.type} as #{parameter.boundary_type}"
760
+ raise LoweringError.new("unsupported foreign boundary mapping #{parameter.type} as #{parameter.boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
761
761
  end
762
762
  when :in
763
763
  lower_foreign_in_argument_value(parameter, argument, env:)
764
764
  when :out, :inout
765
765
  lower_foreign_pointer_argument_value(parameter, argument, env:)
766
766
  else
767
- raise LoweringError, "unsupported foreign passing mode #{parameter.passing_mode}"
767
+ raise LoweringError.new("unsupported foreign passing mode #{parameter.passing_mode}", line: 0, column: 0, path: @ctx.current_analysis_path)
768
768
  end
769
769
  end
770
770
 
@@ -779,7 +779,7 @@ module MilkTea
779
779
 
780
780
  data_expression = IR::Member.new(receiver: lowered_value, member: "data", type: pointer_to(public_element_type))
781
781
  converted_data = foreign_identity_projection_expression(data_expression, pointer_to(boundary_element_type))
782
- raise LoweringError, "unsupported foreign boundary mapping #{public_type} as #{boundary_type}" unless converted_data
782
+ raise LoweringError.new("unsupported foreign boundary mapping #{public_type} as #{boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless converted_data
783
783
 
784
784
  len_expression = IR::Member.new(receiver: lowered_value, member: "len", type: @ctx.types.fetch("ptr_uint"))
785
785
  IR::AggregateLiteral.new(
@@ -799,7 +799,7 @@ module MilkTea
799
799
  converted = foreign_identity_projection_expression(address, parameter.boundary_type)
800
800
  return converted if converted
801
801
 
802
- raise LoweringError, "unsupported foreign pointer boundary mapping #{parameter.type} as #{parameter.boundary_type}"
802
+ raise LoweringError.new("unsupported foreign pointer boundary mapping #{parameter.type} as #{parameter.boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
803
803
  end
804
804
 
805
805
  def foreign_slot_boundary_value_type(type)
@@ -841,7 +841,7 @@ module MilkTea
841
841
  converted = foreign_identity_projection_expression(address, parameter.boundary_type)
842
842
  return converted if converted
843
843
 
844
- raise LoweringError, "unsupported foreign in boundary mapping #{parameter.type} as #{parameter.boundary_type}"
844
+ raise LoweringError.new("unsupported foreign in boundary mapping #{parameter.type} as #{parameter.boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
845
845
  end
846
846
 
847
847
  def lower_foreign_char_pointer_buffer_argument_value(parameter, argument, env:)
@@ -869,7 +869,7 @@ module MilkTea
869
869
  converted = foreign_identity_projection_expression(lowered_value, parameter.boundary_type)
870
870
  return converted if converted
871
871
 
872
- raise LoweringError, "unsupported foreign boundary mapping #{public_type} as #{parameter.boundary_type}"
872
+ raise LoweringError.new("unsupported foreign boundary mapping #{public_type} as #{parameter.boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
873
873
  end
874
874
 
875
875
  def lower_foreign_call_inline(expression, binding, env:, type:)
@@ -888,7 +888,7 @@ module MilkTea
888
888
  next unless total_references > 1
889
889
  next if duplicable_foreign_argument_expression?(expression.arguments.fetch(index).value)
890
890
 
891
- raise LoweringError, "foreign call #{binding.name} cannot be used inline because #{param_ast.name} is referenced multiple times in its mapping; use it as a statement, local initializer, assignment, or return expression"
891
+ raise LoweringError.new("foreign call #{binding.name} cannot be used inline because #{param_ast.name} is referenced multiple times in its mapping; use it as a statement, local initializer, assignment, or return expression", line: 0, column: 0, path: @ctx.current_analysis_path)
892
892
  end
893
893
 
894
894
  binding.ast.params.each_with_index do |param_ast, index|
@@ -896,13 +896,13 @@ module MilkTea
896
896
  next unless automatic_foreign_cstr_temp_needed?(parameter, expression.arguments.fetch(index).value, env:) ||
897
897
  automatic_foreign_cstr_list_temp_needed?(parameter, expression.arguments.fetch(index).value, env:)
898
898
 
899
- raise LoweringError, "foreign call #{binding.name} cannot be used inline because #{param_ast.name} needs temporary foreign text storage; use it as a statement, local initializer, assignment, or return expression"
899
+ raise LoweringError.new("foreign call #{binding.name} cannot be used inline because #{param_ast.name} needs temporary foreign text storage; use it as a statement, local initializer, assignment, or return expression", line: 0, column: 0, path: @ctx.current_analysis_path)
900
900
  end
901
901
 
902
902
  expression.arguments.drop(binding.type.params.length).each do |argument|
903
903
  next unless automatic_variadic_foreign_cstr_temp_needed?(argument.value, env:)
904
904
 
905
- raise LoweringError, "foreign call #{binding.name} cannot be used inline because a variadic argument needs temporary foreign text storage; use it as a statement, local initializer, assignment, or return expression"
905
+ raise LoweringError.new("foreign call #{binding.name} cannot be used inline because a variadic argument needs temporary foreign text storage; use it as a statement, local initializer, assignment, or return expression", line: 0, column: 0, path: @ctx.current_analysis_path)
906
906
  end
907
907
 
908
908
  binding.ast.params.each_with_index do |param_ast, index|
@@ -911,7 +911,7 @@ module MilkTea
911
911
  next unless parameter.passing_mode == :in
912
912
  next if addressable_storage_expression?(foreign_argument_expression(argument))
913
913
 
914
- raise LoweringError, "foreign call #{binding.name} cannot be used inline because #{param_ast.name} needs temporary in storage; use it as a statement, local initializer, assignment, or return expression"
914
+ raise LoweringError.new("foreign call #{binding.name} cannot be used inline because #{param_ast.name} needs temporary in storage; use it as a statement, local initializer, assignment, or return expression", line: 0, column: 0, path: @ctx.current_analysis_path)
915
915
  end
916
916
 
917
917
  replacements = {}
@@ -978,7 +978,7 @@ module MilkTea
978
978
  )
979
979
  return lowered_argument unless temporary_foreign_cstr_expression?(lowered_argument)
980
980
 
981
- raise LoweringError, "foreign variadic call cannot be used inline because an extra argument needs temporary foreign text storage; use it as a statement, local initializer, assignment, or return expression" unless lowered && cleanup
981
+ raise LoweringError.new("foreign variadic call cannot be used inline because an extra argument needs temporary foreign text storage; use it as a statement, local initializer, assignment, or return expression", line: 0, column: 0, path: @ctx.current_analysis_path) unless lowered && cleanup
982
982
 
983
983
  temp_name = fresh_c_temp_name(env, "foreign_arg")
984
984
  lowered << IR::LocalDecl.new(
@@ -1128,7 +1128,7 @@ module MilkTea
1128
1128
 
1129
1129
  case kind
1130
1130
  when :function
1131
- raise LoweringError, "consuming foreign calls must be top-level expression statements" if callee_binding && foreign_function_binding?(callee_binding) && foreign_call_consumes_binding?(callee_binding)
1131
+ raise LoweringError.new("consuming foreign calls must be top-level expression statements", line: 0, column: 0, path: @ctx.current_analysis_path) if callee_binding && foreign_function_binding?(callee_binding) && foreign_call_consumes_binding?(callee_binding)
1132
1132
 
1133
1133
  arguments = expression.arguments.map.with_index do |argument, index|
1134
1134
  expected_arg_type = index < callee_type.params.length ? callee_type.params[index].type : nil
@@ -1301,7 +1301,7 @@ module MilkTea
1301
1301
  )
1302
1302
  end
1303
1303
  else
1304
- raise LoweringError, "unsupported inline foreign mapping call kind #{kind}"
1304
+ raise LoweringError.new("unsupported inline foreign mapping call kind #{kind}", line: 0, column: 0, path: @ctx.current_analysis_path)
1305
1305
  end
1306
1306
  end
1307
1307
 
@@ -1537,9 +1537,9 @@ module MilkTea
1537
1537
 
1538
1538
  if (callable_resolution = resolve_specialized_callable_binding(expression, env:))
1539
1539
  callable_kind, function_binding, = callable_resolution
1540
- raise LoweringError, "specialized method must be called" if callable_kind == :method
1540
+ raise LoweringError.new("specialized method must be called", line: 0, column: 0, path: @ctx.current_analysis_path) if callable_kind == :method
1541
1541
 
1542
- raise LoweringError, "foreign function #{function_binding.name} cannot be used as a value" if foreign_function_binding?(function_binding)
1542
+ raise LoweringError.new("foreign function #{function_binding.name} cannot be used as a value", line: 0, column: 0, path: @ctx.current_analysis_path) if foreign_function_binding?(function_binding)
1543
1543
 
1544
1544
  if function_binding.external
1545
1545
  return IR::Name.new(name: external_function_c_name(function_binding), type:, pointer: false)
@@ -1552,9 +1552,9 @@ module MilkTea
1552
1552
  )
1553
1553
  end
1554
1554
 
1555
- raise LoweringError, "specialization #{expression.callee.name} must be called" if expression.callee.is_a?(AST::Identifier)
1555
+ raise LoweringError.new("specialization #{expression.callee.name} must be called", line: 0, column: 0, path: @ctx.current_analysis_path) if expression.callee.is_a?(AST::Identifier)
1556
1556
 
1557
- raise LoweringError, "unsupported specialization #{expression.class.name}"
1557
+ raise LoweringError.new("unsupported specialization #{expression.class.name}", line: 0, column: 0, path: @ctx.current_analysis_path)
1558
1558
  end
1559
1559
 
1560
1560
  def atomic_method_kind(receiver_type, name)
@@ -1602,7 +1602,7 @@ module MilkTea
1602
1602
  arg = lower_contextual_expression(expression.arguments.first.value, env:, expected_type: elem_type)
1603
1603
  IR::Call.new(callee: "__atomic_exchange_n", arguments: [addr, arg, seq_cst], type: elem_type)
1604
1604
  when :atomic_compare_exchange
1605
- raise LoweringError, "atomic compare_exchange is not yet implemented in the built-in surface; use std.sync.AtomicUint for compare-exchange operations"
1605
+ raise LoweringError.new("atomic compare_exchange is not yet implemented in the built-in surface; use std.sync.AtomicUint for compare-exchange operations", line: 0, column: 0, path: @ctx.current_analysis_path)
1606
1606
  end
1607
1607
  end
1608
1608
 
@@ -41,7 +41,8 @@ module MilkTea
41
41
  value = lower_static_storage_initializer(decl.value, env: empty_env, expected_type: type)
42
42
  end
43
43
 
44
- IR::Constant.new(name: decl.name, linkage_name: value_c_name(decl.name), type:, value:)
44
+ IR::Constant.new(name: decl.name, linkage_name: value_c_name(decl.name), type:, value:,
45
+ line: decl.line, source_path: @ctx.current_analysis_path)
45
46
  end
46
47
  end
47
48
 
@@ -75,7 +76,7 @@ module MilkTea
75
76
  when Hash
76
77
  fields = const_value.map do |name, field_value|
77
78
  field_type = type.field(name)
78
- raise LoweringError, "constant struct field #{name} not found in #{type}" unless field_type
79
+ raise LoweringError.new("constant struct field #{name} not found in #{type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless field_type
79
80
  IR::AggregateField.new(name:, value: lower_const_value_literal(field_type, field_value))
80
81
  end
81
82
  IR::AggregateLiteral.new(type:, fields:)
@@ -130,7 +131,7 @@ module MilkTea
130
131
 
131
132
  def lower_static_assert(statement, env:)
132
133
  condition_value = compile_time_const_value(statement.condition, env:)
133
- raise LoweringError, "static_assert condition must lower to a compile-time bool constant" unless condition_value == true || condition_value == false
134
+ raise LoweringError.new("static_assert condition must lower to a compile-time bool constant", line: 0, column: 0, path: @ctx.current_analysis_path) unless condition_value == true || condition_value == false
134
135
 
135
136
  IR::StaticAssert.new(
136
137
  condition: IR::BooleanLiteral.new(value: condition_value, type: @ctx.types.fetch("bool")),
@@ -110,7 +110,8 @@ module MilkTea
110
110
 
111
111
  interface.methods.each do |method_name, method_binding|
112
112
  method_info = @method_definitions[[concrete_type, method_name]]
113
- raise LoweringError, "no method #{method_name} for #{concrete_type}" unless method_info
113
+ raise LoweringError.new("no method #{method_name} for #{concrete_type}",
114
+ line: 0, column: 0, path: @ctx.current_analysis_path) unless method_info
114
115
 
115
116
  method_analysis, method_ast = method_info
116
117
  method_key = method_ast.kind == :static ? "static:#{method_ast.name}" : method_ast.name
@@ -46,7 +46,7 @@ module MilkTea
46
46
  when :event_wait
47
47
  Types::Registry.function(kind.to_s, params: [], return_type: Types::Registry.task(event_wait_result_type(event_type)))
48
48
  else
49
- raise LoweringError, "unsupported event method #{kind}"
49
+ raise LoweringError.new("unsupported event method #{kind}", line: 0, column: 0, path: @ctx.current_analysis_path)
50
50
  end
51
51
  end
52
52
 
@@ -283,7 +283,7 @@ module MilkTea
283
283
  parameter_type: append_argument_type,
284
284
  }
285
285
  else
286
- raise LoweringError, "unsupported format spec #{part.format_spec.inspect}"
286
+ raise LoweringError.new("unsupported format spec #{part.format_spec.inspect}", line: 0, column: 0, path: @ctx.current_analysis_path)
287
287
  end
288
288
  else
289
289
  append_plan = format_string_append_plan(value_type, context: "formatted string interpolation of #{value_type}")
@@ -434,7 +434,7 @@ module MilkTea
434
434
  capacity: IR::IntegerLiteral.new(value: str_buffer_capacity(lowered_receiver.type), type: @ctx.types.fetch("ptr_uint")),
435
435
  }
436
436
  else
437
- raise LoweringError, "unsupported explicit format sink #{info[:sink_kind]}"
437
+ raise LoweringError.new("unsupported explicit format sink #{info[:sink_kind]}", line: 0, column: 0, path: @ctx.current_analysis_path)
438
438
  end
439
439
  end
440
440
 
@@ -451,7 +451,7 @@ module MilkTea
451
451
  ],
452
452
  )
453
453
  else
454
- raise LoweringError, "unsupported explicit format sink #{sink_target[:kind]}"
454
+ raise LoweringError.new("unsupported explicit format sink #{sink_target[:kind]}", line: 0, column: 0, path: @ctx.current_analysis_path)
455
455
  end
456
456
  end
457
457
 
@@ -560,7 +560,7 @@ module MilkTea
560
560
  value: offset_value,
561
561
  )
562
562
  else
563
- raise LoweringError, "unsupported explicit format sink #{sink_target[:kind]}"
563
+ raise LoweringError.new("unsupported explicit format sink #{sink_target[:kind]}", line: 0, column: 0, path: @ctx.current_analysis_path)
564
564
  end
565
565
 
566
566
  sink_statements.concat(copied_part_cleanups)
@@ -588,7 +588,7 @@ module MilkTea
588
588
  type: @ctx.types.fetch("void"),
589
589
  )
590
590
  else
591
- raise LoweringError, "unsupported explicit format sink #{sink_target[:kind]}"
591
+ raise LoweringError.new("unsupported explicit format sink #{sink_target[:kind]}", line: 0, column: 0, path: @ctx.current_analysis_path)
592
592
  end
593
593
  end
594
594
 
@@ -820,7 +820,7 @@ module MilkTea
820
820
  end
821
821
 
822
822
  if part[:kind] == :custom_expression
823
- raise LoweringError, "custom format parts require statement lowering"
823
+ raise LoweringError.new("custom format parts require statement lowering", line: 0, column: 0, path: @ctx.current_analysis_path)
824
824
  end
825
825
 
826
826
  IR::Call.new(
@@ -837,7 +837,7 @@ module MilkTea
837
837
  when :append
838
838
  part[:format_binding].append_binding
839
839
  else
840
- raise LoweringError, "unsupported custom format hook #{hook}"
840
+ raise LoweringError.new("unsupported custom format hook #{hook}", line: 0, column: 0, path: @ctx.current_analysis_path)
841
841
  end
842
842
 
843
843
  if env
@@ -883,7 +883,7 @@ module MilkTea
883
883
  }
884
884
  end
885
885
 
886
- raise LoweringError, "formatted string interpolation supports str, cstr, bool, numeric primitives, integer-backed enums/flags, and types implementing format_len()/append_format(output: ref[std.string.String]), got #{type}"
886
+ raise LoweringError.new("formatted string interpolation supports str, cstr, bool, numeric primitives, integer-backed enums/flags, and types implementing format_len()/append_format(output: ref[std.string.String]), got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
887
887
  end
888
888
 
889
889
  def format_string_hex_append_plan(type, uppercase:)
@@ -892,7 +892,7 @@ module MilkTea
892
892
  end
893
893
 
894
894
  unless type.is_a?(Types::Primitive) && type.integer?
895
- raise LoweringError, "format spec ':x' and ':X' require integer interpolation, got #{type}"
895
+ raise LoweringError.new("format spec ':x' and ':X' require integer interpolation, got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
896
896
  end
897
897
 
898
898
  if type.signed_integer?
@@ -903,7 +903,7 @@ module MilkTea
903
903
  return [uppercase ? "append_ulong_hex_upper" : "append_ulong_hex", @ctx.types.fetch("ulong")]
904
904
  end
905
905
 
906
- raise LoweringError, "format spec ':x' and ':X' require integer interpolation, got #{type}"
906
+ raise LoweringError.new("format spec ':x' and ':X' require integer interpolation, got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
907
907
  end
908
908
 
909
909
  def format_string_oct_append_plan(type, uppercase:)
@@ -913,7 +913,7 @@ module MilkTea
913
913
  end
914
914
 
915
915
  unless type.is_a?(Types::Primitive) && type.integer?
916
- raise LoweringError, "format spec ':o' and ':O' require integer interpolation, got #{type}"
916
+ raise LoweringError.new("format spec ':o' and ':O' require integer interpolation, got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
917
917
  end
918
918
 
919
919
  if type.signed_integer?
@@ -924,7 +924,7 @@ module MilkTea
924
924
  return ["append_ulong_oct", @ctx.types.fetch("ulong")]
925
925
  end
926
926
 
927
- raise LoweringError, "format spec ':o' and ':O' require integer interpolation, got #{type}"
927
+ raise LoweringError.new("format spec ':o' and ':O' require integer interpolation, got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
928
928
  end
929
929
 
930
930
  def format_string_bin_append_plan(type, uppercase:)
@@ -934,7 +934,7 @@ module MilkTea
934
934
  end
935
935
 
936
936
  unless type.is_a?(Types::Primitive) && type.integer?
937
- raise LoweringError, "format spec ':b' and ':B' require integer interpolation, got #{type}"
937
+ raise LoweringError.new("format spec ':b' and ':B' require integer interpolation, got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
938
938
  end
939
939
 
940
940
  if type.signed_integer?
@@ -945,7 +945,7 @@ module MilkTea
945
945
  return ["append_ulong_bin", @ctx.types.fetch("ulong")]
946
946
  end
947
947
 
948
- raise LoweringError, "format spec ':b' and ':B' require integer interpolation, got #{type}"
948
+ raise LoweringError.new("format spec ':b' and ':B' require integer interpolation, got #{type}", line: 0, column: 0, path: @ctx.current_analysis_path)
949
949
  end
950
950
 
951
951
  def mt_format_length_c_name(name)
@@ -1261,7 +1261,7 @@ module MilkTea
1261
1261
  end
1262
1262
 
1263
1263
  def materialize_prepared_expression(setup, value, env:, type:, prefix:)
1264
- raise LoweringError, "cannot use void expression inline" unless value
1264
+ raise LoweringError.new("cannot use void expression inline", line: 0, column: 0, path: @ctx.current_analysis_path) unless value
1265
1265
 
1266
1266
  if value.is_a?(IR::Name)
1267
1267
  register_prepared_temp!(env, value.name, value.type, pointer: value.pointer)
@@ -1316,7 +1316,7 @@ module MilkTea
1316
1316
 
1317
1317
  case expression
1318
1318
  when AST::AwaitExpr
1319
- raise LoweringError, "await expressions must be lowered in async statement context"
1319
+ raise LoweringError.new("await expressions must be lowered in async statement context", line: 0, column: 0, path: @ctx.current_analysis_path)
1320
1320
  when AST::IntegerLiteral
1321
1321
  IR::IntegerLiteral.new(value: expression.value, type:)
1322
1322
  when AST::CharLiteral
@@ -1341,7 +1341,7 @@ module MilkTea
1341
1341
  when AST::StringLiteral
1342
1342
  IR::StringLiteral.new(value: expression.value, type:, cstring: expression.cstring)
1343
1343
  when AST::FormatString
1344
- raise LoweringError, "unprepared format string reached raw lowering; format strings should be materialized before direct lowering"
1344
+ raise LoweringError.new("unprepared format string reached raw lowering; format strings should be materialized before direct lowering", line: 0, column: 0, path: @ctx.current_analysis_path)
1345
1345
  when AST::BooleanLiteral
1346
1346
  IR::BooleanLiteral.new(value: expression.value, type:)
1347
1347
  when AST::NullLiteral
@@ -1352,12 +1352,12 @@ module MilkTea
1352
1352
  lower_bound_identifier(binding, expected_type:)
1353
1353
  elsif @ctx.functions.key?(expression.name)
1354
1354
  function_binding = @ctx.functions.fetch(expression.name)
1355
- raise LoweringError, "generic function #{expression.name} cannot be used as a value" if function_binding.type_params.any?
1356
- raise LoweringError, "foreign function #{expression.name} cannot be used as a value" if foreign_function_binding?(function_binding)
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?
1356
+ raise LoweringError.new("foreign function #{expression.name} cannot be used as a value", line: 0, column: 0, path: @ctx.current_analysis_path) if foreign_function_binding?(function_binding)
1357
1357
 
1358
1358
  IR::Name.new(name: function_binding_c_name(function_binding, module_name: @ctx.module_name), type: type, pointer: false)
1359
1359
  else
1360
- raise LoweringError, "unsupported identifier #{expression.name}"
1360
+ raise LoweringError.new("unsupported identifier #{expression.name}", line: 0, column: 0, path: @ctx.current_analysis_path)
1361
1361
  end
1362
1362
  when AST::MemberAccess
1363
1363
  lower_member_access(expression, env:, type:)
@@ -1373,7 +1373,7 @@ module MilkTea
1373
1373
  IR::Index.new(receiver:, index:, type:)
1374
1374
  end
1375
1375
  when AST::UnaryOp
1376
- raise LoweringError, "propagation expressions must be prepared before direct lowering" if expression.operator == "?"
1376
+ raise LoweringError.new("propagation expressions must be prepared before direct lowering", line: 0, column: 0, path: @ctx.current_analysis_path) if expression.operator == "?"
1377
1377
 
1378
1378
  operand = lower_expression(expression.operand, env:, expected_type: type)
1379
1379
  expanded = lower_vector_unary_op(expression.operator, operand, type)
@@ -1403,7 +1403,7 @@ module MilkTea
1403
1403
  type:,
1404
1404
  )
1405
1405
  when AST::MatchExpr
1406
- raise LoweringError, "match expressions must be prepared before direct lowering"
1406
+ raise LoweringError.new("match expressions must be prepared before direct lowering", line: 0, column: 0, path: @ctx.current_analysis_path)
1407
1407
  when AST::UnsafeExpr
1408
1408
  lower_expression(expression.expression, env:, expected_type: type)
1409
1409
  when AST::ProcExpr
@@ -1444,7 +1444,7 @@ module MilkTea
1444
1444
  IR::AggregateLiteral.new(type:, fields:)
1445
1445
  end
1446
1446
  else
1447
- raise LoweringError, "unsupported expression #{expression.class.name}"
1447
+ raise LoweringError.new("unsupported expression #{expression.class.name}", line: 0, column: 0, path: @ctx.current_analysis_path)
1448
1448
  end
1449
1449
  end
1450
1450
 
@@ -1466,8 +1466,8 @@ module MilkTea
1466
1466
  imported_module = @ctx.imports.fetch(expression.receiver.name)
1467
1467
  if imported_module.functions.key?(expression.member)
1468
1468
  function_binding = imported_module.functions.fetch(expression.member)
1469
- raise LoweringError, "generic function #{expression.receiver.name}.#{expression.member} cannot be used as a value" if function_binding.type_params.any?
1470
- raise LoweringError, "foreign function #{expression.receiver.name}.#{expression.member} cannot be used as a value" if foreign_function_binding?(function_binding)
1469
+ raise LoweringError.new("generic function #{expression.receiver.name}.#{expression.member} cannot be used as a value", line: 0, column: 0, path: @ctx.current_analysis_path) if function_binding.type_params.any?
1470
+ raise LoweringError.new("foreign function #{expression.receiver.name}.#{expression.member} cannot be used as a value", line: 0, column: 0, path: @ctx.current_analysis_path) if foreign_function_binding?(function_binding)
1471
1471
 
1472
1472
  return IR::Name.new(name: function_binding_c_name(function_binding, module_name: imported_module.name), type:, pointer: false)
1473
1473
  end
@@ -1611,7 +1611,7 @@ module MilkTea
1611
1611
 
1612
1612
  def lower_soa_indexed_field_access(soa_base, index_expr, field_name, soa_type, env:, type:)
1613
1613
  field_type = soa_type.fields[field_name]
1614
- raise LoweringError, "SoA type #{soa_type} has no field #{field_name}" unless field_type
1614
+ raise LoweringError.new("SoA type #{soa_type} has no field #{field_name}", line: 0, column: 0, path: @ctx.current_analysis_path) unless field_type
1615
1615
 
1616
1616
  receiver = lower_expression(soa_base, env:)
1617
1617
  index = lower_expression(index_expr, env:)
@@ -65,7 +65,7 @@ module MilkTea
65
65
  IR::Name.new(name: items_name, type: items_type, pointer: false),
66
66
  pointer_to(boundary_type.element_type),
67
67
  )
68
- raise LoweringError, "unsupported foreign boundary mapping #{public_type} as #{boundary_type}" unless converted_data
68
+ raise LoweringError.new("unsupported foreign boundary mapping #{public_type} as #{boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless converted_data
69
69
 
70
70
  IR::AggregateLiteral.new(
71
71
  type: boundary_type,
@@ -109,7 +109,7 @@ module MilkTea
109
109
  item = IR::Member.new(receiver: item, member: "data", type: pointer_to(@ctx.types.fetch("char"))) if item_type == @ctx.types.fetch("str")
110
110
 
111
111
  converted = foreign_identity_projection_expression(item, boundary_element_type)
112
- raise LoweringError, "unsupported foreign boundary mapping #{parameter.type} as #{boundary_type}" unless converted
112
+ raise LoweringError.new("unsupported foreign boundary mapping #{parameter.type} as #{boundary_type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless converted
113
113
 
114
114
  converted
115
115
  end
@@ -107,7 +107,7 @@ module MilkTea
107
107
  return imported_module.types.fetch(parts.last)
108
108
  end
109
109
 
110
- raise LoweringError, "unsupported extending target #{type_name}"
110
+ raise LoweringError.new("unsupported extending target #{type_name}", line: 0, column: 0, path: @ctx.current_analysis_path)
111
111
  end
112
112
 
113
113
  def lower_function_decl(binding, receiver_type: nil)
@@ -133,7 +133,7 @@ module MilkTea
133
133
  def lower_collection_for_stmt(statement, env:, active_defers:, return_type:, allow_return:)
134
134
  iterable_type = infer_expression_type(statement.iterable, env:)
135
135
  element_type = collection_loop_type(iterable_type)
136
- raise LoweringError, "for loop expects start..stop, array[T, N], span[T], or an iterable with iter()/next(), got #{iterable_type}" unless element_type
136
+ raise LoweringError.new("for loop expects start..stop, array[T, N], span[T], or an iterable with iter()/next(), got #{iterable_type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless element_type
137
137
  iterable_setup, prepared_iterable = prepare_expression_for_inline_lowering(statement.iterable, env:, expected_type: iterable_type)
138
138
  binding_type = collection_loop_binding_type(iterable_type, element_type) || element_type
139
139
 
@@ -207,7 +207,7 @@ module MilkTea
207
207
  iterable = statement.iterables[index]
208
208
  iterable_type = infer_expression_type(iterable, env:)
209
209
  element_type = collection_loop_type(iterable_type)
210
- raise LoweringError, "parallel for loops expect arrays or spans for each iterable, got #{iterable_type}" unless element_type
210
+ raise LoweringError.new("parallel for loops expect arrays or spans for each iterable, got #{iterable_type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless element_type
211
211
 
212
212
  {
213
213
  binding:,
@@ -304,7 +304,7 @@ module MilkTea
304
304
  def lower_iterator_for_stmt(statement, env:, active_defers:, return_type:, allow_return:)
305
305
  iterable_type = infer_expression_type(statement.iterable, env:)
306
306
  iterator_info = iterator_loop_info(iterable_type, env:)
307
- raise LoweringError, "for loop expects start..stop, array[T, N], span[T], or an iterable with iter()/next(), got #{iterable_type}" unless iterator_info
307
+ raise LoweringError.new("for loop expects start..stop, array[T, N], span[T], or an iterable with iter()/next(), got #{iterable_type}", line: 0, column: 0, path: @ctx.current_analysis_path) unless iterator_info
308
308
 
309
309
  iterable_setup, prepared_iterable = prepare_expression_for_inline_lowering(statement.iterable, env:, expected_type: iterable_type)
310
310
  iterator_c_name = fresh_c_temp_name(env, "for_iterator")
@@ -809,7 +809,7 @@ module MilkTea
809
809
  if captures.empty?
810
810
  worker_body = block_body.dup
811
811
  else
812
- raise LoweringError, "detach with captured variables is not yet supported; use a global function call or module-level variables"
812
+ raise LoweringError.new("detach with captured variables is not yet supported; use a global function call or module-level variables", line: 0, column: 0, path: @ctx.current_analysis_path)
813
813
  end
814
814
 
815
815
  @artifacts.synthetic_functions << IR::Function.new(
@@ -833,7 +833,7 @@ module MilkTea
833
833
 
834
834
  def validate_pfor_no_ref_captures!(captures)
835
835
  captures.each do |c|
836
- raise LoweringError, "cannot capture '#{c.name}' of type ref across thread boundary — ref values are not safe to share across threads" if ref_type?(c.type)
836
+ raise LoweringError.new("cannot capture '#{c.name}' of type ref across thread boundary — ref values are not safe to share across threads", line: 0, column: 0, path: @ctx.current_analysis_path) if ref_type?(c.type)
837
837
  end
838
838
  end
839
839
 
@@ -844,7 +844,7 @@ module MilkTea
844
844
  next if idx == other_idx
845
845
  next unless other[:capture_names].include?(name)
846
846
 
847
- raise LoweringError, "write conflict in parallel block: '#{name}' is written in spawn block #{idx + 1} and accessed in spawn block #{other_idx + 1}"
847
+ raise LoweringError.new("write conflict in parallel block: '#{name}' is written in spawn block #{idx + 1} and accessed in spawn block #{other_idx + 1}", line: 0, column: 0, path: @ctx.current_analysis_path)
848
848
  end
849
849
  end
850
850
  end
@@ -193,7 +193,7 @@ module MilkTea
193
193
  when AST::BreakStmt, AST::ContinueStmt, AST::PassStmt
194
194
  nil
195
195
  else
196
- raise LoweringError, "unsupported proc capture statement #{statement.class.name}"
196
+ raise LoweringError.new("unsupported proc capture statement #{statement.class.name}", line: 0, column: 0, path: @ctx.current_analysis_path)
197
197
  end
198
198
  end
199
199
 
@@ -248,7 +248,7 @@ module MilkTea
248
248
  AST::BooleanLiteral, AST::NullLiteral
249
249
  nil
250
250
  else
251
- raise LoweringError, "unsupported proc capture expression #{expression.class.name}"
251
+ raise LoweringError.new("unsupported proc capture expression #{expression.class.name}", line: 0, column: 0, path: @ctx.current_analysis_path)
252
252
  end
253
253
  end
254
254
 
@@ -321,7 +321,7 @@ module MilkTea
321
321
  when Types::Nullable
322
322
  []
323
323
  else
324
- raise LoweringError, "unsupported proc lifecycle container #{type.class.name}"
324
+ raise LoweringError.new("unsupported proc lifecycle container #{type.class.name}", line: 0, column: 0, path: @ctx.current_analysis_path)
325
325
  end
326
326
  end
327
327