@@ -4148,7 +4148,6 @@ fn structDeclInner(
4148
4148
.src_node = node ,
4149
4149
.layout = layout ,
4150
4150
.fields_len = 0 ,
4151
- .body_len = 0 ,
4152
4151
.decls_len = 0 ,
4153
4152
.known_non_opv = false ,
4154
4153
.known_comptime_only = false ,
@@ -4192,6 +4191,19 @@ fn structDeclInner(
4192
4191
var wip_members = try WipMembers .init (gpa , & astgen .scratch , decl_count , field_count , bits_per_field , max_field_size );
4193
4192
defer wip_members .deinit ();
4194
4193
4194
+ // We will use the scratch buffer, starting here, for the bodies:
4195
+ // bodies: { // for every fields_len
4196
+ // field_type_body_inst: Inst, // for each field_type_body_len
4197
+ // align_body_inst: Inst, // for each align_body_len
4198
+ // init_body_inst: Inst, // for each init_body_len
4199
+ // }
4200
+ // Note that the scratch buffer is simultaneously being used by WipMembers, however
4201
+ // it will not access any elements beyond this point in the ArrayList. It also
4202
+ // accesses via the ArrayList items field so it can handle the scratch buffer being
4203
+ // reallocated.
4204
+ // No defer needed here because it is handled by `wip_members.deinit()` above.
4205
+ const bodies_start = astgen .scratch .items .len ;
4206
+
4195
4207
var known_non_opv = false ;
4196
4208
var known_comptime_only = false ;
4197
4209
for (container_decl .ast .members ) | member_node | {
@@ -4203,57 +4215,78 @@ fn structDeclInner(
4203
4215
const field_name = try astgen .identAsString (member .ast .name_token );
4204
4216
wip_members .appendToField (field_name );
4205
4217
4218
+ const doc_comment_index = try astgen .docCommentAsString (member .firstToken ());
4219
+ wip_members .appendToField (doc_comment_index );
4220
+
4206
4221
if (member .ast .type_expr == 0 ) {
4207
4222
return astgen .failTok (member .ast .name_token , "struct field missing type" , .{});
4208
4223
}
4209
4224
4210
4225
const field_type = try typeExpr (& block_scope , & namespace .base , member .ast .type_expr );
4211
- wip_members .appendToField (@enumToInt (field_type ));
4212
-
4213
- const doc_comment_index = try astgen .docCommentAsString (member .firstToken ());
4214
- wip_members .appendToField (doc_comment_index );
4215
-
4226
+ const have_type_body = ! block_scope .isEmpty ();
4216
4227
const have_align = member .ast .align_expr != 0 ;
4217
4228
const have_value = member .ast .value_expr != 0 ;
4218
4229
const is_comptime = member .comptime_token != null ;
4219
- const unused = false ;
4220
4230
4221
4231
if (! is_comptime ) {
4222
4232
known_non_opv = known_non_opv or
4223
4233
nodeImpliesMoreThanOnePossibleValue (tree , member .ast .type_expr );
4224
4234
known_comptime_only = known_comptime_only or
4225
4235
nodeImpliesComptimeOnly (tree , member .ast .type_expr );
4226
4236
}
4227
- wip_members .nextField (bits_per_field , .{ have_align , have_value , is_comptime , unused });
4237
+ wip_members .nextField (bits_per_field , .{ have_align , have_value , is_comptime , have_type_body });
4238
+
4239
+ if (have_type_body ) {
4240
+ if (! block_scope .endsWithNoReturn ()) {
4241
+ _ = try block_scope .addBreak (.break_inline , decl_inst , field_type );
4242
+ }
4243
+ const body = block_scope .instructionsSlice ();
4244
+ const old_scratch_len = astgen .scratch .items .len ;
4245
+ try astgen .scratch .ensureUnusedCapacity (gpa , countBodyLenAfterFixups (astgen , body ));
4246
+ appendBodyWithFixupsArrayList (astgen , & astgen .scratch , body );
4247
+ wip_members .appendToField (@intCast (u32 , astgen .scratch .items .len - old_scratch_len ));
4248
+ block_scope .instructions .items .len = block_scope .instructions_top ;
4249
+ } else {
4250
+ wip_members .appendToField (@enumToInt (field_type ));
4251
+ }
4228
4252
4229
4253
if (have_align ) {
4230
4254
if (layout == .Packed ) {
4231
4255
try astgen .appendErrorNode (member .ast .align_expr , "unable to override alignment of packed struct fields" , .{});
4232
4256
}
4233
- const align_inst = try expr (& block_scope , & namespace .base , align_rl , member .ast .align_expr );
4234
- wip_members .appendToField (@enumToInt (align_inst ));
4257
+ const align_ref = try expr (& block_scope , & namespace .base , coerced_align_rl , member .ast .align_expr );
4258
+ if (! block_scope .endsWithNoReturn ()) {
4259
+ _ = try block_scope .addBreak (.break_inline , decl_inst , align_ref );
4260
+ }
4261
+ const body = block_scope .instructionsSlice ();
4262
+ const old_scratch_len = astgen .scratch .items .len ;
4263
+ try astgen .scratch .ensureUnusedCapacity (gpa , countBodyLenAfterFixups (astgen , body ));
4264
+ appendBodyWithFixupsArrayList (astgen , & astgen .scratch , body );
4265
+ wip_members .appendToField (@intCast (u32 , astgen .scratch .items .len - old_scratch_len ));
4266
+ block_scope .instructions .items .len = block_scope .instructions_top ;
4235
4267
}
4268
+
4236
4269
if (have_value ) {
4237
- const rl : ResultLoc = if (field_type == .none ) .none else .{ .ty = field_type };
4270
+ const rl : ResultLoc = if (field_type == .none ) .none else .{ .coerced_ty = field_type };
4238
4271
4239
4272
const default_inst = try expr (& block_scope , & namespace .base , rl , member .ast .value_expr );
4240
- wip_members .appendToField (@enumToInt (default_inst ));
4273
+ if (! block_scope .endsWithNoReturn ()) {
4274
+ _ = try block_scope .addBreak (.break_inline , decl_inst , default_inst );
4275
+ }
4276
+ const body = block_scope .instructionsSlice ();
4277
+ const old_scratch_len = astgen .scratch .items .len ;
4278
+ try astgen .scratch .ensureUnusedCapacity (gpa , countBodyLenAfterFixups (astgen , body ));
4279
+ appendBodyWithFixupsArrayList (astgen , & astgen .scratch , body );
4280
+ wip_members .appendToField (@intCast (u32 , astgen .scratch .items .len - old_scratch_len ));
4281
+ block_scope .instructions .items .len = block_scope .instructions_top ;
4241
4282
} else if (member .comptime_token ) | comptime_token | {
4242
4283
return astgen .failTok (comptime_token , "comptime field without default initialization value" , .{});
4243
4284
}
4244
4285
}
4245
4286
4246
- if (! block_scope .isEmpty ()) {
4247
- _ = try block_scope .addBreak (.break_inline , decl_inst , .void_value );
4248
- }
4249
-
4250
- const body = block_scope .instructionsSlice ();
4251
- const body_len = astgen .countBodyLenAfterFixups (body );
4252
-
4253
4287
try gz .setStruct (decl_inst , .{
4254
4288
.src_node = node ,
4255
4289
.layout = layout ,
4256
- .body_len = body_len ,
4257
4290
.fields_len = field_count ,
4258
4291
.decls_len = decl_count ,
4259
4292
.known_non_opv = known_non_opv ,
@@ -4263,10 +4296,11 @@ fn structDeclInner(
4263
4296
wip_members .finishBits (bits_per_field );
4264
4297
const decls_slice = wip_members .declsSlice ();
4265
4298
const fields_slice = wip_members .fieldsSlice ();
4266
- try astgen .extra .ensureUnusedCapacity (gpa , decls_slice .len + body_len + fields_slice .len );
4299
+ const bodies_slice = astgen .scratch .items [bodies_start .. ];
4300
+ try astgen .extra .ensureUnusedCapacity (gpa , decls_slice .len + fields_slice .len + bodies_slice .len );
4267
4301
astgen .extra .appendSliceAssumeCapacity (decls_slice );
4268
- astgen .appendBodyWithFixups (body );
4269
4302
astgen .extra .appendSliceAssumeCapacity (fields_slice );
4303
+ astgen .extra .appendSliceAssumeCapacity (bodies_slice );
4270
4304
4271
4305
block_scope .unstack ();
4272
4306
try gz .addNamespaceCaptures (& namespace );
@@ -10981,7 +11015,6 @@ const GenZir = struct {
10981
11015
10982
11016
fn setStruct (gz : * GenZir , inst : Zir.Inst.Index , args : struct {
10983
11017
src_node : Ast.Node.Index ,
10984
- body_len : u32 ,
10985
11018
fields_len : u32 ,
10986
11019
decls_len : u32 ,
10987
11020
layout : std.builtin.Type.ContainerLayout ,
@@ -10998,9 +11031,6 @@ const GenZir = struct {
10998
11031
const node_offset = gz .nodeIndexToRelative (args .src_node );
10999
11032
astgen .extra .appendAssumeCapacity (@bitCast (u32 , node_offset ));
11000
11033
}
11001
- if (args .body_len != 0 ) {
11002
- astgen .extra .appendAssumeCapacity (args .body_len );
11003
- }
11004
11034
if (args .fields_len != 0 ) {
11005
11035
astgen .extra .appendAssumeCapacity (args .fields_len );
11006
11036
}
@@ -11013,7 +11043,6 @@ const GenZir = struct {
11013
11043
.opcode = .struct_decl ,
11014
11044
.small = @bitCast (u16 , Zir.Inst.StructDecl.Small {
11015
11045
.has_src_node = args .src_node != 0 ,
11016
- .has_body_len = args .body_len != 0 ,
11017
11046
.has_fields_len = args .fields_len != 0 ,
11018
11047
.has_decls_len = args .decls_len != 0 ,
11019
11048
.known_non_opv = args .known_non_opv ,
0 commit comments