diff options
| -rw-r--r-- | src/AstGen.zig | 16 | ||||
| -rw-r--r-- | src/Sema.zig | 31 | ||||
| -rw-r--r-- | test/behavior/pointers.zig | 8 |
3 files changed, 39 insertions, 16 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index cb710af900..8197589523 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1319,25 +1319,25 @@ fn arrayInitExpr( }, .ref => { if (types.array != .none) { - return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, .array_init_ref); + return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.array, .array_init_ref); } else { return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon_ref); } }, .none => { if (types.array != .none) { - return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, .array_init); + return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.array, .array_init); } else { return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); } }, .ty, .coerced_ty => |ty_inst| { if (types.array != .none) { - const result = try arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, .array_init); + const result = try arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.array, .array_init); return rvalue(gz, rl, result, node); } else { const elem_type = try gz.addUnNode(.elem_type, ty_inst, node); - return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, elem_type, .array_init); + return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, elem_type, types.array, .array_init); } }, .ptr => |ptr_inst| { @@ -1387,14 +1387,18 @@ fn arrayInitExprRlTy( node: Ast.Node.Index, elements: []const Ast.Node.Index, elem_ty_inst: Zir.Inst.Ref, + array_ty: Zir.Inst.Ref, tag: Zir.Inst.Tag, ) InnerError!Zir.Inst.Ref { const astgen = gz.astgen; const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{ - .operands_len = @intCast(u32, elements.len), + .operands_len = @intCast(u32, elements.len + 1), }); - var extra_index = try reserveExtra(astgen, elements.len); + var extra_index = try reserveExtra(astgen, elements.len + 1); + + astgen.extra.items[extra_index] = @enumToInt(array_ty); + extra_index += 1; const elem_rl: ResultLoc = .{ .ty = elem_ty_inst }; for (elements) |elem_init| { diff --git a/src/Sema.zig b/src/Sema.zig index fb7209ae0e..6c1c3d57b0 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -11796,23 +11796,34 @@ fn zirArrayInit( for (args) |arg, i| resolved_args[i] = sema.resolveInst(arg); - const elem_ty = sema.typeOf(resolved_args[0]); + const elem_ty = sema.typeOf(resolved_args[1]); + const array_ty = switch (resolved_args[0]) { + .none => try Type.Tag.array.create(sema.arena, .{ + .len = resolved_args.len, + .elem_type = elem_ty, + }), - const array_ty = try Type.Tag.array.create(sema.arena, .{ - .len = resolved_args.len, - .elem_type = elem_ty, - }); + else => |ref| blk: { + assert(sema.typeOf(ref).zigTypeTag() == .Type); + var buffer: Value.ToTypeBuffer = undefined; + const val = try sema.resolveConstValue(block, src, ref); + const ty = val.toType(&buffer); + break :blk try ty.copy(sema.arena); + }, + }; + + const elems = resolved_args[1..]; - const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| { + const opt_runtime_src: ?LazySrcLoc = for (elems) |arg| { const arg_src = src; // TODO better source location const comptime_known = try sema.isComptimeKnown(block, arg_src, arg); if (!comptime_known) break arg_src; } else null; const runtime_src = opt_runtime_src orelse { - const elem_vals = try sema.arena.alloc(Value, resolved_args.len); + const elem_vals = try sema.arena.alloc(Value, elems.len); - for (resolved_args) |arg, i| { + for (elems) |arg, i| { // We checked that all args are comptime above. elem_vals[i] = (sema.resolveMaybeUndefVal(block, src, arg) catch unreachable).?; } @@ -11839,7 +11850,7 @@ fn zirArrayInit( }); const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); - for (resolved_args) |arg, i| { + for (elems) |arg, i| { const index = try sema.addIntUnsigned(Type.usize, i); const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref); _ = try block.addBinOp(.store, elem_ptr, arg); @@ -11847,7 +11858,7 @@ fn zirArrayInit( return alloc; } - return block.addAggregateInit(array_ty, resolved_args); + return block.addAggregateInit(array_ty, elems); } fn zirArrayInitAnon( diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 6fd7e41a6d..d2ec6d9bbc 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -270,6 +270,14 @@ test "assign null directly to C pointer and test null equality" { comptime try expect((y1 orelse &othery) == y1); } +test "array initialization types" { + const E = enum { A, B, C }; + try expect(@TypeOf([_]u8{}) == [0]u8); + try expect(@TypeOf([_:0]u8{}) == [0:0]u8); + try expect(@TypeOf([_:.A]E{}) == [0:.A]E); + try expect(@TypeOf([_:0]u8{ 1, 2, 3 }) == [3:0]u8); +} + test "null terminated pointer" { if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO |
