@@ -383,6 +383,8 @@ const ResultInfo = struct {
383383 assignment,
384384 /// No specific operator in particular.
385385 none,
386+ /// The expression is operand to address-of which is the operand to a return expression.
387+ return_addrof,
386388 };
387389};
388390
@@ -955,7 +957,14 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
955957 _ = try gz.addUnTok(.validate_ref_ty, res_ty_inst, tree.firstToken(node));
956958 break :rl .{ .ref_coerced_ty = res_ty_inst };
957959 } else .ref;
958- const result = try expr(gz, scope, .{ .rl = operand_rl }, tree.nodeData(node).node);
960+ const operand_node = tree.nodeData(node).node;
961+ const result = try expr(gz, scope, .{
962+ .rl = operand_rl,
963+ .ctx = switch (ri.ctx) {
964+ .@"return" => .return_addrof,
965+ else => .none,
966+ },
967+ }, operand_node);
959968 return rvalue(gz, ri, result, node);
960969 },
961970 .optional_type => {
@@ -8420,13 +8429,19 @@ fn localVarRef(
84208429 local_ptr.used = .fromToken(ident_token);
84218430 }
84228431
8423- // Can't close over a runtime variable
8424- if (num_namespaces_out != 0 and !local_ptr.maybe_comptime and !gz.is_typeof) {
8425- const ident_name = try astgen.identifierTokenString(ident_token);
8426- return astgen.failNodeNotes(ident, "mutable '{s}' not accessible from here", .{ident_name}, &.{
8427- try astgen.errNoteTok(local_ptr.token_src, "declared mutable here", .{}),
8428- try astgen.errNoteNode(capturing_namespace.node, "crosses namespace boundary here", .{}),
8429- });
8432+ if (!local_ptr.maybe_comptime and !gz.is_typeof) {
8433+ if (num_namespaces_out != 0) {
8434+ const ident_name = try astgen.identifierTokenString(ident_token);
8435+ return astgen.failNodeNotes(ident, "mutable '{s}' not accessible from here", .{ident_name}, &.{
8436+ try astgen.errNoteTok(local_ptr.token_src, "declared mutable here", .{}),
8437+ try astgen.errNoteNode(capturing_namespace.node, "crosses namespace boundary here", .{}),
8438+ });
8439+ } else if (ri.ctx == .return_addrof) {
8440+ const ident_name = try astgen.identifierTokenString(ident_token);
8441+ return astgen.failNodeNotes(ident, "returning address of expired local variable '{s}'", .{ident_name}, &.{
8442+ try astgen.errNoteTok(local_ptr.token_src, "declared runtime-known here", .{}),
8443+ });
8444+ }
84308445 }
84318446
84328447 switch (ri.rl) {
0 commit comments