diff --git a/releasenotes.md b/releasenotes.md index 87a2b8443..f058398fd 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -13,6 +13,7 @@ - `Bytebuffer.grow` was broken #2622. - Hex escapes like `"\x80"` would be incorrectly lowered. #2623 - Ignore const null check on deref in `$defined` and `$sizeof` #2633. +- Subscripting of constant slices would sometimes be considered non-constant #2635. ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 46358a21e..ea625c115 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -12321,8 +12321,8 @@ bool sema_cast_const(Expr *expr) if (!expr_is_const(exprptr(expr->subscript_expr.index.expr))) return false; Expr *parent = exprptr(expr->subscript_expr.expr); Type *flat_type = type_flatten(parent->type); - if (!type_is_any_arraylike(flat_type) || flat_type->type_kind == TYPE_UNTYPED_LIST) return false; if (!sema_cast_const(parent)) return false; + if (flat_type->type_kind != TYPE_SLICE && !type_is_any_arraylike(flat_type) && flat_type->type_kind != TYPE_UNTYPED_LIST) return false; return sema_expr_fold_to_index(expr, parent, expr->subscript_expr.index); } case EXPR_IDENTIFIER: diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 2a141d065..1952bea29 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -3037,10 +3037,9 @@ bool sema_analyse_ct_echo_stmt(SemaContext *context, Ast *statement) { Expr *message = statement->expr_stmt; if (!sema_analyse_expr_rvalue(context, message)) return false; - if (message->expr_kind != EXPR_CONST) + if (!sema_cast_const(message)) { - SEMA_ERROR(message, "Expected a constant value."); - return false; + RETURN_SEMA_ERROR(message, "Expected a constant value."); } const char *prefix = compiler.build.echo_prefix ? compiler.build.echo_prefix : "c3c:"; while (prefix[0] != 0) diff --git a/test/test_suite/struct/struct_slice_access.c3t b/test/test_suite/struct/struct_slice_access.c3t new file mode 100644 index 000000000..4cca7a784 --- /dev/null +++ b/test/test_suite/struct/struct_slice_access.c3t @@ -0,0 +1,24 @@ +module test; +import std; + +struct OfStruct +{ + int type; +} + +struct IContainAnArrayOfStructs +{ + OfStruct[] array; +} + +macro reproduce(OfStruct[] $self) +{ + var a = $self; + var b = $self[0]; +} + +fn int main(String[] args) +{ + reproduce({{1},{2},{3}}); + return 0; +} \ No newline at end of file