From 31b15c775e0b6aaee7c478b2e2d74e7cfa6ddea1 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 14 Aug 2025 20:27:23 +0200 Subject: [PATCH] Slicing a constant array with designated initialization would not update the indexes. --- releasenotes.md | 1 + src/compiler/sema_expr.c | 6 ++ ...lice_const_struct_with_designated_init.c3t | 68 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 test/test_suite/arrays/slice_const_struct_with_designated_init.c3t diff --git a/releasenotes.md b/releasenotes.md index 8c54b9cc2..99bd75d15 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -35,6 +35,7 @@ - Implement `a5hash` in the compiler for compile-time `$$str_hash` to match `String.hash()`. - Functions being tested for overload are now always checked before test. - Compile time indexing at compile time in a $typeof was no considered compile time. +- Slicing a constant array with designated initialization would not update the indexes. ### Stdlib changes - Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index b885f1608..6b3516ceb 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -4316,6 +4316,7 @@ static inline bool sema_slice_initializer(SemaContext *context, Expr *expr, Expr elements--; i--; } + element->init_array_value.index -= range->start_index; } if (vec_size(initializer->init_array.elements) == 0) { @@ -11789,10 +11790,15 @@ TokenType sema_splitpathref(const char *string, ArraySize len, Path **path_ref, } } + +/* + * Rewrite an expression into an expression call. + */ bool sema_insert_method_call(SemaContext *context, Expr *method_call, Decl *method_decl, Expr *parent, Expr **arguments, bool reverse_overload) { SourceSpan original_span = method_call->span; Expr *resolve = method_call; + // In this case we need to resolve the second argument first. if (reverse_overload) { if (!expr_is_const(parent)) diff --git a/test/test_suite/arrays/slice_const_struct_with_designated_init.c3t b/test/test_suite/arrays/slice_const_struct_with_designated_init.c3t new file mode 100644 index 000000000..155a50d8d --- /dev/null +++ b/test/test_suite/arrays/slice_const_struct_with_designated_init.c3t @@ -0,0 +1,68 @@ +// #target: macos-x64 +module test; + +enum Aboba: char +{ + FOO, + BAR, + BAZ, +} + +macro abobize($aboba_str) +{ + Aboba[$aboba_str.len] $abobas; + + $for var $i = 0; $i < $abobas.len; $i++: + char $symbol = $aboba_str[$i]; + $switch $symbol: + $case 'f': + $abobas[$i] = FOO; + $case 'r': + $abobas[$i] = BAR; + $case 'z': + $abobas[$i] = BAZ; + $default: + $error @sprintf("Unexpected symbol in lexical analysis: %s", $symbol); + $endswitch + $endfor + + return $abobas; +} + +fn int main(String[] args) +{ + do_aboba(); + return 0; +} + +macro do_aboba() +{ + var $a = abobize("zfrzfr")[2..]; + Aboba[] x = $a; + Aboba y = $a[0]; + assert(y == BAR); +} + +/* #expect: test.ll + +@.__const = private unnamed_addr constant [4 x i8] c"\01\02\00\01", align 1 + +define i32 @test.main(ptr %0, i64 %1) #0 { +entry: + %args = alloca %"char[][]", align 8 + %x = alloca %"char[]", align 8 + %literal = alloca [4 x i8], align 1 + %y = alloca i8, align 1 + store ptr %0, ptr %args, align 8 + %ptradd = getelementptr inbounds i8, ptr %args, i64 8 + store i64 %1, ptr %ptradd, align 8 + call void @llvm.memcpy.p0.p0.i32(ptr align 1 %literal, ptr align 1 @.__const, i32 4, i1 false) + %2 = insertvalue %"char[]" undef, ptr %literal, 0 + %3 = insertvalue %"char[]" %2, i64 4, 1 + store %"char[]" %3, ptr %x, align 8 + store i8 1, ptr %y, align 1 + %4 = load i8, ptr %y, align 1 + %eq = icmp eq i8 %4, 1 + call void @llvm.assume(i1 %eq) + ret i32 0 +}