diff --git a/lib/std/core/allocators/arena_allocator.c3 b/lib/std/core/allocators/arena_allocator.c3 index fac0229d9..f96be7373 100644 --- a/lib/std/core/allocators/arena_allocator.c3 +++ b/lib/std/core/allocators/arena_allocator.c3 @@ -60,7 +60,7 @@ private fn void*! arena_allocator_function(Allocator* data, usize size, usize al * @require alignment <= MAX_MEMORY_ALIGNMENT `alignment too big` * @require offset <= MAX_MEMORY_ALIGNMENT `offset too big` * @require offset <= size && offset >= 0 - * @require mem::aligned_offset(offset, $alignof(ArenaAllocatorHeader)) == offset + * @require mem::aligned_offset(offset, ArenaAllocatorHeader.alignof) == offset * @require this != null **/ private fn void*! ArenaAllocator._alloc(ArenaAllocator* this, usize size, usize alignment, usize offset) @@ -86,7 +86,7 @@ private fn void*! ArenaAllocator._alloc(ArenaAllocator* this, usize size, usize * @require alignment <= MAX_MEMORY_ALIGNMENT `alignment too big` * @require offset <= MAX_MEMORY_ALIGNMENT `offset too big` * @require offset <= size && offset >= 0 - * @require mem::aligned_offset(offset, $alignof(ArenaAllocatorHeader)) == offset + * @require mem::aligned_offset(offset, ArenaAllocatorHeader.alignof) == offset * @require this != null **/ private fn void*! ArenaAllocator._realloc(ArenaAllocator* this, void *old_pointer, usize size, usize alignment, usize offset) diff --git a/lib/std/core/allocators/temp_allocator.c3 b/lib/std/core/allocators/temp_allocator.c3 index 560ff2927..cd5edfcc8 100644 --- a/lib/std/core/allocators/temp_allocator.c3 +++ b/lib/std/core/allocators/temp_allocator.c3 @@ -176,9 +176,9 @@ private fn void*! TempAllocator._alloc(TempAllocator* this, usize size, usize al { void* start_mem = &this.data; void* starting_ptr = start_mem + this.used; - void* aligned_header_start = mem::aligned_pointer(starting_ptr, $alignof(TempAllocatorChunk)); + void* aligned_header_start = mem::aligned_pointer(starting_ptr, TempAllocatorChunk.alignof); void* mem = aligned_header_start + TempAllocatorChunk.sizeof; - if (alignment > $alignof(TempAllocatorChunk)) + if (alignment > TempAllocatorChunk.alignof) { mem = mem::aligned_pointer(mem + offset, alignment) - offset; } @@ -222,7 +222,7 @@ private fn void*! TempAllocator._alloc(TempAllocator* this, usize size, usize al // Find the page. page = alloc + padded_header_size - TempAllocatorPage.sizeof; - assert(mem::ptr_is_aligned(page, $alignof(TempAllocator))); + assert(mem::ptr_is_aligned(page, TempAllocator.alignof)); assert(mem::ptr_is_aligned(&page.data[0], DEFAULT_MEM_ALIGNMENT)); page.start = alloc; page.size = size; diff --git a/lib/std/core/array.c3 b/lib/std/core/array.c3 index d4bbb402a..4ccf1380d 100644 --- a/lib/std/core/array.c3 +++ b/lib/std/core/array.c3 @@ -6,11 +6,11 @@ macro tconcat(arr1, arr2) $Type[] result = array::talloc($Type, arr1.len + arr2.len); if (arr1.len > 0) { - mem::copy(result.ptr, &arr1[0], arr1.len * $Type.sizeof, $alignof($Type), $alignof($Type)); + mem::copy(result.ptr, &arr1[0], arr1.len * $Type.sizeof, $Type.alignof, $Type.alignof); } if (arr2.len > 0) { - mem::copy(&result[arr1.len], &arr2[0], arr2.len * $Type.sizeof, $alignof($Type), $alignof($Type)); + mem::copy(&result[arr1.len], &arr2[0], arr2.len * $Type.sizeof, $Type.alignof, $Type.alignof); } return result; } @@ -21,11 +21,11 @@ macro concat(arr1, arr2) $Type[] result = array::alloc($Type, arr1.len + arr2.len); if (arr1.len > 0) { - mem::copy(result.ptr, &arr1[0], arr1.len * $Type.sizeof, $alignof($Type), $alignof($Type)); + mem::copy(result.ptr, &arr1[0], arr1.len * $Type.sizeof, $Type.alignof, $Type.alignof); } if (arr2.len > 0) { - mem::copy(&result[arr1.len], &arr2[0], arr2.len * $Type.sizeof, $alignof($Type), $alignof($Type)); + mem::copy(&result[arr1.len], &arr2[0], arr2.len * $Type.sizeof, $Type.alignof, $Type.alignof); } return result; } \ No newline at end of file diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 3b6f725bb..a603813cc 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -98,7 +98,7 @@ macro bitcast(expr, $Type) @builtin var $size = (usize)($sizeof(expr)); $assert($size == $Type.sizeof, "Cannot bitcast between types of different size."); $Type x = void; - mem::copy(&x, &expr, $size, $alignof($Type), $alignof(expr)); + mem::copy(&x, &expr, $size, $Type.alignof, $alignof(expr)); return x; } diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index f07f2b08f..c1af2d4a7 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -60,7 +60,7 @@ macro void clear(void* dst, usize len, usize $dst_align = 0, bool $is_volatile = macro bool equals(a, b, isize len = -1, usize $align = 0) { $if (!$align): - $align = $alignof($typeof(a[0])); + $align = $typeof(a[0]).alignof; $endif; void* x = void; void* y = void; @@ -214,7 +214,7 @@ macro void @tscoped(;@body()) macro talloc($Type) @builtin { - return temp_allocator().alloc_aligned($Type.sizeof, $alignof($Type))!!; + return temp_allocator().alloc_aligned($Type.sizeof, $Type.alignof)!!; } fn void* tmalloc(usize size, usize alignment = allocator::DEFAULT_MEM_ALIGNMENT) @builtin @inline diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index c0f76b035..c52e173e1 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -1,9 +1,9 @@ module std::core::mem::allocator; const MAX_MEMORY_ALIGNMENT = 0x1000_0000; -const DEFAULT_MEM_ALIGNMENT = $alignof(void*) * 2; +const DEFAULT_MEM_ALIGNMENT = (void*.alignof) * 2; const DEFAULT_SIZE_PREFIX = usize.sizeof; -const DEFAULT_SIZE_PREFIX_ALIGNMENT = $alignof(usize); +const DEFAULT_SIZE_PREFIX_ALIGNMENT = usize.alignof; const Allocator* NULL_ALLOCATOR = &_NULL_ALLOCATOR; const Allocator* LIBC_ALLOCATOR = &_SYSTEM_ALLOCATOR; diff --git a/lib/std/core/mem_array.c3 b/lib/std/core/mem_array.c3 index 139a070f4..61db68f13 100644 --- a/lib/std/core/mem_array.c3 +++ b/lib/std/core/mem_array.c3 @@ -17,7 +17,7 @@ macro alloc($Type, usize elements) **/ macro talloc($Type, usize elements) { - $Type* ptr = tmalloc($Type.sizeof * elements, $alignof($Type[1])); + $Type* ptr = tmalloc($Type.sizeof * elements, $Type[1].alignof); return ptr[:elements]; } @@ -35,6 +35,6 @@ macro make($Type, usize elements, Allocator* allocator = mem::current_allocator( **/ macro tmake($Type, usize elements) { - $Type* ptr = tcalloc($Type.sizeof * elements, $alignof($Type[1])); + $Type* ptr = tcalloc($Type.sizeof * elements, $Type[1].alignof); return ptr[:elements]; } diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 3258e87fc..8c1805ceb 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2506,12 +2506,14 @@ INLINE bool type_is_float(Type *type) return kind >= TYPE_FLOAT_FIRST && kind <= TYPE_FLOAT_LAST; } -INLINE bool type_is_invalid_for_typeof(Type *type) +INLINE bool type_is_invalid_storage_type(Type *type) { + if (!type) return false; switch (type->type_kind) { case TYPE_MEMBER: case TYPE_UNTYPED_LIST: + case TYPE_TYPEINFO: return true; default: return false; diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index a6f4da3f2..5adc4e33f 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -2387,6 +2387,11 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local) return false; } decl->type = init_expr->type; + if (type_is_invalid_storage_type(init_expr->type)) + { + SEMA_ERROR(init_expr, "A value of type '%s' cannot be used as a constant.", type_quoted_error_string(init_expr->type)); + return false; + } if (!decl->alignment) decl->alignment = type_alloca_alignment(decl->type); if (!sema_analyse_decl_type(context, decl->type, init_expr->span)) return false; // Skip further evaluation. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index a076824de..465512891 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -92,7 +92,7 @@ static inline bool sema_expr_analyse_taddr(SemaContext *context, Expr *expr); // -- ct_call static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr); -static inline bool sema_expr_analyse_ct_sizeof(SemaContext *context, Expr *expr); + static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr); static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr); @@ -150,8 +150,7 @@ static inline IndexDiff range_const_len(Range *range); static inline bool sema_expr_begin_analyse(Expr *expr); static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr); -static bool sema_expr_analyse_type_var_path(SemaContext *context, Expr *expr, ExprFlatElement **elements, Type **type_ref, - Decl **decl_ref); +static Decl *sema_expr_analyse_var_path(SemaContext *context, Expr *expr, ExprFlatElement **elements); static inline bool sema_expr_analyse_flat_element(SemaContext *context, ExprFlatElement *element, Type *type, Decl **member_ref, ArraySize *index_ref, Type **return_type, unsigned i, SourceSpan loc, bool *is_missing); static Expr *sema_expr_resolve_access_child(SemaContext *context, Expr *child, bool *missing); @@ -176,9 +175,9 @@ static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Type *type); static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment, AlignSize offset); - void expr_insert_widening_type(Expr *expr, Type *infer_type); static Expr *expr_access_inline_member(Expr *parent, Decl *parent_decl); +static inline int64_t expr_get_index_max(Expr *expr); static inline bool expr_both_any_integer_or_integer_vector(Expr *left, Expr *right); static inline bool expr_both_const(Expr *left, Expr *right); static inline bool sema_identifier_find_possible_inferred(Type *to, Expr *expr); @@ -1350,9 +1349,9 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call if (!sema_expr_check_assign(context, arg)) return false; *failable |= IS_OPTIONAL(arg); if (!sema_call_check_inout_param_match(context, param, arg)) return false; - if (arg->type == type_untypedlist) + if (type_is_invalid_storage_type(type)) { - SEMA_ERROR(arg, "An untyped list cannot be passed by reference."); + SEMA_ERROR(arg, "A value of type %s cannot be passed by reference.", type_quoted_error_string(type)); return false; } if (type && type->canonical != arg->type->canonical) @@ -1376,9 +1375,9 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call // foo if (!sema_analyse_expr_rhs(context, type, arg, true)) return false; if (IS_OPTIONAL(arg)) *failable = true; - if (arg->type == type_untypedlist) + if (type_is_invalid_storage_type(arg->type)) { - SEMA_ERROR(arg, "An untyped list can only be passed as a compile time parameter."); + SEMA_ERROR(arg, "A value of type %s can only be passed as a compile time parameter.", type_quoted_error_string(arg->type)); return false; } if (!param->alignment) @@ -2148,11 +2147,11 @@ static bool sema_slice_index_is_in_range(SemaContext *context, Type *type, Expr case TYPE_FLEXIBLE_ARRAY: assert(!from_end); return true; + case TYPE_UNTYPED_LIST: case TYPE_ARRAY: case TYPE_VECTOR: { MemberIndex len = (MemberIndex)type->array.len; - bool is_vector = type->type_kind == TYPE_VECTOR; if (from_end) { idx = len - idx; @@ -2162,22 +2161,17 @@ static bool sema_slice_index_is_in_range(SemaContext *context, Type *type, Expr // Checking end can only be done for arrays. if (end_index && idx >= len) { - SEMA_ERROR(index_expr, - is_vector ? "End index out of bounds, was %lld, exceeding vector width %lld." - : "Array end index out of bounds, was %lld, exceeding array length %lld.", - (long long)idx, (long long)len); + SEMA_ERROR(index_expr, "End index out of bounds, was %lld, exceeding %lld.", (long long)idx, (long long)len); return false; } if (!end_index && idx >= len) { if (len == 0) { - SEMA_ERROR(index_expr, "Cannot index into a zero size array."); + SEMA_ERROR(index_expr, "Cannot index into a zero size list."); return false; } - SEMA_ERROR(index_expr, - is_vector ? "Index out of bounds, was %lld, exceeding max vector width %lld." - : "Array index out of bounds, was %lld, exceeding max array index %lld.", (long long)idx, (long long)len - 1); + SEMA_ERROR(index_expr, "Index out of bounds, was %lld, exceeding maximum (%lld).", (long long)idx, (long long)len - 1); return false; } break; @@ -2199,7 +2193,7 @@ static bool sema_slice_index_is_in_range(SemaContext *context, Type *type, Expr } if (idx < 0) { - SEMA_ERROR(index_expr, "Array index out of bounds, using a negative array index is only allowed with pointers."); + SEMA_ERROR(index_expr, "Index out of bounds, using a negative index is only allowed for pointers."); return false; } return true; @@ -2303,7 +2297,8 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr, int64_t index_value = -1; bool start_from_end = expr->subscript_expr.range.start_from_end; - if (expr_is_const_int(index) && (current_type->type_kind == TYPE_ARRAY || current_type == type_untypedlist)) + int64_t size; + if (expr_is_const_int(index) && (size = expr_get_index_max(subscripted)) >= 0) { // 4c. And that it's in range. if (int_is_neg(index->const_expr.ixx)) @@ -2311,8 +2306,6 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr, SEMA_ERROR(index, "The index may not be negative."); return false; } - int64_t size = current_type == type_untypedlist ? vec_size(subscripted->const_expr.untyped_list) : current_type->array.len; - assert(size >= 0 && "Unexpected overflow"); if (!int_fits(index->const_expr.ixx, TYPE_I64) || size == 0) { SEMA_ERROR(index, "The index is out of range.", size); @@ -2368,7 +2361,6 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr, expr_replace(expr, current_expr->const_expr.untyped_list[index_value]); return true; } - if (!sema_cast_rvalue(context, subscripted)) return false; Decl *overload = NULL; @@ -3309,11 +3301,7 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, expr_rewrite_const_int(expr, type_usize, type_abi_alignment(type), true); return true; case TYPE_PROPERTY_EXTNAMEOF: - if (type_is_builtin(type->type_kind)) - { - SEMA_ERROR(expr, "'extnameof' cannot be used on builtin types."); - return false; - } + if (type_is_builtin(type->type_kind)) return false; sema_expr_rewrite_to_type_nameof(expr, type, TOKEN_CT_EXTNAMEOF); return true; case TYPE_PROPERTY_NONE: @@ -5936,13 +5924,11 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * -static bool sema_expr_analyse_type_var_path(SemaContext *context, Expr *expr, ExprFlatElement **elements, Type **type_ref, - Decl **decl_ref) +static Decl *sema_expr_analyse_var_path(SemaContext *context, Expr *expr, ExprFlatElement **elements) { - if (!sema_analyse_expr_lvalue_fold_const(context, expr)) return false; + if (!sema_analyse_expr_lvalue_fold_const(context, expr)) return NULL; Expr *current = expr; Decl *decl = NULL; - Type *type = NULL; RETRY: switch (current->expr_kind) { @@ -5952,21 +5938,12 @@ RETRY: case EXPR_IDENTIFIER: decl = current->identifier_expr.decl; break; - case EXPR_TYPEINFO: - type = current->type_expr->type; - break; default: - SEMA_ERROR(expr, "A type or a variable was expected here."); - return false; + SEMA_ERROR(expr, "A variable was expected here."); + return NULL; } - if (decl) - { - if (!sema_analyse_decl(context, decl)) return false; - type = decl->type; - } - *decl_ref = decl; - *type_ref = type; - return true; + if (!sema_analyse_decl(context, decl)) return NULL; + return decl; } static inline bool sema_expr_analyse_flat_element(SemaContext *context, ExprFlatElement *element, Type *type, Decl **member_ref, ArraySize *index_ref, Type **return_type, unsigned i, SourceSpan loc, @@ -6096,12 +6073,15 @@ static inline bool sema_expr_analyse_flat_element(SemaContext *context, ExprFlat static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr) { Expr *main_var = expr->ct_call_expr.main_var; - Type *type = NULL; - Decl *decl = NULL; ExprFlatElement *path = expr->ct_call_expr.flat_path; - - if (!sema_expr_analyse_type_var_path(context, main_var, &path, &type, &decl)) return false; - + Decl *decl = sema_expr_analyse_var_path(context, main_var, &path); + if (!decl) return false; + Type *type = decl->type; + if (type_is_invalid_storage_type(type)) + { + SEMA_ERROR(main_var, "Cannot use '$alignof' on type %s.", type_quoted_error_string(type)); + return false; + } AlignSize align = decl && !decl_is_user_defined_type(decl) ? decl->alignment : type_abi_alignment(type); VECEACH(path, i) { @@ -6123,31 +6103,6 @@ static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr } expr_rewrite_const_int(expr, type_isize, align, true); - - return true; -} - -static inline bool sema_expr_analyse_ct_sizeof(SemaContext *context, Expr *expr) -{ - Expr *main_var = expr->ct_call_expr.main_var; - Type *type = NULL; - Decl *decl = NULL; - ExprFlatElement *path = expr->ct_call_expr.flat_path; - if (!sema_expr_analyse_type_var_path(context, main_var, &path, &type, &decl)) return false; - - if (!type) return false; - - VECEACH(path, i) - { - ExprFlatElement *element = &path[i]; - Decl *member; - ArraySize index; - Type *result_type; - if (!sema_expr_analyse_flat_element(context, element, type, &member, &index, &result_type, i, i == 0 ? main_var->span : expr->span, NULL)) return false; - type = result_type; - } - - expr_rewrite_const_int(expr, type_isize, type_size(type), true); return true; } @@ -6179,10 +6134,10 @@ static inline void sema_expr_rewrite_to_type_nameof(Expr *expr, Type *type, Toke static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr) { Expr *main_var = expr->ct_call_expr.main_var; - Type *type = NULL; - Decl *decl = NULL; ExprFlatElement *path = expr->ct_call_expr.flat_path; - if (!sema_expr_analyse_type_var_path(context, main_var, &path, &type, &decl)) return false; + Decl *decl = sema_expr_analyse_var_path(context, main_var, &path); + if (!decl) return false; + Type *type = decl->type; TokenType name_type = expr->ct_call_expr.token_type; @@ -6192,39 +6147,26 @@ static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr) return false; } - if (decl) + if (name_type == TOKEN_CT_EXTNAMEOF) { - if (name_type == TOKEN_CT_EXTNAMEOF) + if (!decl->extname) { - if (!decl->extname) - { - SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name); - return false; - } - expr_rewrite_to_string(expr, decl->extname); - return true; + SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name); + return false; } - if (!decl->unit || name_type == TOKEN_CT_NAMEOF || decl_is_local(decl)) - { - expr_rewrite_to_string(expr, decl->name); - return true; - } - scratch_buffer_clear(); - scratch_buffer_append(decl->unit->module->name->module); - scratch_buffer_append("::"); - scratch_buffer_append(decl->name); - expr_rewrite_to_string(expr, scratch_buffer_copy()); + expr_rewrite_to_string(expr, decl->extname); return true; } - - assert(type); - if (name_type == TOKEN_CT_EXTNAMEOF && !type_is_user_defined(type)) + if (!decl->unit || name_type == TOKEN_CT_NAMEOF || decl_is_local(decl)) { - SEMA_ERROR(main_var, "Only user defined types have an external name."); - return false; + expr_rewrite_to_string(expr, decl->name); + return true; } - - sema_expr_rewrite_to_type_nameof(expr, type, name_type); + scratch_buffer_clear(); + scratch_buffer_append(decl->unit->module->name->module); + scratch_buffer_append("::"); + scratch_buffer_append(decl->name); + expr_rewrite_to_string(expr, scratch_buffer_copy()); return true; } @@ -6587,10 +6529,9 @@ static inline bool sema_expr_analyse_ct_eval(SemaContext *context, Expr *expr) static inline bool sema_expr_analyse_ct_offsetof(SemaContext *context, Expr *expr) { Expr *main_var = expr->ct_call_expr.main_var; - Type *type = NULL; - Decl *decl = NULL; ExprFlatElement *path = expr->ct_call_expr.flat_path; - if (!sema_expr_analyse_type_var_path(context, main_var, &path, &type, &decl)) return false; + Decl *decl = sema_expr_analyse_var_path(context, main_var, &path); + if (!decl) return false; if (!vec_size(path)) { SEMA_ERROR(expr, "Expected a path to get the offset of."); @@ -6598,6 +6539,7 @@ static inline bool sema_expr_analyse_ct_offsetof(SemaContext *context, Expr *exp } ByteSize offset = 0; + Type *type = decl->type; VECEACH(path, i) { ExprFlatElement *element = &path[i]; @@ -6627,8 +6569,6 @@ static inline bool sema_expr_analyse_ct_call(SemaContext *context, Expr *expr) { case TOKEN_CT_DEFINED: return sema_expr_analyse_ct_defined(context, expr); - case TOKEN_CT_SIZEOF: - return sema_expr_analyse_ct_sizeof(context, expr); case TOKEN_CT_ALIGNOF: return sema_expr_analyse_ct_alignof(context, expr); case TOKEN_CT_OFFSETOF: @@ -7005,6 +6945,36 @@ bool sema_analyse_expr_require_const(SemaContext *context, Expr *expr) return true; } +static inline int64_t expr_get_index_max(Expr *expr) +{ + if (expr_is_const_untyped_list(expr)) + { + return vec_size(expr->const_expr.untyped_list); + } + Type *type = expr->type; +RETRY: + switch (type->type_kind) + { + case TYPE_TYPEDEF: + type = type->canonical; + goto RETRY; + case TYPE_DISTINCT: + type = type->decl->distinct_decl.base_type; + goto RETRY; + case TYPE_UNTYPED_LIST: + UNREACHABLE + case TYPE_ARRAY: + case TYPE_VECTOR: + return type->array.len; + case TYPE_OPTIONAL: + type = type->failable; + goto RETRY; + default: + return -1; + } + UNREACHABLE +} + void expr_insert_widening_type(Expr *expr, Type *infer_type) { if (!infer_type) return; diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 168b551a4..a222aa1ba 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -308,9 +308,9 @@ bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool a SEMA_ERROR(expr, "Only type names may be resolved with $evaltype."); return type_info_poison(type_info); } - if (type_is_invalid_for_typeof(expr->type)) + if (type_is_invalid_storage_type(expr->type)) { - SEMA_ERROR(expr, "Compile-time expressions may not be used with $evaltype."); + SEMA_ERROR(expr, "Compile-time types may not be used with $evaltype."); return type_info_poison(type_info); } TypeInfo *inner_type = inner->type_expr; @@ -326,9 +326,9 @@ bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool a { return type_info_poison(type_info); } - if (type_is_invalid_for_typeof(expr->type)) + if (type_is_invalid_storage_type(expr->type)) { - SEMA_ERROR(expr, "Compile-time expressions are not allowed here."); + SEMA_ERROR(expr, "Expected a regular runtime expression here."); return false; } type_info->type = expr->type; diff --git a/src/version.h b/src/version.h index bd1496ea7..8fef5002d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.3.74" \ No newline at end of file +#define COMPILER_VERSION "0.3.75" \ No newline at end of file diff --git a/test/test_suite/compile_time/ct_memberof.c3t b/test/test_suite/compile_time/ct_memberof.c3t index efa42ac51..6e5277261 100644 --- a/test/test_suite/compile_time/ct_memberof.c3t +++ b/test/test_suite/compile_time/ct_memberof.c3t @@ -46,8 +46,8 @@ fn void test(int x) print_args($typeof(&test)); print_args($typeof(&hell)); print_args($typeof(&hello)); - io::println($nameof($typefrom($typeof(&test).returns))); - io::println($nameof($typefrom($typeof(&hell).returns))); + io::println($typeof(&test).returns.nameof); + io::println($typeof(&hell).returns.nameof); print_fields(Foo); print_fields(Bar); print_fields(Bark); diff --git a/test/test_suite/compile_time_introspection/alignof.c3t b/test/test_suite/compile_time_introspection/alignof.c3t index 12f3530e1..c3f585a55 100644 --- a/test/test_suite/compile_time_introspection/alignof.c3t +++ b/test/test_suite/compile_time_introspection/alignof.c3t @@ -36,55 +36,30 @@ union Foob } Ar izzy; - long x = $alignof(zfe); -short y = $alignof(Bob.y); -int z = $alignof(Bob.y); -int w = $alignof(Bob.y); +short y = Bob.y.alignof; +int z = Bob.w.z.alignof; int v = $alignof(v); -int x1 = $alignof(Ex.c); -int x2 = $alignof(Ex.y); -int x3 = $alignof(char[8]); -int x4 = $alignof(Ar.br[1]); -int x5 = $alignof(Ar.br[1]); -int x6 = $alignof(Ar.br[1]); -int x7 = $alignof(Ar.br[1]); -int x8 = $alignof(Ar.br[2]); +int x1 = Ex.c.alignof; +int x2 = Ex.y.alignof; +int x3 = char[8].alignof; int x9 = $alignof(izzy.br[1]); int x10 = $alignof(izzy.br[1]); int x11 = $alignof(izzy.br[1]); -int z0 = $alignof(Foob.c); -int z00 = $alignof(Foob.c[0]); -int z01 = $alignof(Foob.c[1]); -int z02 = $alignof(Foob.c[2]); -int z03 = $alignof(Foob.c[3]); -int z04 = $alignof(Foob.c[4]); -int z05 = $alignof(Foob.c[5]); +int z0 = Foob.c.alignof; -// #expect: foo.ll +/* #expect: foo.ll @foo_x = local_unnamed_addr global i64 16, align 8 @foo_y = local_unnamed_addr global i16 8, align 2 -@foo_z = local_unnamed_addr global i32 8, align 4 -@foo_w = local_unnamed_addr global i32 8, align 4 +@foo_z = local_unnamed_addr global i32 4, align 4 @foo_v = local_unnamed_addr global i32 4, align 4 @foo_x1 = local_unnamed_addr global i32 8, align 4 @foo_x2 = local_unnamed_addr global i32 8, align 4 @foo_x3 = local_unnamed_addr global i32 1, align 4 -@foo_x4 = local_unnamed_addr global i32 4, align 4 -@foo_x5 = local_unnamed_addr global i32 4, align 4 -@foo_x6 = local_unnamed_addr global i32 4, align 4 -@foo_x7 = local_unnamed_addr global i32 4, align 4 -@foo_x8 = local_unnamed_addr global i32 8, align 4 @foo_x9 = local_unnamed_addr global i32 4, align 4 @foo_x10 = local_unnamed_addr global i32 4, align 4 @foo_x11 = local_unnamed_addr global i32 4, align 4 @foo_z0 = local_unnamed_addr global i32 8, align 4 -@foo_z00 = local_unnamed_addr global i32 8, align 4 -@foo_z01 = local_unnamed_addr global i32 1, align 4 -@foo_z02 = local_unnamed_addr global i32 2, align 4 -@foo_z03 = local_unnamed_addr global i32 1, align 4 -@foo_z04 = local_unnamed_addr global i32 4, align 4 -@foo_z05 = local_unnamed_addr global i32 1, align 4 \ No newline at end of file diff --git a/test/test_suite/compile_time_introspection/nameof_err.c3 b/test/test_suite/compile_time_introspection/nameof_err.c3 index 764f6d41b..0de24c9ee 100644 --- a/test/test_suite/compile_time_introspection/nameof_err.c3 +++ b/test/test_suite/compile_time_introspection/nameof_err.c3 @@ -11,10 +11,10 @@ fn void main2() fn void main3() { - $extnameof($evaltype("int")); // #error: Only user defined types have an external name. + $evaltype("int").extnameof; // #error: 'int' does not have a property 'extnameof' } fn void main4() { - $extnameof($evaltype("foo::int")); // #error: Only valid types may be resolved with $evaltype. + $evaltype("foo::int").extnameof; // #error: Only valid types may be resolved with $evaltype. } diff --git a/test/test_suite/compile_time_introspection/offsetof.c3t b/test/test_suite/compile_time_introspection/offsetof.c3t index 7a31f7f53..915dbaa64 100644 --- a/test/test_suite/compile_time_introspection/offsetof.c3t +++ b/test/test_suite/compile_time_introspection/offsetof.c3t @@ -36,35 +36,15 @@ union Foob } -short y = $offsetof(Bob.y); -int z = $offsetof(Bob.y); -int w = $offsetof(Bob.y); -int x1 = $offsetof(Ex.c[3]); -int x2 = $offsetof(Ex.y[1]); -int x4 = $offsetof(Ar.br[1]); -int x6 = $offsetof(Ar.br[1].x); -int x5 = $offsetof(Ar.br[1]); -int x7 = $offsetof(Ar.br[2].x); -int x8 = $offsetof(Ar.br[2]); -int z0 = $offsetof(Foob.c); -int z00 = $offsetof(Foob.c[0]); -int z01 = $offsetof(Foob.c[1]); -int z02 = $offsetof(Foob.c[5]); -int z03 = $offsetof(Foob.a); +short y = Bob.y.offsetof; +int z = Bob.w.z.offsetof; +int w = Bob.w.offsetof; +int z0 = Foob.c.offsetof; +int z03 = Foob.a.offsetof; // #expect: foo.ll @foo_y = local_unnamed_addr global i16 16, align 2 -@foo_z = local_unnamed_addr global i32 16, align 4 -@foo_w = local_unnamed_addr global i32 16, align 4 -@foo_x1 = local_unnamed_addr global i32 3, align 4 -@foo_x2 = local_unnamed_addr global i32 4, align 4 -@foo_x4 = local_unnamed_addr global i32 16, align 4 -@foo_x6 = local_unnamed_addr global i32 20, align 4 -@foo_x5 = local_unnamed_addr global i32 16, align 4 -@foo_x7 = local_unnamed_addr global i32 28, align 4 -@foo_x8 = local_unnamed_addr global i32 24, align 4 +@foo_z = local_unnamed_addr global i32 116, align 4 +@foo_w = local_unnamed_addr global i32 116, align 4 @foo_z0 = local_unnamed_addr global i32 0, align 4 -@foo_z00 = local_unnamed_addr global i32 0, align 4 -@foo_z01 = local_unnamed_addr global i32 1, align 4 -@foo_z02 = local_unnamed_addr global i32 5, align 4 @foo_z03 = local_unnamed_addr global i32 0, align 4 diff --git a/test/test_suite/enumerations/compile_time.c3t b/test/test_suite/enumerations/compile_time.c3t index 1e7e7c21f..68c6f8db0 100644 --- a/test/test_suite/enumerations/compile_time.c3t +++ b/test/test_suite/enumerations/compile_time.c3t @@ -6,7 +6,7 @@ enum MyEnum : short } int myenum_elements = MyEnum.elements; -int myenum_alignof = $alignof(MyEnum); +int myenum_alignof = MyEnum.alignof; int myenum_sizeof = MyEnum.sizeof; // #expect: compile_time.ll diff --git a/test/test_suite/initializer_lists/initializers_to_macros.c3 b/test/test_suite/initializer_lists/initializers_to_macros.c3 index 9625d67bd..4b5a31f18 100644 --- a/test/test_suite/initializer_lists/initializers_to_macros.c3 +++ b/test/test_suite/initializer_lists/initializers_to_macros.c3 @@ -7,5 +7,5 @@ macro test(foo) fn void main() { test(int[] { 1, 2 }); - test({ 1, 2 }); // #error: An untyped list can only be passed as a compile time parameter. + test({ 1, 2 }); // #error: A value of type 'untyped_list' can only be passed as a compile time parameter. } \ No newline at end of file diff --git a/test/test_suite/macros/userland_bitcast.c3t b/test/test_suite/macros/userland_bitcast.c3t index f48a8f3ad..395790ca8 100644 --- a/test/test_suite/macros/userland_bitcast.c3t +++ b/test/test_suite/macros/userland_bitcast.c3t @@ -6,21 +6,21 @@ macro testbitcast(expr, $Type) $Type x = void; var $size = (usize)($sizeof(expr)); - $if ($alignof(expr) >= 8 && $alignof($Type) >= 8): + $if ($alignof(expr) >= 8 && $Type.alignof >= 8): ulong *b = (ulong*)(&expr); ulong *to = (ulong*)(&x); for (usize i = 0; i < $size; i += 8) { to[i] = b[i]; } - $elif ($alignof(expr) >= 4 && $alignof($Type) >= 4): + $elif ($alignof(expr) >= 4 && $Type.alignof >= 4): uint* b = (uint*)(&expr); uint* to = (uint*)(&x); for (usize i = 0; i < $size; i += 4) { to[i] = b[i]; } - $elif ($alignof(expr) >= 2 && $alignof($Type) >= 2): + $elif ($alignof(expr) >= 2 && $Type.alignof >= 2): ushort* b = (ushort*)(&expr); ushort* to = (ushort*)(&x); for (usize i = 0; i < $size; i += 2) diff --git a/test/test_suite/subarrays/slice_negative_len.c3 b/test/test_suite/subarrays/slice_negative_len.c3 index 3ce848262..e9e44f2f7 100644 --- a/test/test_suite/subarrays/slice_negative_len.c3 +++ b/test/test_suite/subarrays/slice_negative_len.c3 @@ -16,7 +16,7 @@ fn void test2() fn void test3() { int[3] x = { 1, 2, 3 }; - int[] z = x[..4]; // #error: Array end index out of bounds, was 4, exceeding array length 3. + int[] z = x[..4]; // #error: End index out of bounds, was 4, exceeding 3. } fn void test4() @@ -29,31 +29,31 @@ fn void test4() fn void test5() { int[3] x = { 1, 2, 3 }; - int[] z = x[..^4]; // #error: Array index out of bounds, using a negative array index is only allowed with pointers. + int[] z = x[..^4]; // #error: Index out of bounds, using a negative index is only allowed for pointers. } fn void test6() { int[3] x = { 1, 2, 3 }; - int[] z = x[3..]; // #error: Array index out of bounds, was 3, exceeding max array index 2. + int[] z = x[3..]; // #error: Index out of bounds, was 3, exceeding maximum (2). } fn void test7() { int[3] x = { 1, 2, 3 }; - int[] z = x[-1..]; // #error: Array index out of bounds, using a negative array index is only allowed with pointers. + int[] z = x[-1..]; // #error: Index out of bounds, using a negative index is only allowed for pointers. } fn void test8() { int[3] x = { 1, 2, 3 }; - int[] z = x[^4..]; // #error: Array index out of bounds, using a negative array index is only allowed with pointers. + int[] z = x[^4..]; // #error: Index out of bounds, using a negative index is only allowed for pointers. } fn void test9() { int[3] x = { 1, 2, 3 }; - int[] z = x[^0..]; // #error: Array index out of bounds, was 3, exceeding max array index 2. + int[] z = x[^0..]; // #error: Index out of bounds, was 3, exceeding maximum (2) } fn void test10() @@ -68,5 +68,5 @@ fn void test10() fn void test11() { int[3] x = { 1, 2, 3 }; - int[] z = x[..^0]; // #error: Array end index out of bounds, was 3, exceeding array length 3 + int[] z = x[..^0]; // #error: End index out of bounds, was 3, exceeding 3. } diff --git a/test/test_suite2/compile_time/ct_memberof.c3t b/test/test_suite2/compile_time/ct_memberof.c3t index 238ef4b29..5a5d51798 100644 --- a/test/test_suite2/compile_time/ct_memberof.c3t +++ b/test/test_suite2/compile_time/ct_memberof.c3t @@ -46,8 +46,8 @@ fn void test(int x) print_args($typeof(&test)); print_args($typeof(&hell)); print_args($typeof(&hello)); - io::println($nameof($typefrom($typeof(&test).returns))); - io::println($nameof($typefrom($typeof(&hell).returns))); + io::println($typeof(&test).returns.nameof); + io::println($typeof(&hell).returns.nameof); print_fields(Foo); print_fields(Bar); print_fields(Bark); diff --git a/test/test_suite2/compile_time_introspection/alignof.c3t b/test/test_suite2/compile_time_introspection/alignof.c3t index 12f3530e1..c3f585a55 100644 --- a/test/test_suite2/compile_time_introspection/alignof.c3t +++ b/test/test_suite2/compile_time_introspection/alignof.c3t @@ -36,55 +36,30 @@ union Foob } Ar izzy; - long x = $alignof(zfe); -short y = $alignof(Bob.y); -int z = $alignof(Bob.y); -int w = $alignof(Bob.y); +short y = Bob.y.alignof; +int z = Bob.w.z.alignof; int v = $alignof(v); -int x1 = $alignof(Ex.c); -int x2 = $alignof(Ex.y); -int x3 = $alignof(char[8]); -int x4 = $alignof(Ar.br[1]); -int x5 = $alignof(Ar.br[1]); -int x6 = $alignof(Ar.br[1]); -int x7 = $alignof(Ar.br[1]); -int x8 = $alignof(Ar.br[2]); +int x1 = Ex.c.alignof; +int x2 = Ex.y.alignof; +int x3 = char[8].alignof; int x9 = $alignof(izzy.br[1]); int x10 = $alignof(izzy.br[1]); int x11 = $alignof(izzy.br[1]); -int z0 = $alignof(Foob.c); -int z00 = $alignof(Foob.c[0]); -int z01 = $alignof(Foob.c[1]); -int z02 = $alignof(Foob.c[2]); -int z03 = $alignof(Foob.c[3]); -int z04 = $alignof(Foob.c[4]); -int z05 = $alignof(Foob.c[5]); +int z0 = Foob.c.alignof; -// #expect: foo.ll +/* #expect: foo.ll @foo_x = local_unnamed_addr global i64 16, align 8 @foo_y = local_unnamed_addr global i16 8, align 2 -@foo_z = local_unnamed_addr global i32 8, align 4 -@foo_w = local_unnamed_addr global i32 8, align 4 +@foo_z = local_unnamed_addr global i32 4, align 4 @foo_v = local_unnamed_addr global i32 4, align 4 @foo_x1 = local_unnamed_addr global i32 8, align 4 @foo_x2 = local_unnamed_addr global i32 8, align 4 @foo_x3 = local_unnamed_addr global i32 1, align 4 -@foo_x4 = local_unnamed_addr global i32 4, align 4 -@foo_x5 = local_unnamed_addr global i32 4, align 4 -@foo_x6 = local_unnamed_addr global i32 4, align 4 -@foo_x7 = local_unnamed_addr global i32 4, align 4 -@foo_x8 = local_unnamed_addr global i32 8, align 4 @foo_x9 = local_unnamed_addr global i32 4, align 4 @foo_x10 = local_unnamed_addr global i32 4, align 4 @foo_x11 = local_unnamed_addr global i32 4, align 4 @foo_z0 = local_unnamed_addr global i32 8, align 4 -@foo_z00 = local_unnamed_addr global i32 8, align 4 -@foo_z01 = local_unnamed_addr global i32 1, align 4 -@foo_z02 = local_unnamed_addr global i32 2, align 4 -@foo_z03 = local_unnamed_addr global i32 1, align 4 -@foo_z04 = local_unnamed_addr global i32 4, align 4 -@foo_z05 = local_unnamed_addr global i32 1, align 4 \ No newline at end of file diff --git a/test/test_suite2/compile_time_introspection/nameof_err.c3 b/test/test_suite2/compile_time_introspection/nameof_err.c3 index 764f6d41b..0de24c9ee 100644 --- a/test/test_suite2/compile_time_introspection/nameof_err.c3 +++ b/test/test_suite2/compile_time_introspection/nameof_err.c3 @@ -11,10 +11,10 @@ fn void main2() fn void main3() { - $extnameof($evaltype("int")); // #error: Only user defined types have an external name. + $evaltype("int").extnameof; // #error: 'int' does not have a property 'extnameof' } fn void main4() { - $extnameof($evaltype("foo::int")); // #error: Only valid types may be resolved with $evaltype. + $evaltype("foo::int").extnameof; // #error: Only valid types may be resolved with $evaltype. } diff --git a/test/test_suite2/compile_time_introspection/offsetof.c3t b/test/test_suite2/compile_time_introspection/offsetof.c3t index 7a31f7f53..915dbaa64 100644 --- a/test/test_suite2/compile_time_introspection/offsetof.c3t +++ b/test/test_suite2/compile_time_introspection/offsetof.c3t @@ -36,35 +36,15 @@ union Foob } -short y = $offsetof(Bob.y); -int z = $offsetof(Bob.y); -int w = $offsetof(Bob.y); -int x1 = $offsetof(Ex.c[3]); -int x2 = $offsetof(Ex.y[1]); -int x4 = $offsetof(Ar.br[1]); -int x6 = $offsetof(Ar.br[1].x); -int x5 = $offsetof(Ar.br[1]); -int x7 = $offsetof(Ar.br[2].x); -int x8 = $offsetof(Ar.br[2]); -int z0 = $offsetof(Foob.c); -int z00 = $offsetof(Foob.c[0]); -int z01 = $offsetof(Foob.c[1]); -int z02 = $offsetof(Foob.c[5]); -int z03 = $offsetof(Foob.a); +short y = Bob.y.offsetof; +int z = Bob.w.z.offsetof; +int w = Bob.w.offsetof; +int z0 = Foob.c.offsetof; +int z03 = Foob.a.offsetof; // #expect: foo.ll @foo_y = local_unnamed_addr global i16 16, align 2 -@foo_z = local_unnamed_addr global i32 16, align 4 -@foo_w = local_unnamed_addr global i32 16, align 4 -@foo_x1 = local_unnamed_addr global i32 3, align 4 -@foo_x2 = local_unnamed_addr global i32 4, align 4 -@foo_x4 = local_unnamed_addr global i32 16, align 4 -@foo_x6 = local_unnamed_addr global i32 20, align 4 -@foo_x5 = local_unnamed_addr global i32 16, align 4 -@foo_x7 = local_unnamed_addr global i32 28, align 4 -@foo_x8 = local_unnamed_addr global i32 24, align 4 +@foo_z = local_unnamed_addr global i32 116, align 4 +@foo_w = local_unnamed_addr global i32 116, align 4 @foo_z0 = local_unnamed_addr global i32 0, align 4 -@foo_z00 = local_unnamed_addr global i32 0, align 4 -@foo_z01 = local_unnamed_addr global i32 1, align 4 -@foo_z02 = local_unnamed_addr global i32 5, align 4 @foo_z03 = local_unnamed_addr global i32 0, align 4 diff --git a/test/test_suite2/enumerations/compile_time.c3t b/test/test_suite2/enumerations/compile_time.c3t index adc1d698a..684f8ef3b 100644 --- a/test/test_suite2/enumerations/compile_time.c3t +++ b/test/test_suite2/enumerations/compile_time.c3t @@ -6,7 +6,7 @@ enum MyEnum : short } int myenum_elements = MyEnum.elements; -int myenum_alignof = $alignof(MyEnum); +int myenum_alignof = MyEnum.alignof; int myenum_sizeof = MyEnum.sizeof; /* #expect: compile_time.ll diff --git a/test/test_suite2/initializer_lists/initializers_to_macros.c3 b/test/test_suite2/initializer_lists/initializers_to_macros.c3 index 9625d67bd..4b5a31f18 100644 --- a/test/test_suite2/initializer_lists/initializers_to_macros.c3 +++ b/test/test_suite2/initializer_lists/initializers_to_macros.c3 @@ -7,5 +7,5 @@ macro test(foo) fn void main() { test(int[] { 1, 2 }); - test({ 1, 2 }); // #error: An untyped list can only be passed as a compile time parameter. + test({ 1, 2 }); // #error: A value of type 'untyped_list' can only be passed as a compile time parameter. } \ No newline at end of file diff --git a/test/test_suite2/macros/userland_bitcast.c3t b/test/test_suite2/macros/userland_bitcast.c3t index 7c4ce2190..5b7442a35 100644 --- a/test/test_suite2/macros/userland_bitcast.c3t +++ b/test/test_suite2/macros/userland_bitcast.c3t @@ -6,21 +6,21 @@ macro testbitcast(expr, $Type) $Type x = void; var $size = (usize)($sizeof(expr)); - $if ($alignof(expr) >= 8 && $alignof($Type) >= 8): + $if ($alignof(expr) >= 8 && $Type.alignof >= 8): ulong *b = (ulong*)(&expr); ulong *to = (ulong*)(&x); for (usize i = 0; i < $size; i += 8) { to[i] = b[i]; } - $elif ($alignof(expr) >= 4 && $alignof($Type) >= 4): + $elif ($alignof(expr) >= 4 && $Type.alignof >= 4): uint* b = (uint*)(&expr); uint* to = (uint*)(&x); for (usize i = 0; i < $size; i += 4) { to[i] = b[i]; } - $elif ($alignof(expr) >= 2 && $alignof($Type) >= 2): + $elif ($alignof(expr) >= 2 && $Type.alignof >= 2): ushort* b = (ushort*)(&expr); ushort* to = (ushort*)(&x); for (usize i = 0; i < $size; i += 2) diff --git a/test/test_suite2/subarrays/slice_negative_len.c3 b/test/test_suite2/subarrays/slice_negative_len.c3 index 3ce848262..e9e44f2f7 100644 --- a/test/test_suite2/subarrays/slice_negative_len.c3 +++ b/test/test_suite2/subarrays/slice_negative_len.c3 @@ -16,7 +16,7 @@ fn void test2() fn void test3() { int[3] x = { 1, 2, 3 }; - int[] z = x[..4]; // #error: Array end index out of bounds, was 4, exceeding array length 3. + int[] z = x[..4]; // #error: End index out of bounds, was 4, exceeding 3. } fn void test4() @@ -29,31 +29,31 @@ fn void test4() fn void test5() { int[3] x = { 1, 2, 3 }; - int[] z = x[..^4]; // #error: Array index out of bounds, using a negative array index is only allowed with pointers. + int[] z = x[..^4]; // #error: Index out of bounds, using a negative index is only allowed for pointers. } fn void test6() { int[3] x = { 1, 2, 3 }; - int[] z = x[3..]; // #error: Array index out of bounds, was 3, exceeding max array index 2. + int[] z = x[3..]; // #error: Index out of bounds, was 3, exceeding maximum (2). } fn void test7() { int[3] x = { 1, 2, 3 }; - int[] z = x[-1..]; // #error: Array index out of bounds, using a negative array index is only allowed with pointers. + int[] z = x[-1..]; // #error: Index out of bounds, using a negative index is only allowed for pointers. } fn void test8() { int[3] x = { 1, 2, 3 }; - int[] z = x[^4..]; // #error: Array index out of bounds, using a negative array index is only allowed with pointers. + int[] z = x[^4..]; // #error: Index out of bounds, using a negative index is only allowed for pointers. } fn void test9() { int[3] x = { 1, 2, 3 }; - int[] z = x[^0..]; // #error: Array index out of bounds, was 3, exceeding max array index 2. + int[] z = x[^0..]; // #error: Index out of bounds, was 3, exceeding maximum (2) } fn void test10() @@ -68,5 +68,5 @@ fn void test10() fn void test11() { int[3] x = { 1, 2, 3 }; - int[] z = x[..^0]; // #error: Array end index out of bounds, was 3, exceeding array length 3 + int[] z = x[..^0]; // #error: End index out of bounds, was 3, exceeding 3. }