@@ -6080,6 +6080,9 @@ fn fieldAccess(
6080
6080
.ref, .ref_coerced_ty => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .ref }, node),
6081
6081
.pseudo_ref => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .pseudo_ref }, node),
6082
6082
else => {
6083
+ if ((gz.is_comptime and gz.astgen.fn_block != null) or !nodeAccessesIdentifier(gz.astgen.tree, node)) {
6084
+ return rvalue(gz, ri, try addFieldAccess(.field_val, gz, scope, .{ .rl = .none }, node), node);
6085
+ }
6083
6086
const ptr = try addFieldAccess(.field_ptr, gz, scope, .{ .rl = .pseudo_ref }, node);
6084
6087
const result = try gz.addUnNode(.load, ptr, node);
6085
6088
return rvalue(gz, ri, result, node);
@@ -6122,40 +6125,32 @@ fn arrayAccess(
6122
6125
) InnerError!Zir.Inst.Ref {
6123
6126
const tree = gz.astgen.tree;
6124
6127
const node_datas = tree.nodes.items(.data);
6125
- switch (ri.rl) {
6126
- .ref, .ref_coerced_ty => {
6127
- const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
6128
-
6129
- const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
6130
-
6131
- const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
6132
- try emitDbgStmt(gz, cursor);
6133
-
6134
- return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
6135
- },
6136
- .pseudo_ref => {
6137
- const lhs = try expr(gz, scope, .{ .rl = .pseudo_ref }, node_datas[node].lhs);
6128
+ const lhs_result: ResultInfo, const need_load = switch (ri.rl) {
6129
+ .ref, .ref_coerced_ty => .{ .{ .rl = .ref }, false },
6130
+ .pseudo_ref => .{ .{ .rl = .pseudo_ref }, false },
6131
+ else => if ((gz.is_comptime and gz.astgen.fn_block != null) or !nodeAccessesIdentifier(tree, node)) {
6132
+ const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);
6138
6133
6139
6134
const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
6140
6135
6141
6136
const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
6142
6137
try emitDbgStmt(gz, cursor);
6143
6138
6144
- return gz .addPlNode(.elem_ptr_node , node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
6145
- },
6146
- else => {
6147
- const lhs = try expr(gz, scope, .{ .rl = .pseudo_ref } , node_datas[node].lhs);
6139
+ return rvalue(gz, ri, try gz .addPlNode(.elem_val_node , node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node );
6140
+ } else .{ .{ .rl = .pseudo_ref }, true } ,
6141
+ };
6142
+ const lhs = try expr(gz, scope, lhs_result , node_datas[node].lhs);
6148
6143
6149
- const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
6144
+ const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
6150
6145
6151
- const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
6152
- try emitDbgStmt(gz, cursor);
6146
+ const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
6147
+ try emitDbgStmt(gz, cursor);
6153
6148
6154
- const ptr = try gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
6155
- const result = try gz.addUnNode(.load, ptr, node) ;
6156
- return rvalue(gz, ri, result, node);
6157
- },
6158
- }
6149
+ const ptr = try gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
6150
+ if (!need_load) return ptr ;
6151
+
6152
+ const loaded = try gz.addUnNode(.load, ptr, node);
6153
+ return rvalue(gz, ri, loaded, node);
6159
6154
}
6160
6155
6161
6156
fn simpleBinOp(
@@ -10953,6 +10948,31 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool {
10953
10948
}
10954
10949
}
10955
10950
10951
+ /// Returns `true` if field/array access chain ultimately refers to an identifier.
10952
+ fn nodeAccessesIdentifier(tree: *const Ast, start_node: Ast.Node.Index) bool {
10953
+ const node_tags = tree.nodes.items(.tag);
10954
+ const node_datas = tree.nodes.items(.data);
10955
+
10956
+ var node = start_node;
10957
+ while (true) {
10958
+ switch (node_tags[node]) {
10959
+ .identifier => return true,
10960
+
10961
+ // Forward the question to the LHS sub-expression.
10962
+ .grouped_expression,
10963
+ .@"try",
10964
+ .@"nosuspend",
10965
+ .unwrap_optional,
10966
+ .deref,
10967
+ .field_access,
10968
+ .array_access,
10969
+ => node = node_datas[node].lhs,
10970
+
10971
+ else => return false,
10972
+ }
10973
+ }
10974
+ }
10975
+
10956
10976
/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
10957
10977
/// result locations must call this function on their result.
10958
10978
/// As an example, if `ri.rl` is `.ptr`, it will write the result to the pointer.
0 commit comments