From cd32b11eb8d33225a1a2bc3bc9e0755936a39ade Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 8 Mar 2022 11:53:43 -0800 Subject: [PATCH 1/2] stage2: inferred alloc can use bitcast ty The comment notes that we can't because of constness, but the recent work by @Vexu lets us use the bitcast ty cause constness comes later. The following tests pass from this: ``` test "A" { const ary = [_:0]u8{42}; const ptr: [*:0]const u8 = &ary; try expect(ptr[1] == 0); } test "B" { comptime { const ary = [_:0]u8{42}; const ptr: [*:0]const u8 = &ary; try expect(ptr[1] == 0); } } ``` --- src/Sema.zig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 249e3be34d..a9de064e85 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2623,10 +2623,9 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com // block so that codegen does not see it. block.instructions.shrinkRetainingCapacity(block.instructions.items.len - 3); sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, new_decl); - // Would be nice if we could just assign `bitcast_ty_ref` to - // `air_datas[ptr_inst].ty_pl.ty`, wouldn't it? Alas, that is almost correct, - // except that the pointer is mutable and we need to make it constant here. - air_datas[ptr_inst].ty_pl.ty = try sema.addType(final_ptr_ty); + // if bitcast ty ref needs to be made const, make_ptr_const + // ZIR handles it later, so we can just use the ty ref here. + air_datas[ptr_inst].ty_pl.ty = air_datas[bitcast_inst].ty_op.ty; return; } From ba62853d26f6a3388a7ad099a1d9091d7eca45c9 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 8 Mar 2022 12:05:12 -0800 Subject: [PATCH 2/2] stage2: sentinel array init must add sentinel to array value I didn't realize that the `array` value type has the sentinel on it. --- src/Sema.zig | 15 +++++---------- test/behavior/pointers.zig | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index a9de064e85..85c2922d74 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -11827,21 +11827,16 @@ fn zirArrayInit( }); }; - const elems = if (!is_sent) - resolved_args - else - resolved_args[0 .. resolved_args.len - 1]; - - const opt_runtime_src: ?LazySrcLoc = for (elems) |arg| { + const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |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, elems.len); + const elem_vals = try sema.arena.alloc(Value, resolved_args.len); - for (elems) |arg, i| { + for (resolved_args) |arg, i| { // We checked that all args are comptime above. elem_vals[i] = (sema.resolveMaybeUndefVal(block, src, arg) catch unreachable).?; } @@ -11868,7 +11863,7 @@ fn zirArrayInit( }); const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); - for (elems) |arg, i| { + for (resolved_args) |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); @@ -11876,7 +11871,7 @@ fn zirArrayInit( return alloc; } - return block.addAggregateInit(array_ty, elems); + return block.addAggregateInit(array_ty, resolved_args); } fn zirArrayInitAnon( diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index c3d4220742..74089611db 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -317,7 +317,11 @@ test "allow any sentinel" { } test "pointer sentinel with enums" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO const S = struct { const Number = enum { @@ -336,7 +340,11 @@ test "pointer sentinel with enums" { } test "pointer sentinel with optional element" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -349,7 +357,11 @@ test "pointer sentinel with optional element" { } test "pointer sentinel with +inf" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void {