errdefer and try/defer fix
This commit is contained in:
@@ -3747,8 +3747,13 @@ defer_misuse_is_diagnosed :: proc(t: ^testing.T) {
|
||||
bad_defer_return()
|
||||
bad_defer_break()
|
||||
bad_return_in_defer()
|
||||
bad_errdefer_nonfallible()
|
||||
_ = bad_try_in_defer() catch 0
|
||||
_ = bad_try_in_errdefer() catch 0
|
||||
return 0
|
||||
}
|
||||
Failure :: enum { bad }
|
||||
fail func() i32 ! Failure { return .bad }
|
||||
bad_defer_return func() void {
|
||||
defer return
|
||||
}
|
||||
@@ -3763,6 +3768,17 @@ bad_return_in_defer func() void {
|
||||
return
|
||||
}
|
||||
}
|
||||
bad_errdefer_nonfallible func() void {
|
||||
errdefer {}
|
||||
}
|
||||
bad_try_in_defer func() i32 ! Failure {
|
||||
defer _ = try fail()
|
||||
return 1
|
||||
}
|
||||
bad_try_in_errdefer func() i32 ! Failure {
|
||||
errdefer _ = try fail()
|
||||
return 1
|
||||
}
|
||||
`
|
||||
source_file := source.Source{path="test.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
@@ -3779,14 +3795,50 @@ bad_return_in_defer func() void {
|
||||
defer_return := false
|
||||
defer_break := false
|
||||
return_in_defer := false
|
||||
errdefer_nonfallible := false
|
||||
try_in_defer := 0
|
||||
for diagnostic in diagnostics.items {
|
||||
defer_return = defer_return || strings.contains(diagnostic.message, "cannot defer a 'return' statement")
|
||||
defer_break = defer_break || strings.contains(diagnostic.message, "cannot defer a 'break' statement")
|
||||
return_in_defer = return_in_defer || strings.contains(diagnostic.message, "cannot 'return' inside a 'defer'")
|
||||
errdefer_nonfallible = errdefer_nonfallible || strings.contains(diagnostic.message, "'errdefer' requires an enclosing fallible function")
|
||||
try_in_defer += 1 if strings.contains(diagnostic.message, "cannot 'try' inside a 'defer'") else 0
|
||||
}
|
||||
testing.expect(t, defer_return)
|
||||
testing.expect(t, defer_break)
|
||||
testing.expect(t, return_in_defer)
|
||||
testing.expect(t, errdefer_nonfallible)
|
||||
testing.expect_value(t, try_in_defer, 2)
|
||||
}
|
||||
|
||||
@(test)
|
||||
errdefer_capture_syntax_is_diagnosed :: proc(t: ^testing.T) {
|
||||
text := `Failure :: enum { bad }
|
||||
bad func() i32 ! Failure {
|
||||
errdefer || {}
|
||||
errdefer |first, second| {}
|
||||
return .bad
|
||||
}
|
||||
main func() i32 { return bad() catch 0 }
|
||||
`
|
||||
source_file := source.Source{path="test.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
stream := lexer.lex(&source_file, &diagnostics, &symbols)
|
||||
defer delete(stream.items)
|
||||
module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
defer ast.destroy_module(&module)
|
||||
|
||||
missing := false
|
||||
multiple := false
|
||||
for diagnostic in diagnostics.items {
|
||||
missing = missing || strings.contains(diagnostic.message, "expected an errdefer capture name")
|
||||
multiple = multiple || strings.contains(diagnostic.message, "'errdefer' accepts exactly one capture")
|
||||
}
|
||||
testing.expect(t, missing)
|
||||
testing.expect(t, multiple)
|
||||
}
|
||||
|
||||
@(test)
|
||||
|
||||
Reference in New Issue
Block a user