| author | |
| committer | |
| log | 354c17869a4fb1053d472d6562f4987fbaca143e |
| tree | 93c7d156a0a3b23842e19b6f7fec7bf3a129d3f8 |
| parent | 3bd62e1bb62f4f490aeaa68c3cbf9c6c09c40726 |
with field_ptr_load and field_ptr_named_load.
These avoid doing by-val load operations for structs that are
runtime-known while keeping the previous semantics for comptime-known
values.4 files changed, 77 insertions(+), 40 deletions(-)
lib/std/zig/AstGen.zig+17-13| ... | @@ -2731,9 +2731,9 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2731,9 +2731,9 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2731 | .elem_val_node, | 2731 | .elem_val_node, |
| 2732 | .elem_val_imm, | 2732 | .elem_val_imm, |
| 2733 | .field_ptr, | 2733 | .field_ptr, |
| 2734 | .field_val, | 2734 | .field_ptr_load, |
| 2735 | .field_ptr_named, | 2735 | .field_ptr_named, |
| 2736 | .field_val_named, | 2736 | .field_ptr_named_load, |
| 2737 | .func, | 2737 | .func, |
| 2738 | .func_inferred, | 2738 | .func_inferred, |
| 2739 | .func_fancy, | 2739 | .func_fancy, |
| ... | @@ -6160,7 +6160,7 @@ fn fieldAccess( | ... | @@ -6160,7 +6160,7 @@ fn fieldAccess( |
| 6160 | switch (ri.rl) { | 6160 | switch (ri.rl) { |
| 6161 | .ref, .ref_coerced_ty => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .ref }, node), | 6161 | .ref, .ref_coerced_ty => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .ref }, node), |
| 6162 | else => { | 6162 | else => { |
| 6163 | const access = try addFieldAccess(.field_val, gz, scope, .{ .rl = .none }, node); | 6163 | const access = try addFieldAccess(.field_ptr_load, gz, scope, .{ .rl = .ref }, node); |
| 6164 | return rvalue(gz, ri, access, node); | 6164 | return rvalue(gz, ri, access, node); |
| 6165 | }, | 6165 | }, |
| 6166 | } | 6166 | } |
| ... | @@ -9286,17 +9286,21 @@ fn builtinCall( | ... | @@ -9286,17 +9286,21 @@ fn builtinCall( |
| 9286 | return rvalue(gz, ri, result, node); | 9286 | return rvalue(gz, ri, result, node); |
| 9287 | }, | 9287 | }, |
| 9288 | .field => { | 9288 | .field => { |
| 9289 | if (ri.rl == .ref or ri.rl == .ref_coerced_ty) { | 9289 | switch (ri.rl) { |
| 9290 | return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{ | 9290 | .ref, .ref_coerced_ty => { |
| 9291 | .lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]), | 9291 | return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{ |
| 9292 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name), | 9292 | .lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]), |
| 9293 | }); | 9293 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name), |
| 9294 | }); | ||
| 9295 | }, | ||
| 9296 | else => { | ||
| 9297 | const result = try gz.addPlNode(.field_ptr_named_load, node, Zir.Inst.FieldNamed{ | ||
| 9298 | .lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]), | ||
| 9299 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name), | ||
| 9300 | }); | ||
| 9301 | return rvalue(gz, ri, result, node); | ||
| 9302 | }, | ||
| 9294 | } | 9303 | } |
| 9295 | const result = try gz.addPlNode(.field_val_named, node, Zir.Inst.FieldNamed{ | ||
| 9296 | .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), | ||
| 9297 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name), | ||
| 9298 | }); | ||
| 9299 | return rvalue(gz, ri, result, node); | ||
| 9300 | }, | 9304 | }, |
| 9301 | .FieldType => { | 9305 | .FieldType => { |
| 9302 | const ty_inst = try typeExpr(gz, scope, params[0]); | 9306 | const ty_inst = try typeExpr(gz, scope, params[0]); |
lib/std/zig/Zir.zig+20-12| ... | @@ -420,6 +420,7 @@ pub const Inst = struct { | ... | @@ -420,6 +420,7 @@ pub const Inst = struct { |
| 420 | /// is the local's value. | 420 | /// is the local's value. |
| 421 | dbg_var_val, | 421 | dbg_var_val, |
| 422 | /// Uses a name to identify a Decl and takes a pointer to it. | 422 | /// Uses a name to identify a Decl and takes a pointer to it. |
| 423 | /// | ||
| 423 | /// Uses the `str_tok` union field. | 424 | /// Uses the `str_tok` union field. |
| 424 | decl_ref, | 425 | decl_ref, |
| 425 | /// Uses a name to identify a Decl and uses it as a value. | 426 | /// Uses a name to identify a Decl and uses it as a value. |
| ... | @@ -472,19 +473,26 @@ pub const Inst = struct { | ... | @@ -472,19 +473,26 @@ pub const Inst = struct { |
| 472 | /// to the named field. The field name is stored in string_bytes. Used by a.b syntax. | 473 | /// to the named field. The field name is stored in string_bytes. Used by a.b syntax. |
| 473 | /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field. | 474 | /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field. |
| 474 | field_ptr, | 475 | field_ptr, |
| 475 | /// Given a struct or object that contains virtual fields, returns the named field. | 476 | /// Given a pointer to a struct or object that contains virtual fields, loads from the |
| 477 | /// named field. | ||
| 478 | /// | ||
| 476 | /// The field name is stored in string_bytes. Used by a.b syntax. | 479 | /// The field name is stored in string_bytes. Used by a.b syntax. |
| 480 | /// | ||
| 477 | /// This instruction also accepts a pointer. | 481 | /// This instruction also accepts a pointer. |
| 482 | /// | ||
| 478 | /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field. | 483 | /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field. |
| 479 | field_val, | 484 | field_ptr_load, |
| 480 | /// Given a pointer to a struct or object that contains virtual fields, returns a pointer | 485 | /// Given a pointer to a struct or object that contains virtual fields, returns a pointer |
| 481 | /// to the named field. The field name is a comptime instruction. Used by @field. | 486 | /// to the named field. The field name is a comptime instruction. Used by @field. |
| 482 | /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed. | 487 | /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed. |
| 483 | field_ptr_named, | 488 | field_ptr_named, |
| 484 | /// Given a struct or object that contains virtual fields, returns the named field. | 489 | /// Given a pointer to a struct or object that contains virtual fields, |
| 490 | /// loads from the named field. | ||
| 491 | /// | ||
| 485 | /// The field name is a comptime instruction. Used by @field. | 492 | /// The field name is a comptime instruction. Used by @field. |
| 493 | /// | ||
| 486 | /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed. | 494 | /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed. |
| 487 | field_val_named, | 495 | field_ptr_named_load, |
| 488 | /// Returns a function type, or a function instance, depending on whether | 496 | /// Returns a function type, or a function instance, depending on whether |
| 489 | /// the body_len is 0. Calling convention is auto. | 497 | /// the body_len is 0. Calling convention is auto. |
| 490 | /// Uses the `pl_node` union field. `payload_index` points to a `Func`. | 498 | /// Uses the `pl_node` union field. `payload_index` points to a `Func`. |
| ... | @@ -1145,9 +1153,9 @@ pub const Inst = struct { | ... | @@ -1145,9 +1153,9 @@ pub const Inst = struct { |
| 1145 | .ensure_err_union_payload_void, | 1153 | .ensure_err_union_payload_void, |
| 1146 | .@"export", | 1154 | .@"export", |
| 1147 | .field_ptr, | 1155 | .field_ptr, |
| 1148 | .field_val, | 1156 | .field_ptr_load, |
| 1149 | .field_ptr_named, | 1157 | .field_ptr_named, |
| 1150 | .field_val_named, | 1158 | .field_ptr_named_load, |
| 1151 | .func, | 1159 | .func, |
| 1152 | .func_inferred, | 1160 | .func_inferred, |
| 1153 | .func_fancy, | 1161 | .func_fancy, |
| ... | @@ -1435,9 +1443,9 @@ pub const Inst = struct { | ... | @@ -1435,9 +1443,9 @@ pub const Inst = struct { |
| 1435 | .elem_val_node, | 1443 | .elem_val_node, |
| 1436 | .elem_val_imm, | 1444 | .elem_val_imm, |
| 1437 | .field_ptr, | 1445 | .field_ptr, |
| 1438 | .field_val, | 1446 | .field_ptr_load, |
| 1439 | .field_ptr_named, | 1447 | .field_ptr_named, |
| 1440 | .field_val_named, | 1448 | .field_ptr_named_load, |
| 1441 | .func, | 1449 | .func, |
| 1442 | .func_inferred, | 1450 | .func_inferred, |
| 1443 | .func_fancy, | 1451 | .func_fancy, |
| ... | @@ -1688,9 +1696,9 @@ pub const Inst = struct { | ... | @@ -1688,9 +1696,9 @@ pub const Inst = struct { |
| 1688 | .error_value = .str_tok, | 1696 | .error_value = .str_tok, |
| 1689 | .@"export" = .pl_node, | 1697 | .@"export" = .pl_node, |
| 1690 | .field_ptr = .pl_node, | 1698 | .field_ptr = .pl_node, |
| 1691 | .field_val = .pl_node, | 1699 | .field_ptr_load = .pl_node, |
| 1692 | .field_ptr_named = .pl_node, | 1700 | .field_ptr_named = .pl_node, |
| 1693 | .field_val_named = .pl_node, | 1701 | .field_ptr_named_load = .pl_node, |
| 1694 | .func = .pl_node, | 1702 | .func = .pl_node, |
| 1695 | .func_inferred = .pl_node, | 1703 | .func_inferred = .pl_node, |
| 1696 | .func_fancy = .pl_node, | 1704 | .func_fancy = .pl_node, |
| ... | @@ -4225,9 +4233,9 @@ fn findTrackableInner( | ... | @@ -4225,9 +4233,9 @@ fn findTrackableInner( |
| 4225 | .error_value, | 4233 | .error_value, |
| 4226 | .@"export", | 4234 | .@"export", |
| 4227 | .field_ptr, | 4235 | .field_ptr, |
| 4228 | .field_val, | 4236 | .field_ptr_load, |
| 4229 | .field_ptr_named, | 4237 | .field_ptr_named, |
| 4230 | .field_val_named, | 4238 | .field_ptr_named_load, |
| 4231 | .import, | 4239 | .import, |
| 4232 | .int, | 4240 | .int, |
| 4233 | .int_big, | 4241 | .int_big, |
src/Sema.zig+38-13| ... | @@ -1187,7 +1187,7 @@ fn analyzeBodyInner( | ... | @@ -1187,7 +1187,7 @@ fn analyzeBodyInner( |
| 1187 | .cmp_gte => try sema.zirCmp(block, inst, .gte), | 1187 | .cmp_gte => try sema.zirCmp(block, inst, .gte), |
| 1188 | .cmp_gt => try sema.zirCmp(block, inst, .gt), | 1188 | .cmp_gt => try sema.zirCmp(block, inst, .gt), |
| 1189 | .cmp_neq => try sema.zirCmpEq(block, inst, .neq, Air.Inst.Tag.fromCmpOp(.neq, block.float_mode == .optimized)), | 1189 | .cmp_neq => try sema.zirCmpEq(block, inst, .neq, Air.Inst.Tag.fromCmpOp(.neq, block.float_mode == .optimized)), |
| 1190 | .decl_ref => try sema.zirDeclRef(block, inst), | 1190 | .decl_ref => try sema.zirDeclRef(block, inst, true), |
| 1191 | .decl_val => try sema.zirDeclVal(block, inst), | 1191 | .decl_val => try sema.zirDeclVal(block, inst), |
| 1192 | .load => try sema.zirLoad(block, inst), | 1192 | .load => try sema.zirLoad(block, inst), |
| 1193 | .elem_ptr => try sema.zirElemPtr(block, inst), | 1193 | .elem_ptr => try sema.zirElemPtr(block, inst), |
| ... | @@ -1211,8 +1211,8 @@ fn analyzeBodyInner( | ... | @@ -1211,8 +1211,8 @@ fn analyzeBodyInner( |
| 1211 | .error_value => try sema.zirErrorValue(block, inst), | 1211 | .error_value => try sema.zirErrorValue(block, inst), |
| 1212 | .field_ptr => try sema.zirFieldPtr(block, inst), | 1212 | .field_ptr => try sema.zirFieldPtr(block, inst), |
| 1213 | .field_ptr_named => try sema.zirFieldPtrNamed(block, inst), | 1213 | .field_ptr_named => try sema.zirFieldPtrNamed(block, inst), |
| 1214 | .field_val => try sema.zirFieldVal(block, inst), | 1214 | .field_ptr_load => try sema.zirFieldPtrLoad(block, inst), |
| 1215 | .field_val_named => try sema.zirFieldValNamed(block, inst), | 1215 | .field_ptr_named_load => try sema.zirFieldPtrNamedLoad(block, inst), |
| 1216 | .func => try sema.zirFunc(block, inst, false), | 1216 | .func => try sema.zirFunc(block, inst, false), |
| 1217 | .func_inferred => try sema.zirFunc(block, inst, true), | 1217 | .func_inferred => try sema.zirFunc(block, inst, true), |
| 1218 | .func_fancy => try sema.zirFuncFancy(block, inst), | 1218 | .func_fancy => try sema.zirFuncFancy(block, inst), |
| ... | @@ -6524,7 +6524,7 @@ pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!Air.NullTer | ... | @@ -6524,7 +6524,7 @@ pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!Air.NullTer |
| 6524 | return nts; | 6524 | return nts; |
| 6525 | } | 6525 | } |
| 6526 | 6526 | ||
| 6527 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6527 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index, escape: bool) CompileError!Air.Inst.Ref { |
| 6528 | const pt = sema.pt; | 6528 | const pt = sema.pt; |
| 6529 | const zcu = pt.zcu; | 6529 | const zcu = pt.zcu; |
| 6530 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 6530 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| ... | @@ -6536,7 +6536,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -6536,7 +6536,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6536 | .no_embedded_nulls, | 6536 | .no_embedded_nulls, |
| 6537 | ); | 6537 | ); |
| 6538 | const nav_index = try sema.lookupIdentifier(block, decl_name); | 6538 | const nav_index = try sema.lookupIdentifier(block, decl_name); |
| 6539 | return sema.analyzeNavRef(block, src, nav_index); | 6539 | return sema.analyzeNavRefInner(block, src, nav_index, escape); |
| 6540 | } | 6540 | } |
| 6541 | 6541 | ||
| 6542 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6542 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -9711,7 +9711,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -9711,7 +9711,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 9711 | return block.addBitCast(dest_ty, operand); | 9711 | return block.addBitCast(dest_ty, operand); |
| 9712 | } | 9712 | } |
| 9713 | 9713 | ||
| 9714 | fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 9714 | fn zirFieldPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 9715 | const tracy = trace(@src()); | 9715 | const tracy = trace(@src()); |
| 9716 | defer tracy.end(); | 9716 | defer tracy.end(); |
| 9717 | 9717 | ||
| ... | @@ -9727,8 +9727,8 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -9727,8 +9727,8 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9727 | sema.code.nullTerminatedString(extra.field_name_start), | 9727 | sema.code.nullTerminatedString(extra.field_name_start), |
| 9728 | .no_embedded_nulls, | 9728 | .no_embedded_nulls, |
| 9729 | ); | 9729 | ); |
| 9730 | const object = try sema.resolveInst(extra.lhs); | 9730 | const object_ptr = try sema.resolveInst(extra.lhs); |
| 9731 | return sema.fieldVal(block, src, object, field_name, field_name_src); | 9731 | return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src); |
| 9732 | } | 9732 | } |
| 9733 | 9733 | ||
| 9734 | fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 9734 | fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -9779,7 +9779,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi | ... | @@ -9779,7 +9779,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi |
| 9779 | } | 9779 | } |
| 9780 | } | 9780 | } |
| 9781 | 9781 | ||
| 9782 | fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 9782 | fn zirFieldPtrNamedLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 9783 | const tracy = trace(@src()); | 9783 | const tracy = trace(@src()); |
| 9784 | defer tracy.end(); | 9784 | defer tracy.end(); |
| 9785 | 9785 | ||
| ... | @@ -9787,9 +9787,9 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -9787,9 +9787,9 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 9787 | const src = block.nodeOffset(inst_data.src_node); | 9787 | const src = block.nodeOffset(inst_data.src_node); |
| 9788 | const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1); | 9788 | const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 9789 | const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data; | 9789 | const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data; |
| 9790 | const object = try sema.resolveInst(extra.lhs); | 9790 | const object_ptr = try sema.resolveInst(extra.lhs); |
| 9791 | const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name }); | 9791 | const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name }); |
| 9792 | return sema.fieldVal(block, src, object, field_name, field_name_src); | 9792 | return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src); |
| 9793 | } | 9793 | } |
| 9794 | 9794 | ||
| 9795 | fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 9795 | fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -13612,7 +13612,6 @@ fn maybeErrorUnwrap( | ... | @@ -13612,7 +13612,6 @@ fn maybeErrorUnwrap( |
| 13612 | .str, | 13612 | .str, |
| 13613 | .as_node, | 13613 | .as_node, |
| 13614 | .panic, | 13614 | .panic, |
| 13615 | .field_val, | ||
| 13616 | => {}, | 13615 | => {}, |
| 13617 | else => return false, | 13616 | else => return false, |
| 13618 | } | 13617 | } |
| ... | @@ -13631,7 +13630,6 @@ fn maybeErrorUnwrap( | ... | @@ -13631,7 +13630,6 @@ fn maybeErrorUnwrap( |
| 13631 | }, | 13630 | }, |
| 13632 | .str => try sema.zirStr(inst), | 13631 | .str => try sema.zirStr(inst), |
| 13633 | .as_node => try sema.zirAsNode(block, inst), | 13632 | .as_node => try sema.zirAsNode(block, inst), |
| 13634 | .field_val => try sema.zirFieldVal(block, inst), | ||
| 13635 | .@"unreachable" => { | 13633 | .@"unreachable" => { |
| 13636 | try safetyPanicUnwrapError(sema, block, operand_src, operand); | 13634 | try safetyPanicUnwrapError(sema, block, operand_src, operand); |
| 13637 | return true; | 13635 | return true; |
| ... | @@ -26673,6 +26671,33 @@ fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { | ... | @@ -26673,6 +26671,33 @@ fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 26673 | } | 26671 | } |
| 26674 | } | 26672 | } |
| 26675 | 26673 | ||
| 26674 | fn fieldPtrLoad( | ||
| 26675 | sema: *Sema, | ||
| 26676 | block: *Block, | ||
| 26677 | src: LazySrcLoc, | ||
| 26678 | object_ptr: Air.Inst.Ref, | ||
| 26679 | field_name: InternPool.NullTerminatedString, | ||
| 26680 | field_name_src: LazySrcLoc, | ||
| 26681 | ) CompileError!Air.Inst.Ref { | ||
| 26682 | const pt = sema.pt; | ||
| 26683 | const zcu = pt.zcu; | ||
| 26684 | const object_ptr_ty = sema.typeOf(object_ptr); | ||
| 26685 | const pointee_ty = object_ptr_ty.childType(zcu); | ||
| 26686 | if (try typeHasOnePossibleValue(sema, pointee_ty)) |opv| { | ||
| 26687 | const object: Air.Inst.Ref = .fromValue(opv); | ||
| 26688 | return fieldVal(sema, block, src, object, field_name, field_name_src); | ||
| 26689 | } | ||
| 26690 | |||
| 26691 | if (try sema.resolveDefinedValue(block, src, object_ptr)) |object_ptr_val| { | ||
| 26692 | if (try sema.pointerDeref(block, src, object_ptr_val, object_ptr_ty)) |object_val| { | ||
| 26693 | const object: Air.Inst.Ref = .fromValue(object_val); | ||
| 26694 | return fieldVal(sema, block, src, object, field_name, field_name_src); | ||
| 26695 | } | ||
| 26696 | } | ||
| 26697 | const field_ptr = try sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false); | ||
| 26698 | return analyzeLoad(sema, block, src, field_ptr, field_name_src); | ||
| 26699 | } | ||
| 26700 | |||
| 26676 | fn fieldVal( | 26701 | fn fieldVal( |
| 26677 | sema: *Sema, | 26702 | sema: *Sema, |
| 26678 | block: *Block, | 26703 | block: *Block, |
src/print_zir.zig+2-2| ... | @@ -450,14 +450,14 @@ const Writer = struct { | ... | @@ -450,14 +450,14 @@ const Writer = struct { |
| 450 | 450 | ||
| 451 | .switch_block_err_union => try self.writeSwitchBlockErrUnion(stream, inst), | 451 | .switch_block_err_union => try self.writeSwitchBlockErrUnion(stream, inst), |
| 452 | 452 | ||
| 453 | .field_val, | 453 | .field_ptr_load, |
| 454 | .field_ptr, | 454 | .field_ptr, |
| 455 | .decl_literal, | 455 | .decl_literal, |
| 456 | .decl_literal_no_coerce, | 456 | .decl_literal_no_coerce, |
| 457 | => try self.writePlNodeField(stream, inst), | 457 | => try self.writePlNodeField(stream, inst), |
| 458 | 458 | ||
| 459 | .field_ptr_named, | 459 | .field_ptr_named, |
| 460 | .field_val_named, | 460 | .field_ptr_named_load, |
| 461 | => try self.writePlNodeFieldNamed(stream, inst), | 461 | => try self.writePlNodeFieldNamed(stream, inst), |
| 462 | 462 | ||
| 463 | .as_node, .as_shift_operand => try self.writeAs(stream, inst), | 463 | .as_node, .as_shift_operand => try self.writeAs(stream, inst), |