authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-14 10:12:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-14 10:12:45-07:00
log25874747174da2b0e77b3b888d0f5a13aa1a317e
treef715cc1f2ce49c747e2e045e785673d41af3b312
parent07397707392d27fbee5f1bf0a788937b66300bf0

stage2: progress towards stage3

* The `@bitCast` workaround is removed in favor of `@ptrCast` properly doing element casting for slice element types. This required an enhancement both to stage1 and stage2. * stage1 incorrectly accepts `.{}` instead of `{}`. stage2 code that abused this is fixed. * Make some parameters comptime to support functions in switch expressions (as opposed to making them function pointers). * Avoid relying on local temporaries being mutable. * Workarounds for when stage1 and stage2 disagree on function pointer types. * Workaround recursive formatting bug with a `@panic("TODO")`. * Remove unreachable `else` prongs for some inferred error sets. All in effort towards #89.

26 files changed, 156 insertions(+), 91 deletions(-)

lib/std/fmt.zig-2
......@@ -766,12 +766,10 @@ fn formatFloatValue(
766766 } else if (comptime std.mem.eql(u8, fmt, "d")) {
767767 formatFloatDecimal(value, options, buf_stream.writer()) catch |err| switch (err) {
768768 error.NoSpaceLeft => unreachable,
769 else => |e| return e,
770769 };
771770 } else if (comptime std.mem.eql(u8, fmt, "x")) {
772771 formatFloatHexadecimal(value, options, buf_stream.writer()) catch |err| switch (err) {
773772 error.NoSpaceLeft => unreachable,
774 else => |e| return e,
775773 };
776774 } else {
777775 @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
lib/std/io.zig-1
......@@ -9,7 +9,6 @@ const os = std.os;
99const fs = std.fs;
1010const mem = std.mem;
1111const meta = std.meta;
12const trait = meta.trait;
1312const File = std.fs.File;
1413
1514pub const Mode = enum {
lib/std/rand.zig+1-3
......@@ -66,9 +66,7 @@ pub const Random = struct {
6666
6767 /// Returns a random value from an enum, evenly distributed.
6868 pub fn enumValue(r: Random, comptime EnumType: type) EnumType {
69 if (comptime !std.meta.trait.is(.Enum)(EnumType)) {
70 @compileError("Random.enumValue requires an enum type, not a " ++ @typeName(EnumType));
71 }
69 comptime assert(@typeInfo(EnumType) == .Enum);
7270
7371 // We won't use int -> enum casting because enum elements can have
7472 // arbitrary values. Instead we'll randomly pick one of the type's values.
src/AstGen.zig+2-2
......@@ -85,12 +85,12 @@ fn reserveExtra(astgen: *AstGen, size: usize) Allocator.Error!u32 {
8585}
8686
8787fn appendRefs(astgen: *AstGen, refs: []const Zir.Inst.Ref) !void {
88 const coerced = @bitCast([]const u32, refs);
88 const coerced = @ptrCast([]const u32, refs);
8989 return astgen.extra.appendSlice(astgen.gpa, coerced);
9090}
9191
9292fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {
93 const coerced = @bitCast([]const u32, refs);
93 const coerced = @ptrCast([]const u32, refs);
9494 astgen.extra.appendSliceAssumeCapacity(coerced);
9595}
9696
src/Liveness.zig+4-4
......@@ -454,7 +454,7 @@ fn analyzeInst(
454454 const inst_data = inst_datas[inst].pl_op;
455455 const callee = inst_data.operand;
456456 const extra = a.air.extraData(Air.Call, inst_data.payload);
457 const args = @bitCast([]const Air.Inst.Ref, a.air.extra[extra.end..][0..extra.data.args_len]);
457 const args = @ptrCast([]const Air.Inst.Ref, a.air.extra[extra.end..][0..extra.data.args_len]);
458458 if (args.len + 1 <= bpi - 1) {
459459 var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1);
460460 buf[0] = callee;
......@@ -495,7 +495,7 @@ fn analyzeInst(
495495 const ty_pl = inst_datas[inst].ty_pl;
496496 const aggregate_ty = a.air.getRefType(ty_pl.ty);
497497 const len = @intCast(usize, aggregate_ty.arrayLen());
498 const elements = @bitCast([]const Air.Inst.Ref, a.air.extra[ty_pl.payload..][0..len]);
498 const elements = @ptrCast([]const Air.Inst.Ref, a.air.extra[ty_pl.payload..][0..len]);
499499
500500 if (elements.len <= bpi - 1) {
501501 var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1);
......@@ -571,9 +571,9 @@ fn analyzeInst(
571571 .assembly => {
572572 const extra = a.air.extraData(Air.Asm, inst_datas[inst].ty_pl.payload);
573573 var extra_i: usize = extra.end;
574 const outputs = @bitCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.outputs_len]);
574 const outputs = @ptrCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.outputs_len]);
575575 extra_i += outputs.len;
576 const inputs = @bitCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.inputs_len]);
576 const inputs = @ptrCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.inputs_len]);
577577 extra_i += inputs.len;
578578
579579 simple: {
src/Module.zig+2-2
......@@ -4593,7 +4593,7 @@ pub fn clearDecl(
45934593 .c => .{ .c = {} },
45944594 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
45954595 .spirv => .{ .spirv = .{} },
4596 .nvptx => .{ .nvptx = .{} },
4596 .nvptx => .{ .nvptx = {} },
45974597 };
45984598 }
45994599 if (decl.getInnerNamespace()) |namespace| {
......@@ -4975,7 +4975,7 @@ pub fn allocateNewDecl(
49754975 .c => .{ .c = {} },
49764976 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
49774977 .spirv => .{ .spirv = .{} },
4978 .nvptx => .{ .nvptx = .{} },
4978 .nvptx => .{ .nvptx = {} },
49794979 },
49804980 .generation = 0,
49814981 .is_pub = false,
src/Sema.zig+25-9
......@@ -14110,21 +14110,27 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1411014110
1411114111 try sema.checkPtrType(block, dest_ty_src, dest_ty);
1411214112 try sema.checkPtrOperand(block, operand_src, operand_ty);
14113 if (dest_ty.isSlice()) {
14113
14114 const dest_is_slice = dest_ty.isSlice();
14115 const operand_is_slice = operand_ty.isSlice();
14116 if (dest_is_slice and !operand_is_slice) {
1411414117 return sema.fail(block, dest_ty_src, "illegal pointer cast to slice", .{});
1411514118 }
14116 const ptr = if (operand_ty.isSlice())
14119 const ptr = if (operand_is_slice and !dest_is_slice)
1411714120 try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty)
1411814121 else
1411914122 operand;
1412014123
14121 try sema.resolveTypeLayout(block, dest_ty_src, dest_ty.elemType2());
14124 const dest_elem_ty = dest_ty.elemType2();
14125 try sema.resolveTypeLayout(block, dest_ty_src, dest_elem_ty);
1412214126 const dest_align = dest_ty.ptrAlignment(target);
14123 try sema.resolveTypeLayout(block, operand_src, operand_ty.elemType2());
14127
14128 const operand_elem_ty = operand_ty.elemType2();
14129 try sema.resolveTypeLayout(block, operand_src, operand_elem_ty);
1412414130 const operand_align = operand_ty.ptrAlignment(target);
1412514131
1412614132 // If the destination is less aligned than the source, preserve the source alignment
14127 var aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
14133 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
1412814134 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
1412914135 if (dest_ty.zigTypeTag() == .Optional) {
1413014136 var buf: Type.Payload.ElemType = undefined;
......@@ -14138,6 +14144,16 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1413814144 }
1413914145 };
1414014146
14147 if (dest_is_slice) {
14148 const operand_elem_size = operand_elem_ty.abiSize(target);
14149 const dest_elem_size = dest_elem_ty.abiSize(target);
14150 if (operand_elem_size != dest_elem_size) {
14151 // note that this is not implemented in stage1 so we should probably wait
14152 // until that codebase is replaced before implementing this in stage2.
14153 return sema.fail(block, dest_ty_src, "TODO: implement @ptrCast between slices changing the length", .{});
14154 }
14155 }
14156
1414114157 return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src);
1414214158}
1414314159
......@@ -15743,7 +15759,7 @@ fn zirMinMax(
1574315759 sema: *Sema,
1574415760 block: *Block,
1574515761 inst: Zir.Inst.Index,
15746 air_tag: Air.Inst.Tag,
15762 comptime air_tag: Air.Inst.Tag,
1574715763) CompileError!Air.Inst.Ref {
1574815764 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1574915765 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
......@@ -15763,7 +15779,7 @@ fn analyzeMinMax(
1576315779 src: LazySrcLoc,
1576415780 lhs: Air.Inst.Ref,
1576515781 rhs: Air.Inst.Ref,
15766 air_tag: Air.Inst.Tag,
15782 comptime air_tag: Air.Inst.Tag,
1576715783 lhs_src: LazySrcLoc,
1576815784 rhs_src: LazySrcLoc,
1576915785) CompileError!Air.Inst.Ref {
......@@ -20976,7 +20992,7 @@ fn resolvePeerTypes(
2097620992 sema: *Sema,
2097720993 block: *Block,
2097820994 src: LazySrcLoc,
20979 instructions: []Air.Inst.Ref,
20995 instructions: []const Air.Inst.Ref,
2098020996 candidate_srcs: Module.PeerTypeCandidateSrc,
2098120997) !Type {
2098220998 switch (instructions.len) {
......@@ -22794,7 +22810,7 @@ pub fn addExtraAssumeCapacity(sema: *Sema, extra: anytype) u32 {
2279422810}
2279522811
2279622812fn appendRefsAssumeCapacity(sema: *Sema, refs: []const Air.Inst.Ref) void {
22797 const coerced = @bitCast([]const u32, refs);
22813 const coerced = @ptrCast([]const u32, refs);
2279822814 sema.air_extra.appendSliceAssumeCapacity(coerced);
2279922815}
2280022816
src/arch/aarch64/CodeGen.zig+8-5
......@@ -2398,7 +2398,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
23982398 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
23992399 const callee = pl_op.operand;
24002400 const extra = self.air.extraData(Air.Call, pl_op.payload);
2401 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
2401 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
24022402 const ty = self.air.typeOf(callee);
24032403
24042404 const fn_ty = switch (ty.zigTypeTag()) {
......@@ -2865,7 +2865,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
28652865 // TODO track the new register / stack allocation
28662866 }
28672867
2868 self.branch_stack.pop().deinit(self.gpa);
2868 {
2869 var item = self.branch_stack.pop();
2870 item.deinit(self.gpa);
2871 }
28692872
28702873 // We already took care of pl_op.operand earlier, so we're going
28712874 // to pass .none here
......@@ -3162,9 +3165,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
31623165 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
31633166 const clobbers_len = @truncate(u31, extra.data.flags);
31643167 var extra_i: usize = extra.end;
3165 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
3168 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
31663169 extra_i += outputs.len;
3167 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
3170 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
31683171 extra_i += inputs.len;
31693172
31703173 const dead = !is_volatile and self.liveness.isUnused(inst);
......@@ -3686,7 +3689,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
36863689 const vector_ty = self.air.typeOfIndex(inst);
36873690 const len = vector_ty.vectorLen();
36883691 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3689 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
3692 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
36903693 const result: MCValue = res: {
36913694 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
36923695 return self.fail("TODO implement airAggregateInit for {}", .{self.target.cpu.arch});
src/arch/arm/CodeGen.zig+8-5
......@@ -3144,7 +3144,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
31443144 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
31453145 const callee = pl_op.operand;
31463146 const extra = self.air.extraData(Air.Call, pl_op.payload);
3147 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3147 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
31483148 const ty = self.air.typeOf(callee);
31493149
31503150 const fn_ty = switch (ty.zigTypeTag()) {
......@@ -3650,7 +3650,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
36503650 // TODO track the new register / stack allocation
36513651 }
36523652
3653 self.branch_stack.pop().deinit(self.gpa);
3653 {
3654 var item = self.branch_stack.pop();
3655 item.deinit(self.gpa);
3656 }
36543657
36553658 // We already took care of pl_op.operand earlier, so we're going
36563659 // to pass .none here
......@@ -3951,9 +3954,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
39513954 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
39523955 const clobbers_len = @truncate(u31, extra.data.flags);
39533956 var extra_i: usize = extra.end;
3954 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
3957 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
39553958 extra_i += outputs.len;
3956 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
3959 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
39573960 extra_i += inputs.len;
39583961
39593962 const dead = !is_volatile and self.liveness.isUnused(inst);
......@@ -4735,7 +4738,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
47354738 const vector_ty = self.air.typeOfIndex(inst);
47364739 const len = vector_ty.vectorLen();
47374740 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4738 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
4741 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
47394742 const result: MCValue = res: {
47404743 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
47414744 return self.fail("TODO implement airAggregateInit for arm", .{});
src/arch/arm/Emit.zig+18-7
......@@ -2,6 +2,7 @@
22//! machine code
33
44const Emit = @This();
5const builtin = @import("builtin");
56const std = @import("std");
67const math = std.math;
78const Mir = @import("Mir.zig");
......@@ -622,12 +623,17 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {
622623 } else return emit.fail("TODO mirLoadStack larger offsets", .{});
623624
624625 const ldr = switch (tag) {
625 .ldr_stack_argument => Instruction.ldr,
626 .ldrb_stack_argument => Instruction.ldrb,
626 .ldr_stack_argument => &Instruction.ldr,
627 .ldrb_stack_argument => &Instruction.ldrb,
627628 else => unreachable,
628629 };
629630
630 try emit.writeInstruction(ldr(
631 const ldr_workaround = switch (builtin.zig_backend) {
632 .stage1 => ldr.*,
633 else => ldr,
634 };
635
636 try emit.writeInstruction(ldr_workaround(
631637 cond,
632638 r_stack_offset.rt,
633639 .fp,
......@@ -643,13 +649,18 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {
643649 } else return emit.fail("TODO mirLoadStack larger offsets", .{});
644650
645651 const ldr = switch (tag) {
646 .ldrh_stack_argument => Instruction.ldrh,
647 .ldrsb_stack_argument => Instruction.ldrsb,
648 .ldrsh_stack_argument => Instruction.ldrsh,
652 .ldrh_stack_argument => &Instruction.ldrh,
653 .ldrsb_stack_argument => &Instruction.ldrsb,
654 .ldrsh_stack_argument => &Instruction.ldrsh,
649655 else => unreachable,
650656 };
651657
652 try emit.writeInstruction(ldr(
658 const ldr_workaround = switch (builtin.zig_backend) {
659 .stage1 => ldr.*,
660 else => ldr,
661 };
662
663 try emit.writeInstruction(ldr_workaround(
653664 cond,
654665 r_stack_offset.rt,
655666 .fp,
src/arch/riscv64/CodeGen.zig+4-4
......@@ -1640,7 +1640,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
16401640 const fn_ty = self.air.typeOf(pl_op.operand);
16411641 const callee = pl_op.operand;
16421642 const extra = self.air.extraData(Air.Call, pl_op.payload);
1643 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
1643 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
16441644
16451645 var info = try self.resolveCallingConventionValues(fn_ty);
16461646 defer info.deinit(self);
......@@ -2075,9 +2075,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
20752075 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
20762076 const clobbers_len = @truncate(u31, extra.data.flags);
20772077 var extra_i: usize = extra.end;
2078 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
2078 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
20792079 extra_i += outputs.len;
2080 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
2080 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
20812081 extra_i += inputs.len;
20822082
20832083 const dead = !is_volatile and self.liveness.isUnused(inst);
......@@ -2413,7 +2413,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
24132413 const vector_ty = self.air.typeOfIndex(inst);
24142414 const len = vector_ty.vectorLen();
24152415 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2416 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
2416 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
24172417 const result: MCValue = res: {
24182418 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
24192419 return self.fail("TODO implement airAggregateInit for riscv64", .{});
src/arch/wasm/CodeGen.zig+2-2
......@@ -2425,7 +2425,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
24252425 var highest_maybe: ?i32 = null;
24262426 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
24272427 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
2428 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
2428 const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
24292429 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
24302430 extra_index = case.end + items.len + case_body.len;
24312431 const values = try self.gpa.alloc(CaseValue, items.len);
......@@ -3328,7 +3328,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
33283328 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
33293329 const result_ty = self.air.typeOfIndex(inst);
33303330 const len = @intCast(usize, result_ty.arrayLen());
3331 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
3331 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
33323332
33333333 switch (result_ty.zigTypeTag()) {
33343334 .Vector => return self.fail("TODO: Wasm backend: implement airAggregateInit for vectors", .{}),
src/arch/x86_64/CodeGen.zig+14-8
......@@ -3501,7 +3501,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
35013501 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
35023502 const callee = pl_op.operand;
35033503 const extra = self.air.extraData(Air.Call, pl_op.payload);
3504 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3504 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
35053505 const ty = self.air.typeOf(callee);
35063506
35073507 const fn_ty = switch (ty.zigTypeTag()) {
......@@ -3684,7 +3684,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
36843684 .ops = (Mir.Ops{
36853685 .flags = 0b01,
36863686 }).encode(),
3687 .data = .{ .imm = @bitCast(i32, @intCast(u32, fn_got_addr)) },
3687 .data = .{ .imm = @intCast(u32, fn_got_addr) },
36883688 });
36893689 } else return self.fail("TODO implement calling extern fn on plan9", .{});
36903690 } else {
......@@ -4220,7 +4220,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
42204220 // TODO track the new register / stack allocation
42214221 }
42224222
4223 self.branch_stack.pop().deinit(self.gpa);
4223 {
4224 var item = self.branch_stack.pop();
4225 item.deinit(self.gpa);
4226 }
42244227
42254228 // We already took care of pl_op.operand earlier, so we're going
42264229 // to pass .none here
......@@ -4562,7 +4565,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
45624565
45634566 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
45644567 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
4565 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
4568 const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
45664569 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
45674570 extra_index = case.end + items.len + case_body.len;
45684571
......@@ -4615,7 +4618,10 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
46154618 if (switch_br.data.else_body_len > 0) {
46164619 const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
46174620 try self.branch_stack.append(.{});
4618 defer self.branch_stack.pop().deinit(self.gpa);
4621 defer {
4622 var item = self.branch_stack.pop();
4623 item.deinit(self.gpa);
4624 }
46194625
46204626 const else_deaths = liveness.deaths.len - 1;
46214627 try self.ensureProcessDeathCapacity(liveness.deaths[else_deaths].len);
......@@ -4705,9 +4711,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
47054711 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
47064712 const clobbers_len = @truncate(u31, extra.data.flags);
47074713 var extra_i: usize = extra.end;
4708 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
4714 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
47094715 extra_i += outputs.len;
4710 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
4716 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
47114717 extra_i += inputs.len;
47124718
47134719 const dead = !is_volatile and self.liveness.isUnused(inst);
......@@ -5975,7 +5981,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
59755981 const result_ty = self.air.typeOfIndex(inst);
59765982 const len = @intCast(usize, result_ty.arrayLen());
59775983 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5978 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
5984 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
59795985 const abi_size = @intCast(u32, result_ty.abiSize(self.target.*));
59805986 const abi_align = result_ty.abiAlignment(self.target.*);
59815987 const result: MCValue = res: {
src/codegen/c.zig+8-9
......@@ -220,6 +220,9 @@ fn formatIdent(
220220}
221221
222222pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
223 if (builtin.zig_backend != .stage1) {
224 @panic("TODO");
225 }
223226 return .{ .data = ident };
224227}
225228
......@@ -2310,7 +2313,6 @@ fn airWrapOp(
23102313 const val = -1 * std.math.pow(i64, 2, @intCast(i64, bits - 1));
23112314 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {
23122315 error.NoSpaceLeft => unreachable,
2313 else => |e| return e,
23142316 };
23152317 },
23162318 },
......@@ -2336,7 +2338,6 @@ fn airWrapOp(
23362338 const val = std.math.pow(u64, 2, pow_bits) - 1;
23372339 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {
23382340 error.NoSpaceLeft => unreachable,
2339 else => |e| return e,
23402341 };
23412342 },
23422343 };
......@@ -2418,7 +2419,6 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
24182419 const val = -1 * std.math.pow(i65, 2, @intCast(i65, bits - 1));
24192420 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {
24202421 error.NoSpaceLeft => unreachable,
2421 else => |e| return e,
24222422 };
24232423 },
24242424 },
......@@ -2444,7 +2444,6 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
24442444 const val = std.math.pow(u65, 2, pow_bits) - 1;
24452445 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {
24462446 error.NoSpaceLeft => unreachable,
2447 else => |e| return e,
24482447 };
24492448 },
24502449 };
......@@ -2702,7 +2701,7 @@ fn airCall(
27022701 }
27032702 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
27042703 const extra = f.air.extraData(Air.Call, pl_op.payload);
2705 const args = @bitCast([]const Air.Inst.Ref, f.air.extra[extra.end..][0..extra.data.args_len]);
2704 const args = @ptrCast([]const Air.Inst.Ref, f.air.extra[extra.end..][0..extra.data.args_len]);
27062705 const callee_ty = f.air.typeOf(pl_op.operand);
27072706 const fn_ty = switch (callee_ty.zigTypeTag()) {
27082707 .Fn => callee_ty,
......@@ -2959,7 +2958,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
29592958 var case_i: u32 = 0;
29602959 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
29612960 const case = f.air.extraData(Air.SwitchBr.Case, extra_index);
2962 const items = @bitCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]);
2961 const items = @ptrCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]);
29632962 const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len];
29642963 extra_index = case.end + case.data.items_len + case_body.len;
29652964
......@@ -2990,9 +2989,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
29902989 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
29912990 const clobbers_len = @truncate(u31, extra.data.flags);
29922991 var extra_i: usize = extra.end;
2993 const outputs = @bitCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.outputs_len]);
2992 const outputs = @ptrCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.outputs_len]);
29942993 extra_i += outputs.len;
2995 const inputs = @bitCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.inputs_len]);
2994 const inputs = @ptrCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.inputs_len]);
29962995 extra_i += inputs.len;
29972996
29982997 if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none;
......@@ -3860,7 +3859,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
38603859 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
38613860 const vector_ty = f.air.getRefType(ty_pl.ty);
38623861 const len = vector_ty.vectorLen();
3863 const elements = @bitCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
3862 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
38643863
38653864 const writer = f.object.writer();
38663865 const local = try f.allocLocal(inst_ty, .Const);
src/codegen/llvm.zig+5-5
......@@ -3657,7 +3657,7 @@ pub const FuncGen = struct {
36573657 fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*const llvm.Value {
36583658 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
36593659 const extra = self.air.extraData(Air.Call, pl_op.payload);
3660 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3660 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
36613661 const callee_ty = self.air.typeOf(pl_op.operand);
36623662 const zig_fn_ty = switch (callee_ty.zigTypeTag()) {
36633663 .Fn => callee_ty,
......@@ -4037,7 +4037,7 @@ pub const FuncGen = struct {
40374037
40384038 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
40394039 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
4040 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
4040 const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
40414041 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
40424042 extra_index = case.end + case.data.items_len + case_body.len;
40434043
......@@ -4538,9 +4538,9 @@ pub const FuncGen = struct {
45384538
45394539 if (!is_volatile and self.liveness.isUnused(inst)) return null;
45404540
4541 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
4541 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
45424542 extra_i += outputs.len;
4543 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
4543 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
45444544 extra_i += inputs.len;
45454545
45464546 if (outputs.len > 1) {
......@@ -6660,7 +6660,7 @@ pub const FuncGen = struct {
66606660 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
66616661 const result_ty = self.air.typeOfIndex(inst);
66626662 const len = @intCast(usize, result_ty.arrayLen());
6663 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
6663 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
66646664 const llvm_result_ty = try self.dg.llvmType(result_ty);
66656665 const target = self.dg.module.getTarget();
66666666
src/link.zig+6-1
......@@ -649,6 +649,11 @@ pub const File = struct {
649649 }
650650 }
651651
652 pub const UpdateDeclExportsError = error{
653 OutOfMemory,
654 AnalysisFail,
655 };
656
652657 /// May be called before or after updateDecl, but must be called after
653658 /// allocateDeclIndexes for any given Decl.
654659 pub fn updateDeclExports(
......@@ -656,7 +661,7 @@ pub const File = struct {
656661 module: *Module,
657662 decl: *Module.Decl,
658663 exports: []const *Module.Export,
659 ) !void {
664 ) UpdateDeclExportsError!void {
660665 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });
661666 assert(decl.has_tv);
662667 switch (base.tag) {
src/link/C.zig+3-2
......@@ -89,8 +89,9 @@ pub fn deinit(self: *C) void {
8989
9090pub fn freeDecl(self: *C, decl: *Module.Decl) void {
9191 const gpa = self.base.allocator;
92 if (self.decl_table.fetchSwapRemove(decl)) |*kv| {
93 kv.value.deinit(gpa);
92 if (self.decl_table.fetchSwapRemove(decl)) |kv| {
93 var decl_block = kv.value;
94 decl_block.deinit(gpa);
9495 }
9596}
9697
src/link/Elf.zig+1-1
......@@ -2482,7 +2482,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
24822482 try self.atom_by_index_table.putNoClobber(self.base.allocator, atom.local_sym_index, atom);
24832483
24842484 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
2485 .none = .{},
2485 .none = {},
24862486 }, .{
24872487 .parent_atom_index = atom.local_sym_index,
24882488 });
src/link/MachO/Object.zig-1
......@@ -625,7 +625,6 @@ pub fn parseDataInCode(self: *Object, allocator: Allocator) !void {
625625 while (true) {
626626 const dice = reader.readStruct(macho.data_in_code_entry) catch |err| switch (err) {
627627 error.EndOfStream => break,
628 else => |e| return e,
629628 };
630629 try self.data_in_code_entries.append(allocator, dice);
631630 }
src/link/MachO/fat.zig-1
......@@ -40,7 +40,6 @@ pub fn getLibraryOffset(reader: anytype, target: std.Target) !u64 {
4040 // fine because we can keep looking for one that might match.
4141 const lib_arch = decodeArch(fat_arch.cputype, false) catch |err| switch (err) {
4242 error.UnsupportedCpuArchitecture => continue,
43 else => |e| return e,
4443 };
4544 if (lib_arch == target.cpu.arch) {
4645 // We have found a matching architecture!
src/link/Plan9.zig+1-1
......@@ -307,7 +307,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
307307 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
308308 .ty = decl.ty,
309309 .val = decl_val,
310 }, &code_buffer, .{ .none = .{} }, .{
310 }, &code_buffer, .{ .none = {} }, .{
311311 .parent_atom_index = @intCast(u32, sym_index),
312312 });
313313 const code = switch (res) {
src/link/Wasm.zig+16-10
......@@ -2551,7 +2551,8 @@ fn emitSymbolTable(self: *Wasm, file: fs.File, arena: Allocator, symbol_table: *
25512551 .iov_base = payload.items.ptr,
25522552 .iov_len = payload.items.len,
25532553 };
2554 try file.writevAll(&.{iovec});
2554 var iovecs = [_]std.os.iovec_const{iovec};
2555 try file.writevAll(&iovecs);
25552556}
25562557
25572558fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {
......@@ -2576,7 +2577,8 @@ fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {
25762577 .iov_base = payload.items.ptr,
25772578 .iov_len = payload.items.len,
25782579 };
2579 try file.writevAll(&.{iovec});
2580 var iovecs = [_]std.os.iovec_const{iovec};
2581 try file.writevAll(&iovecs);
25802582}
25812583
25822584fn getULEB128Size(uint_value: anytype) u32 {
......@@ -2635,12 +2637,14 @@ fn emitCodeRelocations(
26352637 var buf: [5]u8 = undefined;
26362638 leb.writeUnsignedFixed(5, &buf, count);
26372639 try payload.insertSlice(reloc_start, &buf);
2638 const iovec: std.os.iovec_const = .{
2639 .iov_base = payload.items.ptr,
2640 .iov_len = payload.items.len,
2640 var iovecs = [_]std.os.iovec_const{
2641 .{
2642 .iov_base = payload.items.ptr,
2643 .iov_len = payload.items.len,
2644 },
26412645 };
26422646 const header_offset = try reserveCustomSectionHeader(file);
2643 try file.writevAll(&.{iovec});
2647 try file.writevAll(&iovecs);
26442648 const size = @intCast(u32, payload.items.len);
26452649 try writeCustomSectionHeader(file, header_offset, size);
26462650}
......@@ -2694,12 +2698,14 @@ fn emitDataRelocations(
26942698 var buf: [5]u8 = undefined;
26952699 leb.writeUnsignedFixed(5, &buf, count);
26962700 try payload.insertSlice(reloc_start, &buf);
2697 const iovec: std.os.iovec_const = .{
2698 .iov_base = payload.items.ptr,
2699 .iov_len = payload.items.len,
2701 var iovecs = [_]std.os.iovec_const{
2702 .{
2703 .iov_base = payload.items.ptr,
2704 .iov_len = payload.items.len,
2705 },
27002706 };
27012707 const header_offset = try reserveCustomSectionHeader(file);
2702 try file.writevAll(&.{iovec});
2708 try file.writevAll(&iovecs);
27032709 const size = @intCast(u32, payload.items.len);
27042710 try writeCustomSectionHeader(file, header_offset, size);
27052711}
src/print_air.zig+5-5
......@@ -328,7 +328,7 @@ const Writer = struct {
328328 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
329329 const vector_ty = w.air.getRefType(ty_pl.ty);
330330 const len = @intCast(usize, vector_ty.arrayLen());
331 const elements = @bitCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);
331 const elements = @ptrCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);
332332
333333 try s.print("{}, [", .{vector_ty.fmtDebug()});
334334 for (elements) |elem, i| {
......@@ -533,9 +533,9 @@ const Writer = struct {
533533 try s.writeAll(", volatile");
534534 }
535535
536 const outputs = @bitCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.outputs_len]);
536 const outputs = @ptrCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.outputs_len]);
537537 extra_i += outputs.len;
538 const inputs = @bitCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.inputs_len]);
538 const inputs = @ptrCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.inputs_len]);
539539 extra_i += inputs.len;
540540
541541 for (outputs) |output| {
......@@ -604,7 +604,7 @@ const Writer = struct {
604604 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
605605 const pl_op = w.air.instructions.items(.data)[inst].pl_op;
606606 const extra = w.air.extraData(Air.Call, pl_op.payload);
607 const args = @bitCast([]const Air.Inst.Ref, w.air.extra[extra.end..][0..extra.data.args_len]);
607 const args = @ptrCast([]const Air.Inst.Ref, w.air.extra[extra.end..][0..extra.data.args_len]);
608608 try w.writeOperand(s, inst, 0, pl_op.operand);
609609 try s.writeAll(", [");
610610 for (args) |arg, i| {
......@@ -674,7 +674,7 @@ const Writer = struct {
674674
675675 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
676676 const case = w.air.extraData(Air.SwitchBr.Case, extra_index);
677 const items = @bitCast([]const Air.Inst.Ref, w.air.extra[case.end..][0..case.data.items_len]);
677 const items = @ptrCast([]const Air.Inst.Ref, w.air.extra[case.end..][0..case.data.items_len]);
678678 const case_body = w.air.extra[case.end + items.len ..][0..case.data.body_len];
679679 extra_index = case.end + case.data.items_len + case_body.len;
680680
src/stage1/ir.cpp+6
......@@ -23052,6 +23052,12 @@ static Stage1AirInst *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, Stage1ZirI
2305223052 if (type_is_invalid(src_type))
2305323053 return ira->codegen->invalid_inst_gen;
2305423054
23055 // This logic is not quite right; this is just to get stage1 to accept valid code
23056 // we use in the self-hosted compiler.
23057 if (is_slice(dest_type) && is_slice(src_type)) {
23058 return ir_analyze_bit_cast(ira, instruction->base.scope, instruction->base.source_node, ptr, dest_type);
23059 }
23060
2305523061 bool keep_bigger_alignment = true;
2305623062 return ir_analyze_ptr_cast(ira, instruction->base.scope, instruction->base.source_node, ptr,
2305723063 instruction->ptr->source_node, dest_type, dest_type_value->source_node,
src/type.zig+1-1
......@@ -1451,7 +1451,7 @@ pub const Type = extern union {
14511451 var duped_names = Module.ErrorSet.NameMap{};
14521452 try duped_names.ensureTotalCapacity(allocator, names.len);
14531453 for (names) |name| {
1454 duped_names.putAssumeCapacityNoClobber(name, .{});
1454 duped_names.putAssumeCapacityNoClobber(name, {});
14551455 }
14561456 return Tag.error_set_merged.create(allocator, duped_names);
14571457 },
test/behavior/ptrcast.zig+16
......@@ -217,3 +217,19 @@ test "implicit optional pointer to optional anyopaque pointer" {
217217 var z = @ptrCast(*[4]u8, y);
218218 try expect(std.mem.eql(u8, z, "aoeu"));
219219}
220
221test "@ptrCast slice to slice" {
222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
224
225 const S = struct {
226 fn foo(slice: []u32) []i32 {
227 return @ptrCast([]i32, slice);
228 }
229 };
230 var buf: [4]u32 = .{ 0, 0, 0, 0 };
231 const alias = S.foo(&buf);
232 alias[1] = 42;
233 try expect(buf[1] == 42);
234 try expect(alias.len == 4);
235}