| ... | ... | @@ -13154,9 +13154,59 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13154 | 13154 | } |
| 13155 | 13155 | |
| 13156 | 13156 | fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13157 | const tracy = trace(@src()); |
| 13158 | defer tracy.end(); |
| 13159 | |
| 13157 | 13160 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 13158 | | const src = inst_data.src(); |
| 13159 | | return sema.fail(block, src, "TODO: Sema.zirBuiltinCall", .{}); |
| 13161 | const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 13162 | const func_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 13163 | const args_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| 13164 | const call_src = inst_data.src(); |
| 13165 | |
| 13166 | const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index); |
| 13167 | var func = sema.resolveInst(extra.data.callee); |
| 13168 | const options = sema.resolveInst(extra.data.options); |
| 13169 | const args = sema.resolveInst(extra.data.args); |
| 13170 | |
| 13171 | const modifier: std.builtin.CallOptions.Modifier = modifier: { |
| 13172 | const export_options_ty = try sema.getBuiltinType(block, options_src, "CallOptions"); |
| 13173 | const coerced_options = try sema.coerce(block, export_options_ty, options, options_src); |
| 13174 | const options_val = try sema.resolveConstValue(block, options_src, coerced_options); |
| 13175 | const fields = options_val.castTag(.@"struct").?.data; |
| 13176 | const struct_obj = export_options_ty.castTag(.@"struct").?.data; |
| 13177 | const modifier_index = struct_obj.fields.getIndex("modifier").?; |
| 13178 | const stack_index = struct_obj.fields.getIndex("stack").?; |
| 13179 | if (!fields[stack_index].isNull()) { |
| 13180 | return sema.fail(block, options_src, "TODO: implement @call with stack", .{}); |
| 13181 | } |
| 13182 | break :modifier fields[modifier_index].toEnum(std.builtin.CallOptions.Modifier); |
| 13183 | }; |
| 13184 | |
| 13185 | const args_ty = sema.typeOf(args); |
| 13186 | if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) { |
| 13187 | return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty}); |
| 13188 | } |
| 13189 | |
| 13190 | var resolved_args: []Air.Inst.Ref = undefined; |
| 13191 | |
| 13192 | // Desugar bound functions here |
| 13193 | if (sema.typeOf(func).tag() == .bound_fn) { |
| 13194 | const bound_func = try sema.resolveValue(block, func_src, func); |
| 13195 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 13196 | func = bound_data.func_inst; |
| 13197 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1); |
| 13198 | resolved_args[0] = bound_data.arg0_inst; |
| 13199 | for (resolved_args[1..]) |*resolved, i| { |
| 13200 | resolved.* = try sema.tupleFieldValByIndex(block, args_src, args, @intCast(u32, i), args_ty); |
| 13201 | } |
| 13202 | } else { |
| 13203 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount()); |
| 13204 | for (resolved_args) |*resolved, i| { |
| 13205 | resolved.* = try sema.tupleFieldValByIndex(block, args_src, args, @intCast(u32, i), args_ty); |
| 13206 | } |
| 13207 | } |
| 13208 | |
| 13209 | return sema.analyzeCall(block, func, func_src, call_src, modifier, false, resolved_args); |
| 13160 | 13210 | } |
| 13161 | 13211 | |
| 13162 | 13212 | fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -14684,10 +14734,8 @@ fn tupleFieldVal( |
| 14684 | 14734 | field_name_src: LazySrcLoc, |
| 14685 | 14735 | tuple_ty: Type, |
| 14686 | 14736 | ) CompileError!Air.Inst.Ref { |
| 14687 | | const tuple = tuple_ty.castTag(.tuple).?.data; |
| 14688 | | |
| 14689 | 14737 | if (mem.eql(u8, field_name, "len")) { |
| 14690 | | return sema.addIntUnsigned(Type.usize, tuple.types.len); |
| 14738 | return sema.addIntUnsigned(Type.usize, tuple_ty.structFieldCount()); |
| 14691 | 14739 | } |
| 14692 | 14740 | |
| 14693 | 14741 | const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| { |
| ... | ... | @@ -14695,7 +14743,18 @@ fn tupleFieldVal( |
| 14695 | 14743 | tuple_ty, field_name, @errorName(err), |
| 14696 | 14744 | }); |
| 14697 | 14745 | }; |
| 14746 | return tupleFieldValByIndex(sema, block, src, tuple_byval, field_index, tuple_ty); |
| 14747 | } |
| 14698 | 14748 | |
| 14749 | fn tupleFieldValByIndex( |
| 14750 | sema: *Sema, |
| 14751 | block: *Block, |
| 14752 | src: LazySrcLoc, |
| 14753 | tuple_byval: Air.Inst.Ref, |
| 14754 | field_index: u32, |
| 14755 | tuple_ty: Type, |
| 14756 | ) CompileError!Air.Inst.Ref { |
| 14757 | const tuple = tuple_ty.castTag(.tuple).?.data; |
| 14699 | 14758 | const field_ty = tuple.types[field_index]; |
| 14700 | 14759 | |
| 14701 | 14760 | if (tuple.values[field_index].tag() != .unreachable_value) { |