From 883052a6bbd49d15401d1d5f4a2559f4bd9327e3 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Wed, 22 Oct 2025 23:48:32 +0200 Subject: [PATCH] Improved generic inference in initializers #2541. --- releasenotes.md | 1 + src/compiler/sema_expr.c | 18 +++++++++++++++--- test/test_suite/generic/generic_inference.c3 | 13 +++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 test/test_suite/generic/generic_inference.c3 diff --git a/releasenotes.md b/releasenotes.md index 489b6ca0a..6b1059d13 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -10,6 +10,7 @@ - Allow `..` ranges to use "a..a-1" in order to express zero length. - Disallow aliasing of `@local` symbols with a higher visibility in the alias. - Add `--max-macro-iterations` to set macro iteration limit. +- Improved generic inference in initializers #2541. ### Fixes - Bug in `io::write_using_write_byte`. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index ba3b12604..868f950dc 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -7427,12 +7427,12 @@ static bool sema_binary_arithmetic_promotion(SemaContext *context, Expr *left, E right_type = type_no_optional(right->type)->canonical; if (type_is_pointer_like(left_type)) { - *operator_overload_ref = OVERLOAD_NONE; + *operator_overload_ref = OVERLOAD_NONE; // NOLINT return sema_expr_analyse_ptr_add(context, parent, left, right, left_type, right_type, cast_to_iptr, failed_ref); } if (type_is_pointer_like(right_type)) { - *operator_overload_ref = OVERLOAD_NONE; + *operator_overload_ref = OVERLOAD_NONE; // NOLINT return sema_expr_analyse_ptr_add(context, parent, right, left, right_type, left_type, cast_to_iptr, failed_ref); } } @@ -11597,7 +11597,19 @@ bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allo } else { - if (!sema_analyse_inferred_expr(context, to, expr, no_match_ref)) return false; + Module *generic; + if (to && (generic = type_find_generic(to)) != NULL) + { + Module *generic_module = context->generic.infer; + context->generic.infer = generic; + bool success = sema_analyse_inferred_expr(context, to, expr, no_match_ref); + context->generic.infer = generic_module; + if (!success) return false; + } + else + { + if (!sema_analyse_inferred_expr(context, to, expr, no_match_ref)) return false; + } } if (!sema_cast_rvalue(context, expr, true)) return false; if (to) to = type_no_optional(to); diff --git a/test/test_suite/generic/generic_inference.c3 b/test/test_suite/generic/generic_inference.c3 new file mode 100644 index 000000000..bb9489cc8 --- /dev/null +++ b/test/test_suite/generic/generic_inference.c3 @@ -0,0 +1,13 @@ +import std::collections::linkedlist; +struct Foo +{ + LinkedList {int} x; +} + +fn int main(String[] args) +{ + Foo f; + f.x = linkedlist::@new(tmem); + Foo f1 = { .x = linkedlist::@new(tmem) }; + return 0; +} \ No newline at end of file