| ... | ... | @@ -741,6 +741,7 @@ const DocData = struct { |
| 741 | 741 | null: struct {}, |
| 742 | 742 | undefined: struct {}, |
| 743 | 743 | @"struct": []FieldVal, |
| 744 | fieldVal: FieldVal, |
| 744 | 745 | bool: bool, |
| 745 | 746 | @"anytype": struct {}, |
| 746 | 747 | @"&": usize, // index in `exprs` |
| ... | ... | @@ -867,7 +868,10 @@ const DocData = struct { |
| 867 | 868 | |
| 868 | 869 | const FieldVal = struct { |
| 869 | 870 | name: []const u8, |
| 870 | | val: WalkResult, |
| 871 | val: struct { |
| 872 | typeRef: ?usize, // index in `exprs` |
| 873 | expr: usize, // index in `exprs` |
| 874 | }, |
| 871 | 875 | }; |
| 872 | 876 | |
| 873 | 877 | const ElemVal = struct { |
| ... | ... | @@ -921,8 +925,8 @@ const DocData = struct { |
| 921 | 925 | /// Since the type information is only needed in certain contexts, the |
| 922 | 926 | /// underlying normalized data (Expr) is untyped. |
| 923 | 927 | const WalkResult = struct { |
| 924 | | typeRef: ?Expr = null, // index in `exprs` |
| 925 | | expr: Expr, // index in `exprs` |
| 928 | typeRef: ?Expr = null, |
| 929 | expr: Expr, |
| 926 | 930 | }; |
| 927 | 931 | }; |
| 928 | 932 | |
| ... | ... | @@ -2874,7 +2878,20 @@ fn walkInstruction( |
| 2874 | 2878 | need_type, |
| 2875 | 2879 | call_ctx, |
| 2876 | 2880 | ); |
| 2877 | | fv.* = .{ .name = field_name, .val = value }; |
| 2881 | const exprIdx = self.exprs.items.len; |
| 2882 | try self.exprs.append(self.arena, value.expr); |
| 2883 | var typeRefIdx: ?usize = null; |
| 2884 | if (value.typeRef) |ref| { |
| 2885 | typeRefIdx = self.exprs.items.len; |
| 2886 | try self.exprs.append(self.arena, ref); |
| 2887 | } |
| 2888 | fv.* = .{ |
| 2889 | .name = field_name, |
| 2890 | .val = .{ |
| 2891 | .typeRef = typeRefIdx, |
| 2892 | .expr = exprIdx, |
| 2893 | }, |
| 2894 | }; |
| 2878 | 2895 | } |
| 2879 | 2896 | |
| 2880 | 2897 | return DocData.WalkResult{ |
| ... | ... | @@ -2942,7 +2959,23 @@ fn walkInstruction( |
| 2942 | 2959 | need_type, |
| 2943 | 2960 | call_ctx, |
| 2944 | 2961 | ); |
| 2945 | | fv.* = .{ .name = field_name, .val = value }; |
| 2962 | |
| 2963 | const exprIdx = self.exprs.items.len; |
| 2964 | try self.exprs.append(self.arena, value.expr); |
| 2965 | var typeRefIdx: ?usize = null; |
| 2966 | if (value.typeRef) |ref| { |
| 2967 | typeRefIdx = self.exprs.items.len; |
| 2968 | try self.exprs.append(self.arena, ref); |
| 2969 | } |
| 2970 | |
| 2971 | fv.* = .{ |
| 2972 | .name = field_name, |
| 2973 | .val = .{ |
| 2974 | .typeRef = typeRefIdx, |
| 2975 | .expr = exprIdx, |
| 2976 | }, |
| 2977 | }; |
| 2978 | |
| 2946 | 2979 | idx = init_extra.end; |
| 2947 | 2980 | } |
| 2948 | 2981 | |
| ... | ... | @@ -3085,6 +3118,75 @@ fn walkInstruction( |
| 3085 | 3118 | .expr = .{ .call = call_slot_index }, |
| 3086 | 3119 | }; |
| 3087 | 3120 | }, |
| 3121 | .field_call => { |
| 3122 | const pl_node = data[@intFromEnum(inst)].pl_node; |
| 3123 | const extra = file.zir.extraData(Zir.Inst.FieldCall, pl_node.payload_index); |
| 3124 | |
| 3125 | const obj_ptr = try self.walkRef( |
| 3126 | file, |
| 3127 | parent_scope, |
| 3128 | parent_src, |
| 3129 | extra.data.obj_ptr, |
| 3130 | need_type, |
| 3131 | call_ctx, |
| 3132 | ); |
| 3133 | |
| 3134 | var field_call = try self.arena.alloc(DocData.Expr, 2); |
| 3135 | |
| 3136 | if (obj_ptr.typeRef) |ref| { |
| 3137 | field_call[0] = ref; |
| 3138 | } else { |
| 3139 | field_call[0] = obj_ptr.expr; |
| 3140 | } |
| 3141 | field_call[1] = .{ .declName = file.zir.nullTerminatedString(extra.data.field_name_start) }; |
| 3142 | try self.tryResolveRefPath(file, inst, field_call); |
| 3143 | |
| 3144 | const args_len = extra.data.flags.args_len; |
| 3145 | var args = try self.arena.alloc(DocData.Expr, args_len); |
| 3146 | const body = file.zir.extra[extra.end..]; |
| 3147 | |
| 3148 | try self.repurposed_insts.put(self.arena, inst, {}); |
| 3149 | defer _ = self.repurposed_insts.remove(inst); |
| 3150 | |
| 3151 | var i: usize = 0; |
| 3152 | while (i < args_len) : (i += 1) { |
| 3153 | const arg_end = file.zir.extra[extra.end + i]; |
| 3154 | const break_index = body[arg_end - 1]; |
| 3155 | const ref = data[break_index].@"break".operand; |
| 3156 | // TODO: consider toggling need_type to true if we ever want |
| 3157 | // to show discrepancies between the types of provided |
| 3158 | // arguments and the types declared in the function |
| 3159 | // signature for its parameters. |
| 3160 | const wr = try self.walkRef( |
| 3161 | file, |
| 3162 | parent_scope, |
| 3163 | parent_src, |
| 3164 | ref, |
| 3165 | false, |
| 3166 | &.{ |
| 3167 | .inst = inst, |
| 3168 | .prev = call_ctx, |
| 3169 | }, |
| 3170 | ); |
| 3171 | args[i] = wr.expr; |
| 3172 | } |
| 3173 | |
| 3174 | const cte_slot_index = self.comptime_exprs.items.len; |
| 3175 | try self.comptime_exprs.append(self.arena, .{ |
| 3176 | .code = "field call", |
| 3177 | }); |
| 3178 | |
| 3179 | const call_slot_index = self.calls.items.len; |
| 3180 | try self.calls.append(self.arena, .{ |
| 3181 | .func = .{ .refPath = field_call }, |
| 3182 | .args = args, |
| 3183 | .ret = .{ .comptimeExpr = cte_slot_index }, |
| 3184 | }); |
| 3185 | |
| 3186 | return DocData.WalkResult{ |
| 3187 | .expr = .{ .call = call_slot_index }, |
| 3188 | }; |
| 3189 | }, |
| 3088 | 3190 | .func, .func_inferred => { |
| 3089 | 3191 | const type_slot_index = self.types.items.len; |
| 3090 | 3192 | try self.types.append(self.arena, .{ .Unanalyzed = .{} }); |
| ... | ... | @@ -4374,6 +4476,9 @@ fn tryResolveRefPath( |
| 4374 | 4476 | }, |
| 4375 | 4477 | } |
| 4376 | 4478 | }, |
| 4479 | .fieldVal => |fv| { |
| 4480 | resolved_parent = self.exprs.items[fv.val.expr]; |
| 4481 | }, |
| 4377 | 4482 | } |
| 4378 | 4483 | } else { |
| 4379 | 4484 | panicWithContext( |
| ... | ... | @@ -4675,7 +4780,7 @@ fn tryResolveRefPath( |
| 4675 | 4780 | .@"struct" => |st| { |
| 4676 | 4781 | for (st) |field| { |
| 4677 | 4782 | if (std.mem.eql(u8, field.name, child_string)) { |
| 4678 | | path[i + 1] = field.val.expr; |
| 4783 | path[i + 1] = .{ .fieldVal = field }; |
| 4679 | 4784 | continue :outer; |
| 4680 | 4785 | } |
| 4681 | 4786 | } |