error inference in fallible functions

This commit is contained in:
2026-08-09 16:17:49 +02:00
parent 572ffe7d07
commit a7a32894f3
5 changed files with 217 additions and 37 deletions
+23 -10
View File
@@ -403,8 +403,8 @@ parse_type_atom :: proc(parser: ^Parser) -> ast.Type_Syntax {
source.add(parser.diagnostics, current(parser).span, "expected ')' after function type parameters")
}
result := parse_type(parser)
if _, ok := allow(parser, .Bang); ok {
error_type := parse_error_type(parser)
error_type, _ := parse_function_error(parser, false)
if types.is_valid(error_type) {
if c_abi {
source.add(parser.diagnostics, current(parser).span, "c_func pointer types cannot be fallible")
} else {
@@ -530,6 +530,22 @@ parse_error_type :: proc(parser: ^Parser) -> ast.Type_Syntax {
return parse_type_pipe_tail(parser, left)
}
parse_function_error :: proc(parser: ^Parser, allow_inferred: bool) -> (ast.Type_Syntax, bool) {
bang, present := allow(parser, .Bang)
if !present {
return types.INVALID, false
}
kind := current(parser).kind
inferred := kind == .Left_Brace || kind == .Newline || kind == .Eof
if !inferred {
return parse_error_type(parser), false
}
if !allow_inferred {
source.add(parser.diagnostics, bang.span, "inferred error channels require a function body")
}
return types.INVALID, true
}
skip_parenthesized :: proc(parser: ^Parser) -> source.Span {
start := current(parser)
depth := 0
@@ -2600,10 +2616,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi, package_hidden
}
skip_newlines(parser)
result := parse_type(parser)
error_type := types.INVALID
if _, ok := allow(parser, .Bang); ok {
error_type = parse_error_type(parser)
}
error_type, infer_error := parse_function_error(parser, true)
end := previous(parser)
ended_by_newline := current(parser).kind == .Newline
if current(parser).kind == .Newline {
@@ -2626,6 +2639,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi, package_hidden
params=params,
result=result,
error=error_type,
infer_error=infer_error,
diagnostic=source.INVALID_DIAGNOSTIC,
})
return
@@ -2645,6 +2659,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi, package_hidden
params=params,
result=result,
error=error_type,
infer_error=infer_error,
body=body,
diagnostic=source.INVALID_DIAGNOSTIC,
})
@@ -2661,10 +2676,7 @@ parse_function_literal :: proc(parser: ^Parser) -> ast.Expr_Id {
}
skip_newlines(parser)
result := parse_type(parser)
error_type := types.INVALID
if _, ok := allow(parser, .Bang); ok {
error_type = parse_error_type(parser)
}
error_type, infer_error := parse_function_error(parser, true)
if current(parser).kind == .Newline {
skip_newlines(parser)
}
@@ -2687,6 +2699,7 @@ parse_function_literal :: proc(parser: ^Parser) -> ast.Expr_Id {
params=params,
result=result,
error=error_type,
infer_error=infer_error,
body=body,
diagnostic=source.INVALID_DIAGNOSTIC,
})