From 6bc4b69ab80f9451236362751a3213dcfb2e805a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 2 Oct 2026 13:03:48 +0100 Subject: [PATCH] Fix #7316: a polymorphic procedure in a constant compound literal is its instance, not nil --- src/check_expr.cpp | 2 +- tests/issues/run.bat | 1 + tests/issues/run.sh | 1 + tests/issues/test_issue_7316.odin | 47 +++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/issues/test_issue_7316.odin diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 50b59f0c1..3556017ca 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1006,7 +1006,7 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand PolyProcData poly_proc_data = {}; if (check_polymorphic_procedure_assignment(c, operand, type, operand->expr, &poly_proc_data)) { Entity *e = poly_proc_data.gen_entity; - add_type_and_value(c, operand->expr, Addressing_Value, e->type, {}); + add_type_and_value(c, operand->expr, Addressing_Value, e->type, exact_value_procedure(operand->expr)); Ast *expr = unparen_expr(operand->expr); if (expr->kind == Ast_SelectorExpr) { add_entity_use(c, expr->SelectorExpr.selector, e); diff --git a/tests/issues/run.bat b/tests/issues/run.bat index 28fee09f4..f54c28eaf 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -78,6 +78,7 @@ clang -c ..\test_issue_sysv_abi.c -o test_issue_sysv_abi_c.o || exit /b ..\..\..\odin run ..\test_issue_7482.odin %COMMON% || exit /b ..\..\..\odin run ..\test_issue_7562.odin %COMMON% -no-crt -no-thread-local || exit /b ..\..\..\odin run ..\test_issue_7562.odin %COMMON% -no-crt -no-thread-local -o:speed || exit /b +..\..\..\odin test ..\test_issue_7316.odin %COMMON% || exit /b ..\..\..\odin test ..\test_issue_7566.odin %COMMON% || exit /b ..\..\..\odin test ..\test_issue_7587.odin %COMMON% || exit /b ..\..\..\odin run ..\test_issue_7596.odin %COMMON% || exit /b diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 209d2923d..15d208d9a 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -101,6 +101,7 @@ $ODIN check ../test_issue_7012.odin -no-entry-point $COMMON_CHECK $ODIN build ../test_issue_7037.odin $COMMON -o:none $ODIN run ../test_issue_7482.odin $COMMON $ODIN run ../test_issue_7564.odin $COMMON +$ODIN test ../test_issue_7316.odin $COMMON $ODIN test ../test_issue_7566.odin $COMMON $ODIN test ../test_issue_7587.odin $COMMON $ODIN run ../test_issue_7596.odin $COMMON diff --git a/tests/issues/test_issue_7316.odin b/tests/issues/test_issue_7316.odin new file mode 100644 index 000000000..7f0edd503 --- /dev/null +++ b/tests/issues/test_issue_7316.odin @@ -0,0 +1,47 @@ +// Tests issue #7316 https://github.com/odin-lang/Odin/issues/7316 +// A polymorphic procedure in a constant compound literal is its instance, not nil +package test_issues + +import "core:testing" + +Foo :: struct($N: int) { + data: [N]u8, + number: int, + update: proc(f: ^Foo(N), delta: int), + get: proc(f: Foo(N)) -> int, +} + +foo_update :: proc(f: ^Foo($N), delta: int) { f.number += delta } +foo_get :: proc(f: Foo($N)) -> int { return f.number } + +foo_init :: proc(f: ^Foo($N)) { + f^ = { + number = 333, + update = foo_update, + get = foo_get, + } +} + +identity :: proc(x: $T) -> T { return x } + +global_foo := Foo(4){number = 1, update = foo_update, get = foo_get} +global_procs := [2]proc(int) -> int{identity, identity} + +@(test) +test_issue_7316 :: proc(t: ^testing.T) { + f: Foo(10) + foo_init(&f) + testing.expect(t, f.update != nil) + testing.expect(t, f.get != nil) + f.update(&f, 5) + testing.expect_value(t, f.get(f), 338) + + g := Foo(10){number = 1, update = foo_update} + testing.expect(t, g.update != nil) + + procs := [2]proc(int) -> int{identity, identity} + testing.expect_value(t, procs[1](7), 7) + + testing.expect(t, global_foo.update != nil) + testing.expect_value(t, global_procs[0](9), 9) +}