fallible main

This commit is contained in:
2026-08-09 15:08:15 +02:00
parent 6688822de2
commit 572ffe7d07
4 changed files with 224 additions and 61 deletions
+21 -17
View File
@@ -1305,6 +1305,9 @@ type_from_syntax :: proc(
function_channel_type :: proc(checker: ^Checker, function: ast.Function) -> types.Type {
result := type_from_syntax(checker, function.result, function.pkg, function.file)
if function.pkg == 0 && function.name == checker.main_symbol && result == types.INT {
result = types.I32
}
if types.is_valid(function.error) {
return types.fallible(&checker.module.types, result, type_from_syntax(checker, function.error, function.pkg, function.file))
}
@@ -4703,10 +4706,6 @@ ensure_spec :: proc(
comptime_signature.allocator = checker.allocator
append(&comptime_signature, ..comptime_values)
result := function_channel_type(checker, function)
if function.pkg == 0 && function.name == checker.main_symbol && function.result == types.INT &&
!types.is_valid(function.error) {
result = types.I32
}
index := spec_id(len(checker.specs))
append(
&checker.specs,
@@ -5825,12 +5824,7 @@ infer_expr :: proc(
}
} else {
declared := function_channel_type(checker, function)
if function.pkg == 0 && function.name == checker.main_symbol && function.result == types.INT &&
!types.is_valid(function.error) {
last = types.I32
} else {
last = declared if is_runtime_type(checker, declared) || types.is_void(declared) || types.is_noreturn(declared) else types.INVALID
}
last = declared if is_runtime_type(checker, declared) || types.is_void(declared) || types.is_noreturn(declared) else types.INVALID
}
delete(stack[frame_index].args, checker.allocator)
stack[frame_index].args = nil
@@ -10402,7 +10396,10 @@ build_expr :: proc(
make_link_name :: proc(checker: ^Checker, id: Spec_Id) -> string {
spec := checker.specs[id]
function := checker.ast_module.functions[spec.template]
if function.pkg == 0 && function.name == checker.main_symbol && checker.entry_point == .Plain {
native_main := function.pkg == 0 && function.name == checker.main_symbol &&
checker.entry_point == .Plain &&
types.kind(spec.result, &checker.module.types) != .Fallible
if native_main {
return fmt.aprintf("main", allocator = checker.allocator)
}
if function.generated {
@@ -13981,7 +13978,9 @@ build_function :: proc(checker: ^Checker, id: Spec_Id) {
problematic := signature_diagnostic != source.INVALID_DIAGNOSTIC ||
checker.template_diagnostics[spec.template] != source.INVALID_DIAGNOSTIC
native_main := function.pkg == 0 && function.name == checker.main_symbol && checker.entry_point == .Plain
native_main := function.pkg == 0 && function.name == checker.main_symbol &&
checker.entry_point == .Plain &&
types.kind(spec.result, &checker.module.types) != .Fallible
if !function.has_body {
if unresolved_result && signature_diagnostic == source.INVALID_DIAGNOSTIC &&
checker.template_diagnostics[spec.template] == source.INVALID_DIAGNOSTIC {
@@ -14814,18 +14813,23 @@ check :: proc(
id = source.add(
diagnostics,
template.span,
"main must be unique, have a body, take no parameters or one @std/process Init, and return void, i32, or int",
"main must be unique, have a body, take no parameters or one @std/process Init, and return void, i32, or int, optionally with an error channel",
)
}
checker.module.injected_main = hir.INVALID_FUNCTION
checker.module.io_provider = hir.INVALID_FUNCTION
replace_main_with_trap(&checker, id)
} else if checker.entry_point == .Process {
} else {
main_spec := find_spec(&checker, main_template, nil)
provider_spec := find_spec(&checker, checker.io_provider_template, nil)
if main_spec != INVALID_SPEC && provider_spec != INVALID_SPEC {
if checker.entry_point == .Process {
provider_spec := find_spec(&checker, checker.io_provider_template, nil)
if main_spec != INVALID_SPEC && provider_spec != INVALID_SPEC {
checker.module.injected_main = checker.specs[main_spec].hir_id
checker.module.io_provider = checker.specs[provider_spec].hir_id
}
} else if main_spec != INVALID_SPEC &&
types.kind(checker.specs[main_spec].result, &checker.module.types) == .Fallible {
checker.module.injected_main = checker.specs[main_spec].hir_id
checker.module.io_provider = checker.specs[provider_spec].hir_id
}
}
}