fallible ergonomics

This commit is contained in:
2026-06-30 20:32:13 +02:00
parent 07c560b750
commit 7ca7e33033
8 changed files with 289 additions and 25 deletions
+75
View File
@@ -2439,6 +2439,81 @@ main func() i32 {
testing.expect(t, len(hir_module.functions) > 1)
}
@(test)
fallible_ergonomics_rejects_bad_try_and_catch_blocks :: proc(t: ^testing.T) {
text := `A :: enum {
a
}
B :: enum {
b
}
fa func() i32 ! A {
return .a
}
bad_error func() i32 ! B {
x :: try fa()
return x
}
bad_catch func() i32 {
return fa() catch |e| {
_ = e
}
}
main func() i32 {
_ = bad_error() catch 0
return bad_catch()
}
`
source_file := source.Source{path="fallible_ergonomics.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)
ast_module := parser.parse(&stream, &source_file, &diagnostics)
defer ast.destroy_module(&ast_module)
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
defer hir.destroy_module(&hir_module)
found_error := false
found_yield := false
for diagnostic in diagnostics.items {
found_error = found_error || strings.contains(diagnostic.message, "'try' error channel cannot be widened")
found_yield = found_yield || strings.contains(diagnostic.message, "a value block must end with an explicit 'yield'")
}
testing.expect(t, found_error)
testing.expect(t, found_yield)
success_text := `A :: enum {
a
}
B :: enum {
b
}
Both :: alias A | B
fs func() i64 ! A {
return 1
}
bad_success func() i32 ! Both {
x :: try fs()
return x
}
main func() i32 {
return bad_success() catch 0
}
`
directory := "/tmp/brolang-test-try-success-mismatch"
main_path := "/tmp/brolang-test-try-success-mismatch/main.bro"
output := "/tmp/brolang-test-try-success-mismatch-output"
_ = os2.remove_all(directory)
defer _ = os2.remove_all(directory)
defer _ = os.remove(output)
testing.expect(t, os.make_directory(directory) == nil)
testing.expect(t, os.write_entire_file(main_path, transmute([]byte)success_text))
testing.expect_value(t, compiler_core.compile_package(directory, output), 1)
}
@(test)
errors_example_compiles_and_runs :: proc(t: ^testing.T) {
output := "/tmp/brolang-test-errors"