authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-28 09:59:30+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-28 13:09:14-07:00
log3a65fa269f476ecb9dafd8be77ee9f9c0c4ba996
treec658188c6b6119c733c1378cc6e0676853e7c608
parente1375942e584d4fffd3ecd06277ced7cf35d7e6c

stage2: slice mul/cat


1 files changed, 21 insertions(+), 10 deletions(-)

src/Sema.zig+21-10
......@@ -8072,9 +8072,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
80728072 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
80738073 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
80748074
8075 const lhs_info = getArrayCatInfo(lhs_ty) orelse
8075 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
80768076 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty});
8077 const rhs_info = getArrayCatInfo(rhs_ty) orelse
8077 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse
80788078 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty});
80798079 if (!lhs_info.elem_type.eql(rhs_info.elem_type)) {
80808080 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty });
......@@ -8095,9 +8095,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
80958095 const rhs_len = try sema.usizeCast(block, lhs_src, rhs_info.len);
80968096 const final_len = lhs_len + rhs_len;
80978097 const final_len_including_sent = final_len + @boolToInt(res_sent != null);
8098 const is_pointer = lhs_ty.zigTypeTag() == .Pointer;
8099 const lhs_sub_val = if (is_pointer) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val;
8100 const rhs_sub_val = if (is_pointer) (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).? else rhs_val;
8098 const lhs_single_ptr = lhs_ty.zigTypeTag() == .Pointer and !lhs_ty.isSlice();
8099 const rhs_single_ptr = rhs_ty.zigTypeTag() == .Pointer and !rhs_ty.isSlice();
8100 const lhs_sub_val = if (lhs_single_ptr) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val;
8101 const rhs_sub_val = if (rhs_single_ptr) (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).? else rhs_val;
81018102 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);
81028103 defer anon_decl.deinit();
81038104
......@@ -8129,7 +8130,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
81298130 });
81308131 const val = try Value.Tag.array.create(anon_decl.arena(), buf);
81318132 const decl = try anon_decl.finish(ty, val);
8132 if (is_pointer) {
8133 if (lhs_single_ptr or rhs_single_ptr) {
81338134 return sema.analyzeDeclRef(decl);
81348135 } else {
81358136 return sema.analyzeDeclVal(block, .unneeded, decl);
......@@ -8142,11 +8143,20 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
81428143 }
81438144}
81448145
8145fn getArrayCatInfo(t: Type) ?Type.ArrayInfo {
8146fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {
8147 const t = sema.typeOf(inst);
81468148 return switch (t.zigTypeTag()) {
81478149 .Array => t.arrayInfo(),
81488150 .Pointer => blk: {
81498151 const ptrinfo = t.ptrInfo().data;
8152 if (ptrinfo.size == .Slice) {
8153 const val = try sema.resolveConstValue(block, src, inst);
8154 return Type.ArrayInfo{
8155 .elem_type = t.childType(),
8156 .sentinel = t.sentinel(),
8157 .len = val.sliceLen(),
8158 };
8159 }
81508160 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;
81518161 if (ptrinfo.size != .One) return null;
81528162 break :blk ptrinfo.pointee_type.arrayInfo();
......@@ -8169,7 +8179,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
81698179
81708180 // In `**` rhs has to be comptime-known, but lhs can be runtime-known
81718181 const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize);
8172 const mulinfo = getArrayCatInfo(lhs_ty) orelse
8182 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
81738183 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty});
81748184
81758185 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch
......@@ -8180,7 +8190,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
81808190 const final_len_including_sent = final_len + @boolToInt(mulinfo.sentinel != null);
81818191 const lhs_len = try sema.usizeCast(block, lhs_src, mulinfo.len);
81828192
8183 const lhs_sub_val = if (lhs_ty.zigTypeTag() == .Pointer) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val;
8193 const is_single_ptr = lhs_ty.zigTypeTag() == .Pointer and !lhs_ty.isSlice();
8194 const lhs_sub_val = if (is_single_ptr) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val;
81848195
81858196 var anon_decl = try block.startAnonDecl(src);
81868197 defer anon_decl.deinit();
......@@ -8220,7 +8231,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
82208231 break :blk try Value.Tag.array.create(anon_decl.arena(), buf);
82218232 };
82228233 const decl = try anon_decl.finish(final_ty, val);
8223 if (lhs_ty.zigTypeTag() == .Pointer) {
8234 if (is_single_ptr) {
82248235 return sema.analyzeDeclRef(decl);
82258236 } else {
82268237 return sema.analyzeDeclVal(block, .unneeded, decl);