| ... | @@ -13154,9 +13154,59 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13154,9 +13154,59 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13154 | } | 13154 | } |
| 13155 | | 13155 | |
| 13156 | fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 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 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 13160 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 13158 | const src = inst_data.src(); | 13161 | const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 13159 | return sema.fail(block, src, "TODO: Sema.zirBuiltinCall", .{}); | 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 | fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13212 | fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -14684,10 +14734,8 @@ fn tupleFieldVal( | ... | @@ -14684,10 +14734,8 @@ fn tupleFieldVal( |
| 14684 | field_name_src: LazySrcLoc, | 14734 | field_name_src: LazySrcLoc, |
| 14685 | tuple_ty: Type, | 14735 | tuple_ty: Type, |
| 14686 | ) CompileError!Air.Inst.Ref { | 14736 | ) CompileError!Air.Inst.Ref { |
| 14687 | const tuple = tuple_ty.castTag(.tuple).?.data; | | |
| 14688 | | | |
| 14689 | if (mem.eql(u8, field_name, "len")) { | 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 | const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| { | 14741 | const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| { |
| ... | @@ -14695,7 +14743,18 @@ fn tupleFieldVal( | ... | @@ -14695,7 +14743,18 @@ fn tupleFieldVal( |
| 14695 | tuple_ty, field_name, @errorName(err), | 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 | const field_ty = tuple.types[field_index]; | 14758 | const field_ty = tuple.types[field_index]; |
| 14700 | | 14759 | |
| 14701 | if (tuple.values[field_index].tag() != .unreachable_value) { | 14760 | if (tuple.values[field_index].tag() != .unreachable_value) { |