diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4b79274ee5..0ec1a24939 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4356,7 +4356,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const ip = &zcu.intern_pool; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); - const args = sema.code.refSlice(extra.end, extra.data.operands_len); + const all_args = sema.code.refSlice(extra.end, extra.data.operands_len); + const arg_pairs: []const [2]Zir.Inst.Ref = @as([*]const [2]Zir.Inst.Ref, @ptrCast(all_args))[0..@divExact(all_args.len, 2)]; const src = block.nodeOffset(inst_data.src_node); var len: Air.Inst.Ref = .none; @@ -4364,27 +4365,24 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. var len_idx: u32 = undefined; var any_runtime = false; - const runtime_arg_lens = try gpa.alloc(Air.Inst.Ref, args.len); + const runtime_arg_lens = try gpa.alloc(Air.Inst.Ref, arg_pairs.len); defer gpa.free(runtime_arg_lens); // First pass to look for comptime values. - for (args, 0..) |zir_arg, i_usize| { + for (arg_pairs, 0..) |zir_arg_pair, i_usize| { const i: u32 = @intCast(i_usize); runtime_arg_lens[i] = .none; - if (zir_arg == .none) continue; - const object = try sema.resolveInst(zir_arg); - const object_ty = sema.typeOf(object); - // Each arg could be an indexable, or a range, in which case the length - // is passed directly as an integer. - const is_int = switch (object_ty.zigTypeTag(zcu)) { - .int, .comptime_int => true, - else => false, - }; + if (zir_arg_pair[0] == .none) continue; + const arg_src = block.src(.{ .for_input = .{ .for_node_offset = inst_data.src_node, .input_index = i, } }); - const arg_len_uncoerced = if (is_int) object else l: { + + const arg_len_uncoerced = if (zir_arg_pair[1] == .none) l: { + // This argument is an indexable. + const object = try sema.resolveInst(zir_arg_pair[0]); + const object_ty = sema.typeOf(object); if (!object_ty.isIndexable(zcu)) { // Instead of using checkIndexable we customize this error. const msg = msg: { @@ -4401,8 +4399,12 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. return sema.failWithOwnedErrorMsg(block, msg); } if (!object_ty.indexableHasLen(zcu)) continue; - break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), arg_src); + } else l: { + // This argument is a range. + const range_start = try sema.resolveInst(zir_arg_pair[0]); + const range_end = try sema.resolveInst(zir_arg_pair[1]); + break :l try sema.analyzeArithmetic(block, .sub, range_end, range_start, arg_src, arg_src, arg_src, true); }; const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src); if (len == .none) { @@ -4444,17 +4446,12 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const msg = msg: { const msg = try sema.errMsg(src, "unbounded for loop", .{}); errdefer msg.destroy(gpa); - for (args, 0..) |zir_arg, i_usize| { + for (arg_pairs, 0..) |zir_arg_pair, i_usize| { const i: u32 = @intCast(i_usize); - if (zir_arg == .none) continue; - const object = try sema.resolveInst(zir_arg); + if (zir_arg_pair[0] == .none) continue; + if (zir_arg_pair[1] != .none) continue; + const object = try sema.resolveInst(zir_arg_pair[0]); const object_ty = sema.typeOf(object); - // Each arg could be an indexable, or a range, in which case the length - // is passed directly as an integer. - switch (object_ty.zigTypeTag(zcu)) { - .int, .comptime_int => continue, - else => {}, - } const arg_src = block.src(.{ .for_input = .{ .for_node_offset = inst_data.src_node, .input_index = i, |
