aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/langref.html.in2
-rw-r--r--lib/std/event/loop.zig23
-rw-r--r--src/all_types.hpp1
-rw-r--r--src/analyze.cpp23
-rw-r--r--src/analyze.hpp2
-rw-r--r--src/codegen.cpp12
-rw-r--r--src/ir.cpp172
-rw-r--r--test/compile_errors.zig8
-rw-r--r--test/stage1/behavior/fn.zig16
-rw-r--r--test/stage1/behavior/struct.zig11
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);
+}