From 91aa601464ebfb7e21cd1c27742d31e499f095cc Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Sat, 1 Aug 2026 23:33:52 +0200 Subject: [PATCH] fix(checker): infer return match calls --- compiler/checker/checker.odin | 4 ++++ compiler_tests.odin | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/compiler/checker/checker.odin b/compiler/checker/checker.odin index 091cf78..36fb3df 100644 --- a/compiler/checker/checker.odin +++ b/compiler/checker/checker.odin @@ -5977,6 +5977,10 @@ infer_statements :: proc( _ = infer_expr(checker, statement.expr, locals^[:], pkg, file, demanded, local_types) } case .Return: + if statement.value_control_flow { + infer_statements(checker, statement.body, locals, local_types, pkg, file, demanded, result, result_hint) + continue + } if statement.expr != ast.INVALID_EXPR { returned := infer_expr(checker, statement.expr, locals^[:], pkg, file, demanded, local_types, result_hint) if is_runtime_type(checker, result_hint) { diff --git a/compiler_tests.odin b/compiler_tests.odin index 03cae82..8562a99 100644 --- a/compiler_tests.odin +++ b/compiler_tests.odin @@ -6367,6 +6367,41 @@ main func() i32 { testing.expect(t, len(hir_module.functions) > 1) } +@(test) +return_match_inference_visits_arm_calls :: proc(t: ^testing.T) { + text := `Kind :: enum { + a + b +} +identity func(value i32) i32 { + return value +} +choose func(kind Kind) i32 { + return match kind { + .a: identity(41) + .b: identity(42) + } +} +main func() i32 { + return choose(.a) - 41 +} +` + source_file := source.Source{path="return_match_call.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) + testing.expect(t, len(hir_module.functions) > 2) +} + @(test) fallible_ergonomics_rejects_bad_try_and_catch_blocks :: proc(t: ^testing.T) { text := `A :: enum {