diff --git a/compiler/checker/checker.odin b/compiler/checker/checker.odin index 70e0f26..41f7fae 100644 --- a/compiler/checker/checker.odin +++ b/compiler/checker/checker.odin @@ -5040,9 +5040,6 @@ infer_compound_expr :: proc( } if expr.right != ast.INVALID_EXPR { fallback := infer_nested_expr(checker, expr.right, fallback_locals[:], pkg, file, demanded, local_types) - if types.is_valid(success) && types.is_valid(fallback) && !types.equal(success, fallback) { - return types.widest(success, fallback) - } return success if types.is_valid(success) else fallback } infer_statements(checker, expr.body, &fallback_locals, local_types, pkg, file, demanded, &success, success) diff --git a/compiler_tests.odin b/compiler_tests.odin index 9854785..66c0542 100644 --- a/compiler_tests.odin +++ b/compiler_tests.odin @@ -1307,6 +1307,42 @@ main func() void { testing.expect_value(t, len(diagnostics.items), 0) } +@(test) +catch_fallback_preserves_fallible_success_type :: proc(t: ^testing.T) { + text := `Read_Error :: enum { + failed +} +read func(value []u8, fail bool) []u8 ! Read_Error { + if fail { + return .failed + } + return value +} +take_slice func(value []u8) void { _ = value } +main func() void { + expression :: read("ok", false) catch "fallback" + block :: read("ok", true) catch { + yield "fallback" + } + take_slice(expression) + take_slice(block) +} +` + 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) + 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) + + testing.expect_value(t, len(diagnostics.items), 0) +} + @(test) pipeline_emits_specialized_calling_conventions_and_checked_add :: proc(t: ^testing.T) { text := `sum_c c_func(a, b int) int {