error inference in fallible functions
This commit is contained in:
+23
-10
@@ -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,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user