mt-lang 0.3.17 → 0.3.20
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 +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/c_backend/expressions.rb +34 -23
- data/lib/milk_tea/core/c_backend/feature_detection.rb +25 -45
- data/lib/milk_tea/core/c_backend/type_collectors.rb +18 -30
- data/lib/milk_tea/core/c_backend/type_declaration.rb +0 -6
- data/lib/milk_tea/core/c_backend.rb +49 -39
- data/lib/milk_tea/core/compile_time.rb +98 -72
- data/lib/milk_tea/core/intrinsics.rb +7 -0
- data/lib/milk_tea/core/lexer.rb +46 -35
- data/lib/milk_tea/core/lowering/block.rb +9 -0
- data/lib/milk_tea/core/lowering/calls.rb +2 -0
- data/lib/milk_tea/core/lowering/declarations.rb +1 -1
- data/lib/milk_tea/core/lowering/functions.rb +11 -8
- data/lib/milk_tea/core/lowering/resolve.rb +10 -3
- data/lib/milk_tea/core/lowering/scans.rb +13 -18
- data/lib/milk_tea/core/module_binder.rb +9 -10
- data/lib/milk_tea/core/module_loader.rb +38 -42
- data/lib/milk_tea/core/module_path_resolver.rb +1 -4
- data/lib/milk_tea/core/parser/declarations.rb +43 -19
- data/lib/milk_tea/core/parser/expressions.rb +4 -7
- data/lib/milk_tea/core/parser/statements.rb +5 -5
- data/lib/milk_tea/core/parser.rb +26 -0
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +24 -31
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +20 -23
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +117 -85
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +19 -41
- data/lib/milk_tea/core/semantic_analyzer.rb +56 -37
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +6 -0
- data/lib/milk_tea/tooling/cli/commands/bindgen.rb +11 -0
- data/lib/milk_tea/tooling/cli/commands/build.rb +37 -0
- data/lib/milk_tea/tooling/cli/commands/cache.rb +46 -0
- data/lib/milk_tea/tooling/cli/commands/check.rb +116 -0
- data/lib/milk_tea/tooling/cli/commands/command_base.rb +8 -0
- data/lib/milk_tea/tooling/cli/commands/completions.rb +48 -0
- data/lib/milk_tea/tooling/cli/commands/dap.rb +58 -0
- data/lib/milk_tea/tooling/cli/commands/debug.rb +77 -0
- data/lib/milk_tea/tooling/cli/commands/deps.rb +17 -0
- data/lib/milk_tea/tooling/cli/commands/docs.rb +58 -0
- data/lib/milk_tea/tooling/cli/commands/emit_c.rb +64 -0
- data/lib/milk_tea/tooling/cli/commands/format.rb +199 -0
- data/lib/milk_tea/tooling/cli/commands/lex.rb +46 -0
- data/lib/milk_tea/tooling/cli/commands/lint.rb +248 -0
- data/lib/milk_tea/tooling/cli/commands/lower.rb +50 -0
- data/lib/milk_tea/tooling/cli/commands/lsp.rb +43 -0
- data/lib/milk_tea/tooling/cli/commands/new.rb +26 -0
- data/lib/milk_tea/tooling/cli/commands/parse.rb +51 -0
- data/lib/milk_tea/tooling/cli/commands/run.rb +99 -0
- data/lib/milk_tea/tooling/cli/commands/snapshot.rb +117 -0
- data/lib/milk_tea/tooling/cli/commands/test.rb +557 -0
- data/lib/milk_tea/tooling/cli/commands/toolchain.rb +16 -0
- data/lib/milk_tea/tooling/cli.rb +101 -1893
- metadata +24 -2
|
@@ -645,22 +645,13 @@ module MilkTea
|
|
|
645
645
|
)
|
|
646
646
|
end
|
|
647
647
|
|
|
648
|
-
def
|
|
649
|
-
|
|
648
|
+
def specialized_receiver_method_kind(receiver_type, name)
|
|
649
|
+
SPECIALIZED_RECEIVERS.each_value do |spec|
|
|
650
|
+
next unless send(spec[:predicate], receiver_type)
|
|
650
651
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
def atomic_method_kind(receiver_type, name)
|
|
655
|
-
return unless atomic_type?(receiver_type)
|
|
656
|
-
|
|
657
|
-
ATOMIC_METHOD_KINDS[name]
|
|
658
|
-
end
|
|
659
|
-
|
|
660
|
-
def simd_method_kind(receiver_type, name)
|
|
661
|
-
return unless simd_type?(receiver_type)
|
|
662
|
-
|
|
663
|
-
SIMD_METHOD_KINDS[name]
|
|
652
|
+
return spec[:kinds][name]
|
|
653
|
+
end
|
|
654
|
+
nil
|
|
664
655
|
end
|
|
665
656
|
|
|
666
657
|
def check_atomic_method_call(kind, receiver_type, receiver, arguments, scopes:)
|
|
@@ -750,8 +741,8 @@ module MilkTea
|
|
|
750
741
|
|
|
751
742
|
case expression
|
|
752
743
|
when AST::Call
|
|
753
|
-
|
|
754
|
-
|
|
744
|
+
resolution = resolve_callable(expression.callee, scopes:)
|
|
745
|
+
resolution.kind == :struct && resolution.value == target_type
|
|
755
746
|
when AST::Specialization
|
|
756
747
|
return false unless expression.callee.is_a?(AST::Identifier)
|
|
757
748
|
return false unless %w[zero default].include?(expression.callee.name)
|
|
@@ -772,12 +763,6 @@ module MilkTea
|
|
|
772
763
|
name == "as_str" || name == "as_cstr"
|
|
773
764
|
end
|
|
774
765
|
|
|
775
|
-
def str_buffer_method_kind(receiver_type, name)
|
|
776
|
-
return unless str_buffer_type?(receiver_type)
|
|
777
|
-
|
|
778
|
-
STR_BUFFER_METHOD_KINDS[name]
|
|
779
|
-
end
|
|
780
|
-
|
|
781
766
|
def str_buffer_method_name(kind)
|
|
782
767
|
STR_BUFFER_METHOD_NAMES.fetch(kind)
|
|
783
768
|
end
|
|
@@ -1032,42 +1017,50 @@ module MilkTea
|
|
|
1032
1017
|
end
|
|
1033
1018
|
end
|
|
1034
1019
|
|
|
1035
|
-
fill_parameter_defaults!(by_position, params, binding
|
|
1020
|
+
fill_parameter_defaults!(by_position, params, binding)
|
|
1036
1021
|
|
|
1037
1022
|
by_position.reject(&:nil?)
|
|
1038
1023
|
end
|
|
1039
1024
|
|
|
1040
|
-
def fill_parameter_defaults!(by_position, params, binding
|
|
1025
|
+
def fill_parameter_defaults!(by_position, params, binding)
|
|
1041
1026
|
return unless binding
|
|
1042
1027
|
|
|
1043
1028
|
ast_params = binding.ast.params
|
|
1044
|
-
return unless ast_params.any? { |p|
|
|
1029
|
+
return unless ast_params.any? { |p| param_has_default?(p) }
|
|
1045
1030
|
|
|
1046
1031
|
params.each_with_index do |param, idx|
|
|
1047
1032
|
next unless by_position[idx].nil?
|
|
1048
1033
|
next unless idx < ast_params.length
|
|
1049
1034
|
|
|
1050
1035
|
ast_param = ast_params[idx]
|
|
1051
|
-
next unless
|
|
1036
|
+
next unless param_has_default?(ast_param)
|
|
1052
1037
|
|
|
1053
|
-
by_position[idx] =
|
|
1038
|
+
by_position[idx] = default_arg_for(ast_param)
|
|
1054
1039
|
end
|
|
1055
1040
|
end
|
|
1056
1041
|
|
|
1057
1042
|
def fill_positional_defaults!(arguments, binding)
|
|
1058
|
-
return unless binding.ast.params.any? { |p|
|
|
1043
|
+
return unless binding.ast.params.any? { |p| param_has_default?(p) }
|
|
1059
1044
|
|
|
1060
1045
|
ast_params = binding.ast.params
|
|
1061
1046
|
while arguments.length < ast_params.length
|
|
1062
1047
|
ast_param = ast_params[arguments.length]
|
|
1063
|
-
if
|
|
1064
|
-
arguments <<
|
|
1048
|
+
if param_has_default?(ast_param)
|
|
1049
|
+
arguments << default_arg_for(ast_param)
|
|
1065
1050
|
else
|
|
1066
1051
|
break
|
|
1067
1052
|
end
|
|
1068
1053
|
end
|
|
1069
1054
|
end
|
|
1070
1055
|
|
|
1056
|
+
def param_has_default?(ast_param)
|
|
1057
|
+
ast_param.respond_to?(:default_value) && ast_param.default_value
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
def default_arg_for(ast_param)
|
|
1061
|
+
AST::Argument.new(name: nil, value: ast_param.default_value)
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1071
1064
|
def count_required_params(binding)
|
|
1072
1065
|
return binding.type.params.length unless binding.ast.params.any? { |p| p.respond_to?(:default_value) && p.default_value }
|
|
1073
1066
|
|
|
@@ -199,8 +199,8 @@ module MilkTea
|
|
|
199
199
|
when AST::Specialization
|
|
200
200
|
if expression.callee.is_a?(AST::Identifier)
|
|
201
201
|
if expression.callee.name == "zero"
|
|
202
|
-
|
|
203
|
-
return check_zero_call(
|
|
202
|
+
resolution = resolve_callable(expression, scopes:)
|
|
203
|
+
return check_zero_call(resolution.value, [], expected_type:) if resolution.kind == :zero
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
if expression.callee.name == "default"
|
|
@@ -397,10 +397,7 @@ module MilkTea
|
|
|
397
397
|
if char_array_removed_text_method?(method_receiver_type, expression.member)
|
|
398
398
|
raise_sema_error("#{method_receiver_type}.#{expression.member} is not available; array[char, N] is raw storage, use str_buffer[N] or an explicit helper")
|
|
399
399
|
end
|
|
400
|
-
if
|
|
401
|
-
raise_sema_error("method #{method_receiver_type}.#{expression.member} must be called")
|
|
402
|
-
end
|
|
403
|
-
if event_type?(method_receiver_type) && event_method_kind(method_receiver_type, expression.member)
|
|
400
|
+
if specialized_receiver_method_kind(method_receiver_type, expression.member)
|
|
404
401
|
raise_sema_error("method #{method_receiver_type}.#{expression.member} must be called")
|
|
405
402
|
end
|
|
406
403
|
|
|
@@ -923,7 +920,10 @@ module MilkTea
|
|
|
923
920
|
end
|
|
924
921
|
|
|
925
922
|
def infer_call(expression, scopes:, expected_type: nil)
|
|
926
|
-
|
|
923
|
+
resolution = resolve_callable(expression.callee, scopes:)
|
|
924
|
+
callable_kind = resolution.kind
|
|
925
|
+
callable = resolution.value
|
|
926
|
+
receiver = resolution.receiver
|
|
927
927
|
@resolved_call_kinds[@ctx.ast.node_ids[expression.callee.object_id]] = callable_kind
|
|
928
928
|
|
|
929
929
|
case callable_kind
|
|
@@ -1152,7 +1152,9 @@ module MilkTea
|
|
|
1152
1152
|
call = expression
|
|
1153
1153
|
return unless call.is_a?(AST::Call)
|
|
1154
1154
|
|
|
1155
|
-
|
|
1155
|
+
resolution = resolve_callable(call.callee, scopes:)
|
|
1156
|
+
callable_kind = resolution.kind
|
|
1157
|
+
callable = resolution.value
|
|
1156
1158
|
return unless callable_kind == :function
|
|
1157
1159
|
|
|
1158
1160
|
callable = specialize_function_binding(
|
|
@@ -1245,6 +1247,11 @@ module MilkTea
|
|
|
1245
1247
|
end
|
|
1246
1248
|
|
|
1247
1249
|
def resolve_callable(callee, scopes:)
|
|
1250
|
+
kind, value, receiver = resolve_callable_raw(callee, scopes:)
|
|
1251
|
+
CallableResolution.new(kind:, value:, receiver:)
|
|
1252
|
+
end
|
|
1253
|
+
|
|
1254
|
+
def resolve_callable_raw(callee, scopes:)
|
|
1248
1255
|
case callee
|
|
1249
1256
|
when AST::Identifier
|
|
1250
1257
|
if (binding = lookup_value(callee.name, scopes))
|
|
@@ -1343,20 +1350,8 @@ module MilkTea
|
|
|
1343
1350
|
raise_sema_error("#{method_receiver_type}.#{callee.member} is not available; array[char, N] is raw storage, use str_buffer[N] or an explicit helper")
|
|
1344
1351
|
end
|
|
1345
1352
|
|
|
1346
|
-
if (
|
|
1347
|
-
return [
|
|
1348
|
-
end
|
|
1349
|
-
|
|
1350
|
-
if (event_method = event_method_kind(method_receiver_type, callee.member))
|
|
1351
|
-
return [event_method, method_receiver_type, callee.receiver]
|
|
1352
|
-
end
|
|
1353
|
-
|
|
1354
|
-
if (atomic_method = atomic_method_kind(method_receiver_type, callee.member))
|
|
1355
|
-
return [atomic_method, method_receiver_type, callee.receiver]
|
|
1356
|
-
end
|
|
1357
|
-
|
|
1358
|
-
if (simd_method = simd_method_kind(method_receiver_type, callee.member))
|
|
1359
|
-
return [simd_method, method_receiver_type, callee.receiver]
|
|
1353
|
+
if (kind = specialized_receiver_method_kind(method_receiver_type, callee.member))
|
|
1354
|
+
return [kind, method_receiver_type, callee.receiver]
|
|
1360
1355
|
end
|
|
1361
1356
|
|
|
1362
1357
|
field_receiver_type = infer_field_receiver_type(callee.receiver, scopes:)
|
|
@@ -1574,7 +1569,9 @@ module MilkTea
|
|
|
1574
1569
|
end
|
|
1575
1570
|
|
|
1576
1571
|
def resolve_callable_handle_argument(expression, scopes:)
|
|
1577
|
-
|
|
1572
|
+
resolution = resolve_callable(expression, scopes:)
|
|
1573
|
+
callable_kind = resolution.kind
|
|
1574
|
+
callable = resolution.value
|
|
1578
1575
|
raise_sema_error("callable_of expects a callable declaration name") unless callable_kind == :function
|
|
1579
1576
|
|
|
1580
1577
|
Types::CallableHandle.new(describe_expression(expression), callable.ast)
|
|
@@ -211,123 +211,148 @@ module MilkTea
|
|
|
211
211
|
|
|
212
212
|
def resolve_non_nullable_type(type_ref, type_params: {}, type_param_constraints: {}, nested_types: nil)
|
|
213
213
|
if type_ref.is_a?(AST::FunctionType)
|
|
214
|
-
|
|
215
|
-
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
|
|
216
|
-
end
|
|
217
|
-
return Types::Registry.function(nil, params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
|
|
214
|
+
return resolve_function_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
218
215
|
end
|
|
219
216
|
|
|
220
217
|
if type_ref.is_a?(AST::ProcType)
|
|
221
|
-
|
|
222
|
-
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
|
|
223
|
-
end
|
|
224
|
-
return Types::Registry.proc(params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
|
|
218
|
+
return resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
225
219
|
end
|
|
226
220
|
|
|
227
221
|
if type_ref.is_a?(AST::DynType)
|
|
228
|
-
|
|
229
|
-
raise_sema_error("generic interface #{interface.name} requires type arguments") if interface.is_a?(GenericInterfaceBinding)
|
|
230
|
-
type_arguments = interface.type_arguments || []
|
|
231
|
-
type = Types::Dyn.new(interface, type_arguments)
|
|
232
|
-
type = Types::Registry.nullable(type) if type_ref.nullable
|
|
233
|
-
return type
|
|
222
|
+
return resolve_dyn_type_ref(type_ref)
|
|
234
223
|
end
|
|
235
224
|
|
|
236
225
|
if type_ref.is_a?(AST::TupleType)
|
|
237
|
-
|
|
238
|
-
element_types = []
|
|
239
|
-
type_ref.element_types.each do |et|
|
|
240
|
-
if et.is_a?(AST::Argument)
|
|
241
|
-
names << et.name
|
|
242
|
-
element_types << resolve_type_ref(et.value, type_params:, type_param_constraints:)
|
|
243
|
-
else
|
|
244
|
-
names << nil
|
|
245
|
-
element_types << resolve_type_ref(et, type_params:, type_param_constraints:)
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
has_named = names.any?
|
|
249
|
-
return Types::Registry.tuple(element_types, field_names: has_named ? names : nil)
|
|
226
|
+
return resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
250
227
|
end
|
|
251
228
|
|
|
252
229
|
parts = type_ref.name.parts
|
|
253
230
|
|
|
254
231
|
if type_ref.arguments.any?
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if name != "ref" && arguments.any? { |argument| contains_ref_type?(argument) && !stored_ref_supported_type?(argument) }
|
|
259
|
-
raise_sema_error("ref types cannot be nested inside #{name}", type_ref)
|
|
260
|
-
end
|
|
232
|
+
return resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:)
|
|
233
|
+
end
|
|
261
234
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
end
|
|
235
|
+
if parts.length == 1 && type_ref.lifetime
|
|
236
|
+
raise_sema_error("lifetime annotations are only valid on ref types, got #{type_ref.name}", type_ref)
|
|
237
|
+
end
|
|
266
238
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
return generic_type.instantiate(arguments)
|
|
271
|
-
rescue ArgumentError => error
|
|
272
|
-
raise_sema_error(error.message)
|
|
273
|
-
end
|
|
274
|
-
end
|
|
239
|
+
if parts.length == 1
|
|
240
|
+
return resolve_single_part_type_ref(type_ref, parts.first, nested_types:, type_params:)
|
|
241
|
+
end
|
|
275
242
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
type = @ctx.types[name]
|
|
279
|
-
if type.is_a?(Types::Struct) && type.lifetime_params&.any?
|
|
280
|
-
lifetime_args = arguments.select { |a| a.is_a?(Types::LifetimeRef) }.map(&:name)
|
|
281
|
-
if lifetime_args.to_set == type.lifetime_params.to_set
|
|
282
|
-
return type
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
end
|
|
243
|
+
resolve_multi_part_type_ref(type_ref, parts)
|
|
244
|
+
end
|
|
286
245
|
|
|
287
|
-
|
|
288
|
-
|
|
246
|
+
def resolve_function_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
247
|
+
params = type_ref.params.map do |param|
|
|
248
|
+
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
|
|
249
|
+
end
|
|
250
|
+
Types::Registry.function(nil, params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
|
|
251
|
+
end
|
|
289
252
|
|
|
290
|
-
|
|
253
|
+
def resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
254
|
+
params = type_ref.params.map do |param|
|
|
255
|
+
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
|
|
256
|
+
end
|
|
257
|
+
Types::Registry.proc(params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
|
|
258
|
+
end
|
|
291
259
|
|
|
292
|
-
|
|
260
|
+
def resolve_dyn_type_ref(type_ref)
|
|
261
|
+
interface = resolve_interface_ref(type_ref.interface)
|
|
262
|
+
raise_sema_error("generic interface #{interface.name} requires type arguments") if interface.is_a?(GenericInterfaceBinding)
|
|
263
|
+
type_arguments = interface.type_arguments || []
|
|
264
|
+
type = Types::Dyn.new(interface, type_arguments)
|
|
265
|
+
type = Types::Registry.nullable(type) if type_ref.nullable
|
|
266
|
+
type
|
|
267
|
+
end
|
|
293
268
|
|
|
294
|
-
|
|
295
|
-
|
|
269
|
+
def resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
270
|
+
names = []
|
|
271
|
+
element_types = []
|
|
272
|
+
type_ref.element_types.each do |et|
|
|
273
|
+
if et.is_a?(AST::Argument)
|
|
274
|
+
names << et.name
|
|
275
|
+
element_types << resolve_type_ref(et.value, type_params:, type_param_constraints:)
|
|
276
|
+
else
|
|
277
|
+
names << nil
|
|
278
|
+
element_types << resolve_type_ref(et, type_params:, type_param_constraints:)
|
|
279
|
+
end
|
|
296
280
|
end
|
|
281
|
+
has_named = names.any?
|
|
282
|
+
Types::Registry.tuple(element_types, field_names: has_named ? names : nil)
|
|
283
|
+
end
|
|
297
284
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
285
|
+
def resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:)
|
|
286
|
+
name = parts.join(".")
|
|
287
|
+
arguments = type_ref.arguments.map { |argument| resolve_type_argument(argument.value, type_params:, type_param_constraints:) }
|
|
301
288
|
|
|
302
|
-
if
|
|
303
|
-
|
|
289
|
+
if name != "ref" && arguments.any? { |argument| contains_ref_type?(argument) && !stored_ref_supported_type?(argument) }
|
|
290
|
+
raise_sema_error("ref types cannot be nested inside #{name}", type_ref)
|
|
291
|
+
end
|
|
304
292
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
293
|
+
if name == "Task"
|
|
294
|
+
validate_generic_type!(name, arguments)
|
|
295
|
+
return Types::Registry.task(arguments[0])
|
|
296
|
+
end
|
|
308
297
|
|
|
309
|
-
|
|
310
|
-
|
|
298
|
+
if (generic_type = resolve_named_generic_type(parts))
|
|
299
|
+
begin
|
|
300
|
+
validate_generic_type_param_constraints!(generic_type, arguments, context: "type #{generic_type}", available_type_param_constraints: type_param_constraints)
|
|
301
|
+
return generic_type.instantiate(arguments)
|
|
302
|
+
rescue ArgumentError => error
|
|
303
|
+
raise_sema_error(error.message)
|
|
311
304
|
end
|
|
305
|
+
end
|
|
312
306
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
307
|
+
if arguments.all? { |a| a.is_a?(Types::LifetimeRef) }
|
|
308
|
+
type = @ctx.types[name]
|
|
309
|
+
if type.is_a?(Types::Struct) && type.lifetime_params&.any?
|
|
310
|
+
lifetime_args = arguments.select { |a| a.is_a?(Types::LifetimeRef) }.map(&:name)
|
|
311
|
+
if lifetime_args.to_set == type.lifetime_params.to_set
|
|
312
|
+
return type
|
|
319
313
|
end
|
|
320
|
-
raise_sema_error("unknown type #{parts.first}", type_ref, suggestion: suggestion ? "did you mean '#{suggestion}'?" : nil)
|
|
321
314
|
end
|
|
322
|
-
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
validate_generic_type!(name, arguments)
|
|
318
|
+
return Types::Registry.span(arguments.first) if name == "span"
|
|
319
|
+
|
|
320
|
+
return Types::Registry.soa(arguments[0], count: arguments[1].value) if name == "SoA"
|
|
321
|
+
|
|
322
|
+
return Types::Registry.simd(arguments[0], lane_count: arguments[1].value) if name == "simd"
|
|
323
|
+
|
|
324
|
+
arguments = [type_ref.lifetime] + arguments if name == "ref" && type_ref.lifetime
|
|
325
|
+
Types::Registry.generic_instance(name, arguments)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def resolve_single_part_type_ref(type_ref, name, nested_types:, type_params:)
|
|
329
|
+
return type_params.fetch(name) if type_params.key?(name)
|
|
323
330
|
|
|
331
|
+
if nested_types && (type = nested_types[name])
|
|
324
332
|
return type
|
|
325
333
|
end
|
|
326
334
|
|
|
327
|
-
if
|
|
328
|
-
|
|
329
|
-
|
|
335
|
+
if name.start_with?("@")
|
|
336
|
+
raise_sema_error("unknown lifetime #{name}", type_ref)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
type = @ctx.types[name]
|
|
340
|
+
unless type
|
|
341
|
+
type_names = @ctx.types.keys
|
|
342
|
+
suggestion = suggest_name(name, type_names)
|
|
343
|
+
unless suggestion
|
|
344
|
+
suggestion = import_suggestion_for_type(name)
|
|
345
|
+
end
|
|
346
|
+
raise_sema_error("unknown type #{name}", type_ref, suggestion: suggestion ? "did you mean '#{suggestion}'?" : nil)
|
|
330
347
|
end
|
|
348
|
+
raise_sema_error("generic type #{name} requires type arguments", type_ref) if type.is_a?(Types::GenericStructDefinition) || type.is_a?(Types::GenericVariantDefinition)
|
|
349
|
+
|
|
350
|
+
type
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def resolve_multi_part_type_ref(type_ref, parts)
|
|
354
|
+
type = resolve_nested_type_ref(parts)
|
|
355
|
+
return type if type
|
|
331
356
|
|
|
332
357
|
if parts.length == 2 && @ctx.imports.key?(parts.first)
|
|
333
358
|
imported_module = @ctx.imports.fetch(parts.first)
|
|
@@ -386,12 +411,19 @@ module MilkTea
|
|
|
386
411
|
def resolve_type_argument_ref(type_ref, type_params:, type_param_constraints:)
|
|
387
412
|
return resolve_type_ref(type_ref, type_params:, type_param_constraints:) unless literal_type_argument_name_candidate?(type_ref)
|
|
388
413
|
|
|
389
|
-
|
|
390
|
-
|
|
414
|
+
result = try_resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
415
|
+
return result if result
|
|
416
|
+
|
|
391
417
|
literal_type_argument = resolve_named_literal_type_argument(type_ref)
|
|
392
418
|
return literal_type_argument if literal_type_argument
|
|
393
419
|
|
|
394
|
-
|
|
420
|
+
resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def try_resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
424
|
+
resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
425
|
+
rescue SemanticError
|
|
426
|
+
nil
|
|
395
427
|
end
|
|
396
428
|
|
|
397
429
|
def literal_type_argument_name_candidate?(type_ref)
|
|
@@ -555,30 +555,32 @@ module MilkTea
|
|
|
555
555
|
end
|
|
556
556
|
end
|
|
557
557
|
|
|
558
|
+
MATCH_STMT_DISPATCH = [
|
|
559
|
+
[Types::Enum, :each_enum_match_arm, true],
|
|
560
|
+
[Types::Variant, :each_variant_match_arm, true],
|
|
561
|
+
[:integer, :each_integer_match_arm, false],
|
|
562
|
+
[Types::StringView, :each_string_match_arm, false],
|
|
563
|
+
[Types::Tuple, :each_tuple_match_arm, false],
|
|
564
|
+
].freeze
|
|
565
|
+
|
|
558
566
|
def check_match_stmt(statement, scopes:, return_type:, allow_return:)
|
|
559
567
|
validate_consuming_foreign_expression!(statement.expression, scopes:, root_allowed: false)
|
|
560
568
|
scrutinee_type = infer_expression(statement.expression, scopes:)
|
|
569
|
+
|
|
561
570
|
if error_type?(scrutinee_type)
|
|
562
|
-
check_recovered_match_stmt(statement, scopes:, return_type:, allow_return:)
|
|
563
|
-
elsif scrutinee_type.is_a?(Types::Enum)
|
|
564
|
-
check_enum_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
565
|
-
elsif scrutinee_type.is_a?(Types::Variant)
|
|
566
|
-
check_variant_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
567
|
-
elsif integer_type?(scrutinee_type)
|
|
568
|
-
check_integer_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
569
|
-
elsif scrutinee_type.is_a?(Types::StringView)
|
|
570
|
-
check_string_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
571
|
-
elsif scrutinee_type.is_a?(Types::Tuple)
|
|
572
|
-
check_tuple_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
573
|
-
else
|
|
574
|
-
raise_sema_error("match requires an enum, variant, or integer scrutinee, got #{scrutinee_type}")
|
|
571
|
+
return check_recovered_match_stmt(statement, scopes:, return_type:, allow_return:)
|
|
575
572
|
end
|
|
576
|
-
end
|
|
577
573
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
574
|
+
MATCH_STMT_DISPATCH.each do |type_class, arm_method, per_arm_scopes|
|
|
575
|
+
next unless type_class == :integer ? integer_type?(scrutinee_type) : scrutinee_type.is_a?(type_class)
|
|
576
|
+
|
|
577
|
+
send(arm_method, statement, scrutinee_type, scopes:) do |arm, arm_scopes|
|
|
578
|
+
check_block(arm.body, scopes: per_arm_scopes ? arm_scopes : scopes, return_type:, allow_return:)
|
|
579
|
+
end
|
|
580
|
+
return
|
|
581
581
|
end
|
|
582
|
+
|
|
583
|
+
raise_sema_error("match requires an enum, variant, or integer scrutinee, got #{scrutinee_type}")
|
|
582
584
|
end
|
|
583
585
|
|
|
584
586
|
def each_enum_match_arm(statement, scrutinee_type, scopes:)
|
|
@@ -746,24 +748,6 @@ module MilkTea
|
|
|
746
748
|
end
|
|
747
749
|
end
|
|
748
750
|
|
|
749
|
-
def check_integer_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
750
|
-
each_integer_match_arm(statement, scrutinee_type, scopes:) do |arm|
|
|
751
|
-
check_block(arm.body, scopes:, return_type:, allow_return:)
|
|
752
|
-
end
|
|
753
|
-
end
|
|
754
|
-
|
|
755
|
-
def check_string_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
756
|
-
each_string_match_arm(statement, scrutinee_type, scopes:) do |arm|
|
|
757
|
-
check_block(arm.body, scopes:, return_type:, allow_return:)
|
|
758
|
-
end
|
|
759
|
-
end
|
|
760
|
-
|
|
761
|
-
def check_tuple_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
762
|
-
each_tuple_match_arm(statement, scrutinee_type, scopes:) do |arm|
|
|
763
|
-
check_block(arm.body, scopes:, return_type:, allow_return:)
|
|
764
|
-
end
|
|
765
|
-
end
|
|
766
|
-
|
|
767
751
|
def wildcard_pattern?(expression)
|
|
768
752
|
expression.is_a?(AST::Identifier) && expression.name == "_"
|
|
769
753
|
end
|
|
@@ -810,12 +794,6 @@ module MilkTea
|
|
|
810
794
|
failure_fields && failure_fields.length == 1 && failure_fields.key?("error")
|
|
811
795
|
end
|
|
812
796
|
|
|
813
|
-
def check_variant_match_stmt(statement, scrutinee_type, scopes:, return_type:, allow_return:)
|
|
814
|
-
each_variant_match_arm(statement, scrutinee_type, scopes:) do |arm, arm_scopes|
|
|
815
|
-
check_block(arm.body, scopes: arm_scopes, return_type:, allow_return:)
|
|
816
|
-
end
|
|
817
|
-
end
|
|
818
|
-
|
|
819
797
|
def each_variant_match_arm(statement, scrutinee_type, scopes:)
|
|
820
798
|
covered_arms = {}
|
|
821
799
|
wildcard_seen = false
|
|
@@ -94,6 +94,7 @@ module MilkTea
|
|
|
94
94
|
end
|
|
95
95
|
ResolvedAttributeApplication = Data.define(:binding, :argument_values)
|
|
96
96
|
AttributePresenceKey = Data.define(:target, :attribute_module_name, :attribute_name)
|
|
97
|
+
CallableResolution = Data.define(:kind, :value, :receiver)
|
|
97
98
|
TypeParamConstraintBinding = Data.define(:interfaces) do
|
|
98
99
|
def initialize(interfaces: []) = super
|
|
99
100
|
end
|
|
@@ -185,30 +186,47 @@ module MilkTea
|
|
|
185
186
|
end
|
|
186
187
|
|
|
187
188
|
def check
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
189
|
+
@completed_phases = Set.new
|
|
190
|
+
|
|
191
|
+
run_phase(:install_builtin_types)
|
|
192
|
+
run_phase(:install_builtin_attributes)
|
|
193
|
+
run_phase(:install_imports)
|
|
194
|
+
run_phase(:install_prelude_types, requires: [:install_imports])
|
|
195
|
+
run_phase(:declare_named_types, requires: [:install_builtin_types, :install_imports, :install_prelude_types])
|
|
196
|
+
run_phase(:resolve_generic_type_param_constraints, requires: [:declare_named_types])
|
|
197
|
+
run_phase(:resolve_type_aliases, requires: [:declare_named_types])
|
|
198
|
+
run_phase(:declare_attributes)
|
|
199
|
+
run_phase(:resolve_aggregate_fields, requires: [:resolve_type_aliases, :declare_named_types])
|
|
200
|
+
run_phase(:resolve_enum_members, requires: [:declare_named_types])
|
|
201
|
+
run_phase(:resolve_variant_arms, requires: [:declare_named_types])
|
|
202
|
+
run_phase(:collect_emit_declarations)
|
|
203
|
+
run_phase(:declare_top_level_values, requires: [:resolve_aggregate_fields, :resolve_type_aliases])
|
|
204
|
+
run_phase(:check_attribute_applications, requires: [:declare_attributes])
|
|
205
|
+
run_phase(:declare_functions, requires: [:resolve_aggregate_fields, :resolve_enum_members, :resolve_variant_arms])
|
|
206
|
+
run_phase(:check_interface_conformances, requires: [:declare_functions, :resolve_aggregate_fields])
|
|
207
|
+
run_phase(:check_top_level_values, requires: [:declare_top_level_values])
|
|
208
|
+
run_phase(:finalize_top_level_const_values, requires: [:check_top_level_values])
|
|
209
|
+
run_phase(:check_top_level_static_asserts, requires: [:finalize_top_level_const_values])
|
|
210
|
+
run_phase(:check_functions, requires: [:declare_functions, :resolve_aggregate_fields, :check_interface_conformances])
|
|
208
211
|
|
|
209
212
|
build_analysis
|
|
210
213
|
end
|
|
211
214
|
|
|
215
|
+
def run_phase(name, requires: [])
|
|
216
|
+
requires.each do |required|
|
|
217
|
+
unless @completed_phases&.include?(required)
|
|
218
|
+
raise "BUG: phase #{required} must run before #{name} — check phase ordering"
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
send(name)
|
|
222
|
+
ensure
|
|
223
|
+
@completed_phases << name if @completed_phases
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def run_collecting_phase(name, requires: [])
|
|
227
|
+
catch_structural { run_phase(name, requires:) }
|
|
228
|
+
end
|
|
229
|
+
|
|
212
230
|
def collect_emit_declarations
|
|
213
231
|
collect_emit_from_declarations(expanded_declarations)
|
|
214
232
|
@ctx.ast.declarations.grep(AST::ConstDecl).each { |decl| @ctx.const_declarations[decl.name] ||= decl }
|
|
@@ -274,23 +292,24 @@ module MilkTea
|
|
|
274
292
|
def check_collecting_errors
|
|
275
293
|
@collecting_errors = true
|
|
276
294
|
@structural_errors = []
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
295
|
+
@completed_phases = Set.new
|
|
296
|
+
|
|
297
|
+
run_collecting_phase(:install_builtin_types)
|
|
298
|
+
run_collecting_phase(:install_builtin_attributes)
|
|
299
|
+
run_collecting_phase(:install_imports)
|
|
300
|
+
run_collecting_phase(:install_prelude_types, requires: [:install_imports])
|
|
301
|
+
run_collecting_phase(:declare_named_types, requires: [:install_builtin_types, :install_imports, :install_prelude_types])
|
|
302
|
+
run_collecting_phase(:resolve_generic_type_param_constraints, requires: [:declare_named_types])
|
|
303
|
+
run_collecting_phase(:resolve_type_aliases, requires: [:declare_named_types])
|
|
304
|
+
run_collecting_phase(:declare_attributes)
|
|
305
|
+
run_collecting_phase(:resolve_aggregate_fields, requires: [:resolve_type_aliases, :declare_named_types])
|
|
306
|
+
run_collecting_phase(:resolve_enum_members, requires: [:declare_named_types])
|
|
307
|
+
run_collecting_phase(:resolve_variant_arms, requires: [:declare_named_types])
|
|
308
|
+
run_collecting_phase(:collect_emit_declarations)
|
|
309
|
+
run_collecting_phase(:declare_top_level_values, requires: [:resolve_aggregate_fields, :resolve_type_aliases])
|
|
310
|
+
run_collecting_phase(:check_attribute_applications, requires: [:declare_attributes])
|
|
311
|
+
run_collecting_phase(:declare_functions, requires: [:resolve_aggregate_fields, :resolve_enum_members, :resolve_variant_arms])
|
|
312
|
+
run_collecting_phase(:check_interface_conformances, requires: [:declare_functions, :resolve_aggregate_fields])
|
|
294
313
|
|
|
295
314
|
errors = @structural_errors.dup
|
|
296
315
|
|