diff options
| -rw-r--r-- | doc/langref.html.in | 2 | ||||
| -rw-r--r-- | lib/std/event/loop.zig | 23 | ||||
| -rw-r--r-- | src/all_types.hpp | 1 | ||||
| -rw-r--r-- | src/analyze.cpp | 23 | ||||
| -rw-r--r-- | src/analyze.hpp | 2 | ||||
| -rw-r--r-- | src/codegen.cpp | 12 | ||||
| -rw-r--r-- | src/ir.cpp | 172 | ||||
| -rw-r--r-- | test/compile_errors.zig | 8 | ||||
| -rw-r--r-- | test/stage1/behavior/fn.zig | 16 | ||||
| -rw-r--r-- | test/stage1/behavior/struct.zig | 11 |
10 files changed, 203 insertions, 67 deletions
diff --git a/doc/langref.html.in b/doc/langref.html.in index f5fbb4e3a3..5d989c1bbd 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5404,7 +5404,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 { <p> For example, if we were to introduce another function to the above snippet: </p> - {#code_begin|test_err|cannot store runtime value in type 'type'#} + {#code_begin|test_err|values of type 'type' must be comptime known#} fn max(comptime T: type, a: T, b: T) T { return if (a > b) a else b; } diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index a6284411eb..8f01c19746 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -645,12 +645,6 @@ pub const Loop = struct { } } - /// This is equivalent to function call, except it calls `startCpuBoundOperation` first. - pub fn call(comptime func: var, args: ...) @typeOf(func).ReturnType { - startCpuBoundOperation(); - return func(args); - } - /// Yielding lets the event loop run, starting any unstarted async operations. /// Note that async operations automatically start when a function yields for any other reason, /// for example, when async I/O is performed. This function is intended to be used only when @@ -942,23 +936,6 @@ test "std.event.Loop - basic" { loop.run(); } -test "std.event.Loop - call" { - // https://github.com/ziglang/zig/issues/1908 - if (builtin.single_threaded) return error.SkipZigTest; - - var loop: Loop = undefined; - try loop.initMultiThreaded(); - defer loop.deinit(); - - var did_it = false; - var handle = async Loop.call(testEventLoop); - var handle2 = async Loop.call(testEventLoop2, &handle, &did_it); - - loop.run(); - - testing.expect(did_it); -} - async fn testEventLoop() i32 { return 1234; } diff --git a/src/all_types.hpp b/src/all_types.hpp index 1acd855b96..25815ef64a 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3667,6 +3667,7 @@ struct IrInstructionArgType { IrInstruction *fn_type; IrInstruction *arg_index; + bool allow_var; }; struct IrInstructionExport { diff --git a/src/analyze.cpp b/src/analyze.cpp index 4c63c566e9..1232cebe8b 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) { return false; } -// Whether the type has bits at runtime. +// Deprecated. Use type_has_bits2. bool type_has_bits(ZigType *type_entry) { assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); @@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) { return type_entry->abi_size != 0; } +// Whether the type has bits at runtime. +Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) { + Error err; + + if (type_is_invalid(type_entry)) + return ErrorSemanticAnalyzeFail; + + if (type_entry->id == ZigTypeIdStruct && + type_entry->data.structure.resolve_status == ResolveStatusBeingInferred) + { + *result = true; + return ErrorNone; + } + + if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) + return err; + + *result = type_entry->abi_size != 0; + return ErrorNone; +} + // Whether you can infer the value based solely on the type. OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { assert(type_entry != nullptr); diff --git a/src/analyze.hpp b/src/analyze.hpp index 06c8847eda..884f525717 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type); bool handle_is_ptr(ZigType *type_entry); bool type_has_bits(ZigType *type_entry); +Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result); + Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result); bool ptr_allows_addr_zero(ZigType *ptr_type); bool type_is_nonnull_ptr(ZigType *type); diff --git a/src/codegen.cpp b/src/codegen.cpp index 3ed269e621..a0666a3522 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_ } static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { + Error err; + ZigType *ptr_type = instruction->ptr->value.type; assert(ptr_type->id == ZigTypeIdPointer); - if (!type_has_bits(ptr_type)) + bool ptr_type_has_bits; + if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits))) + codegen_report_errors_and_exit(g); + if (!ptr_type_has_bits) return nullptr; if (instruction->ptr->ref_count == 0) { // In this case, this StorePtr instruction should be elided. Something happened like this: @@ -7834,6 +7839,11 @@ static void define_builtin_types(CodeGen *g) { g->builtin_types.entry_null = entry; } { + ZigType *entry = new_type_table_entry(ZigTypeIdOpaque); + buf_init_from_str(&entry->name, "(var)"); + g->builtin_types.entry_var = entry; + } + { ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple); buf_init_from_str(&entry->name, "(args)"); g->builtin_types.entry_arg_tuple = entry; diff --git a/src/ir.cpp b/src/ir.cpp index e794e8db03..b6cc3cd4cb 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -206,6 +206,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); +static ResultLoc *no_result_loc(void); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -3119,11 +3120,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast } static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *fn_type, IrInstruction *arg_index) + IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var) { IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); instruction->fn_type = fn_type; instruction->arg_index = arg_index; + instruction->allow_var = allow_var; ir_ref_instruction(fn_type, irb->current_basic_block); ir_ref_instruction(arg_index, irb->current_basic_block); @@ -5670,7 +5672,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo if (arg1_value == irb->codegen->invalid_instruction) return arg1_value; - IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); + IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false); return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); } case BuiltinFnIdExport: @@ -5892,13 +5894,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node if (fn_ref == irb->codegen->invalid_instruction) return fn_ref; + IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref); + size_t arg_count = node->data.fn_call_expr.params.length; IrInstruction **args = allocate<IrInstruction*>(arg_count); for (size_t i = 0; i < arg_count; i += 1) { AstNode *arg_node = node->data.fn_call_expr.params.at(i); - args[i] = ir_gen_node(irb, arg_node, scope); - if (args[i] == irb->codegen->invalid_instruction) - return args[i]; + + IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); + IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc()); + + IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); + if (arg == irb->codegen->invalid_instruction) + return arg; + + args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); } IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, @@ -12554,6 +12565,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou return result; } +static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); + return ira->codegen->invalid_instruction; +} + +static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct")); + return ira->codegen->invalid_instruction; +} + +static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); + return ira->codegen->invalid_instruction; +} + static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) { @@ -12565,6 +12597,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ira->codegen->invalid_instruction; } + // This means the wanted type is anything. + if (wanted_type == ira->codegen->builtin_types.entry_var) { + return value; + } + // perfect match or non-const to const ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, source_node, false); @@ -13121,6 +13158,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); } + // cast from inferred struct type to array, union, or struct + if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) { + AstNode *decl_node = actual_type->data.structure.decl_node; + ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); + ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; + uint32_t field_count = actual_type->data.structure.src_field_count; + if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) && + wanted_type->data.array.len == field_count) + { + return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); + } else if (wanted_type->id == ZigTypeIdStruct && + (init_kind == ContainerInitKindStruct || field_count == 0)) + { + return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); + } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) { + return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); + } + } + // cast from undefined to anything if (actual_type->id == ZigTypeIdUndefined) { return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); @@ -15507,15 +15563,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; result->base.value.data.x_ptr.data.ref.pointee = pointee; - if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) + bool var_type_has_bits; + if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) return ira->codegen->invalid_instruction; if (align != 0) { if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) return ira->codegen->invalid_instruction; - if (!type_has_bits(var_type)) { - ir_add_error(ira, source_inst, - buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", - name_hint, buf_ptr(&var_type->name))); + if (!var_type_has_bits) { + ir_add_error(ira, source_inst, + buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", + name_hint, buf_ptr(&var_type->name))); return ira->codegen->invalid_instruction; } } @@ -15587,21 +15644,31 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { ptr->value.data.x_ptr.data.ref.pointee = undef_child; } -static bool ir_result_has_type(ResultLoc *result_loc) { +static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { switch (result_loc->id) { case ResultLocIdInvalid: case ResultLocIdPeerParent: zig_unreachable(); case ResultLocIdNone: case ResultLocIdPeer: - return false; + *out = false; + return ErrorNone; case ResultLocIdReturn: case ResultLocIdInstruction: case ResultLocIdBitCast: - case ResultLocIdCast: - return true; + *out = true; + return ErrorNone; + case ResultLocIdCast: { + ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); + ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); + if (type_is_invalid(dest_type)) + return ErrorSemanticAnalyzeFail; + *out = (dest_type != ira->codegen->builtin_types.entry_var); + return ErrorNone; + } case ResultLocIdVar: - return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; + *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; + return ErrorNone; } zig_unreachable(); } @@ -15748,7 +15815,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } return nullptr; } - if (ir_result_has_type(peer_parent->parent)) { + bool peer_parent_has_type; + if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) + return ira->codegen->invalid_instruction; + if (peer_parent_has_type) { if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true; ira->src_implicit_return_type_list.append(value); @@ -15791,6 +15861,11 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if (type_is_invalid(dest_type)) return ira->codegen->invalid_instruction; + if (dest_type == ira->codegen->builtin_types.entry_var) { + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, + force_runtime, non_null_comptime); + } + ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, result_cast->base.source_instruction->source_node, false); if (const_cast_result.id == ConstCastResultIdInvalid) @@ -15998,6 +16073,9 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, if (type_is_invalid(implicit_elem_type)) return ira->codegen->invalid_instruction; } else { + implicit_elem_type = ira->codegen->builtin_types.entry_var; + } + if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { Buf *bare_name = buf_alloc(); Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), instruction->base.scope, instruction->base.source_node, bare_name); @@ -17582,6 +17660,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, } static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { + Error err; + if (ira->const_predecessor_bb) { for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; @@ -17713,24 +17793,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh } ZigType *resolved_type; - if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) { - if (peer_parent->parent->id == ResultLocIdReturn) { - resolved_type = ira->explicit_return_type; - } else if (peer_parent->parent->id == ResultLocIdCast) { - resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); - if (type_is_invalid(resolved_type)) - return ira->codegen->invalid_instruction; - } else { - ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; - ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); - resolved_type = resolved_loc_ptr_type->data.pointer.child_type; + if (peer_parent != nullptr) { + bool peer_parent_has_type; + if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) + return ira->codegen->invalid_instruction; + if (peer_parent_has_type) { + if (peer_parent->parent->id == ResultLocIdReturn) { + resolved_type = ira->explicit_return_type; + } else if (peer_parent->parent->id == ResultLocIdCast) { + resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); + if (type_is_invalid(resolved_type)) + return ira->codegen->invalid_instruction; + } else { + ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; + ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); + resolved_type = resolved_loc_ptr_type->data.pointer.child_type; + } + goto skip_resolve_peer_types; } - } else { + } + { resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, new_incoming_values.items, new_incoming_values.length); if (type_is_invalid(resolved_type)) return ira->codegen->invalid_instruction; } +skip_resolve_peer_types: switch (type_has_one_possible_value(ira->codegen, resolved_type)) { case OnePossibleValueInvalid: @@ -18429,7 +18517,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n inferred_struct_field->inferred_struct_type = container_type; inferred_struct_field->field_name = field_name; - ZigType *elem_type = ira->codegen->builtin_types.entry_c_void; + ZigType *elem_type = ira->codegen->builtin_types.entry_var; ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field); @@ -22101,15 +22189,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct } for (size_t i = 0; i < errors_len; i += 1) { Stage2ErrorMsg *clang_err = &errors_ptr[i]; - // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null - if (clang_err->source && clang_err->filename_ptr) { + // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null + if (clang_err->source && clang_err->filename_ptr) { ErrorMsg *err_msg = err_msg_create_with_offset( clang_err->filename_ptr ? buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), clang_err->line, clang_err->column, clang_err->offset, clang_err->source, buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); err_msg_add_note(parent_err_msg, err_msg); - } + } } return ira->codegen->invalid_instruction; @@ -25597,6 +25685,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) return ira->codegen->invalid_instruction; + if (fn_type->id == ZigTypeIdBoundFn) { + fn_type = fn_type->data.bound_fn.fn_type; + arg_index += 1; + } if (fn_type->id != ZigTypeIdFn) { ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); return ira->codegen->invalid_instruction; @@ -25604,6 +25696,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; if (arg_index >= fn_type_id->param_count) { + if (instruction->allow_var) { + // TODO remove this with var args + return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); + } ir_add_error(ira, arg_index_inst, buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); @@ -25615,10 +25711,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct // Args are only unresolved if our function is generic. ir_assert(fn_type->data.fn.is_generic, &instruction->base); - ir_add_error(ira, arg_index_inst, - buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", - arg_index, buf_ptr(&fn_type->name))); - return ira->codegen->invalid_instruction; + if (instruction->allow_var) { + return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); + } else { + ir_add_error(ira, arg_index_inst, + buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", + arg_index, buf_ptr(&fn_type->name))); + return ira->codegen->invalid_instruction; + } } return ir_const_type(ira, &instruction->base, result_type); } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index c42c95465a..63d7240d42 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2123,8 +2123,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\fn bar(x: *b.Foo) void {} , - "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'", - "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", + "tmp.zig:6:9: error: expected type '*b.Foo', found '*a.Foo'", + "tmp.zig:6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", "a.zig:1:17: note: a.Foo declared here", "b.zig:1:17: note: b.Foo declared here", ); @@ -4988,7 +4988,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } , - "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'", + "tmp.zig:8:16: error: expected type '*const u3', found '*align(:3:1) const u3'", ); cases.add( @@ -5685,7 +5685,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ x.* += 1; \\} , - "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'", + "tmp.zig:8:9: error: expected type '*u32', found '*align(1) u32'", ); cases.add( diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig index 1fc586f39f..99d145f1b1 100644 --- a/test/stage1/behavior/fn.zig +++ b/test/stage1/behavior/fn.zig @@ -247,3 +247,19 @@ test "discard the result of a function that returns a struct" { S.entry(); comptime S.entry(); } + +test "function call with anon list literal" { + const S = struct { + fn doTheTest() void { + consumeVec(.{9, 8, 7}); + } + + fn consumeVec(vec: [3]f32) void { + expect(vec[0] == 9); + expect(vec[1] == 8); + expect(vec[2] == 7); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index a42c261e3b..722f44d352 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -755,7 +755,7 @@ test "fully anonymous struct" { test "fully anonymous list literal" { const S = struct { fn doTheTest() void { - dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"}); + dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); } fn dump(args: var) void { expect(args.@"0" == 1234); @@ -768,3 +768,12 @@ test "fully anonymous list literal" { S.doTheTest(); comptime S.doTheTest(); } + +test "anonymous struct literal assigned to variable" { + var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) }; + expect(vec.@"0" == 22); + expect(vec.@"1" == 55); + expect(vec.@"2" == 99); + vec.@"1" += 1; + expect(vec.@"1" == 56); +} |
