authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 11:09:00-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 11:09:00-07:00
log3f60481be45fbde9e37d4b8aaff8a02e1db3e07d
tree202ff020bcbaf4d9cc8f97d6ab150b9cf96b5730
parentae495de54d6aed6efbfc727f66154216b15225af

AstGen: implement the remaining struct init ResultLoc forms


3 files changed, 188 insertions(+), 85 deletions(-)

src/AstGen.zig+139-66
...@@ -877,63 +877,115 @@ pub fn structInitExpr(...@@ -877,63 +877,115 @@ pub fn structInitExpr(
877 }877 }
878 }878 }
879 switch (rl) {879 switch (rl) {
880 .discard => return astgen.failNode(node, "TODO implement structInitExpr discard", .{}),880 .discard => {
881 .none, .none_or_ref => return astgen.failNode(node, "TODO implement structInitExpr none", .{}),881 for (struct_init.ast.fields) |field_init| {
882 .ref => unreachable, // struct literal not valid as l-value882 _ = try expr(gz, scope, .discard, field_init);
883 .ty => |ty_inst| {883 }
884 const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len);884 return Zir.Inst.Ref.void_value;
885 },
886 .none, .none_or_ref => {
887 if (struct_init.ast.type_expr != 0) {
888 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
889 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
890 }
891 const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
885 defer gpa.free(fields_list);892 defer gpa.free(fields_list);
886893
887 for (struct_init.ast.fields) |field_init, i| {894 for (struct_init.ast.fields) |field_init, i| {
888 const name_token = tree.firstToken(field_init) - 2;895 const name_token = tree.firstToken(field_init) - 2;
889 const str_index = try gz.identAsString(name_token);896 const str_index = try gz.identAsString(name_token);
890897
891 const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{
892 .container_type = ty_inst,
893 .name_start = str_index,
894 });
895 fields_list[i] = .{898 fields_list[i] = .{
896 .field_type = gz.refToIndex(field_ty_inst).?,899 .field_name = str_index,
897 .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),900 .init = try expr(gz, scope, .none, field_init),
898 };901 };
899 }902 }
900 const init_inst = try gz.addPlNode(.struct_init, node, Zir.Inst.StructInit{903 const init_inst = try gz.addPlNode(.struct_init_anon, node, Zir.Inst.StructInitAnon{
901 .fields_len = @intCast(u32, fields_list.len),904 .fields_len = @intCast(u32, fields_list.len),
902 });905 });
903 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +906 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
904 fields_list.len * @typeInfo(Zir.Inst.StructInit.Item).Struct.fields.len);907 fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
905 for (fields_list) |field| {908 for (fields_list) |field| {
906 _ = gz.astgen.addExtraAssumeCapacity(field);909 _ = gz.astgen.addExtraAssumeCapacity(field);
907 }910 }
908 return rvalue(gz, scope, rl, init_inst, node);911 return init_inst;
909 },912 },
910 .ptr => |ptr_inst| {913 .ref => unreachable, // struct literal not valid as l-value
911 const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len);914 .ty => |ty_inst| return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst),
912 defer gpa.free(field_ptr_list);915 .ptr, .inferred_ptr => |ptr_inst| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst),
916 .block_ptr => |block_gz| return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr),
917 }
918}
913919
914 for (struct_init.ast.fields) |field_init, i| {920pub fn structInitExprRlPtr(
915 const name_token = tree.firstToken(field_init) - 2;921 gz: *GenZir,
916 const str_index = try gz.identAsString(name_token);922 scope: *Scope,
917 const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{923 rl: ResultLoc,
918 .lhs = ptr_inst,924 node: ast.Node.Index,
919 .field_name_start = str_index,925 struct_init: ast.full.StructInit,
920 });926 result_ptr: Zir.Inst.Ref,
921 field_ptr_list[i] = gz.refToIndex(field_ptr).?;927) InnerError!Zir.Inst.Ref {
922 _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init);928 const astgen = gz.astgen;
923 }929 const gpa = astgen.gpa;
924 const validate_inst = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{930 const tree = &astgen.file.tree;
925 .body_len = @intCast(u32, field_ptr_list.len),931
926 });932 const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len);
927 try astgen.extra.appendSlice(gpa, field_ptr_list);933 defer gpa.free(field_ptr_list);
928 return validate_inst;934
929 },935 for (struct_init.ast.fields) |field_init, i| {
930 .inferred_ptr => |ptr_inst| {936 const name_token = tree.firstToken(field_init) - 2;
931 return astgen.failNode(node, "TODO implement structInitExpr inferred_ptr", .{});937 const str_index = try gz.identAsString(name_token);
932 },938 const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{
933 .block_ptr => |block_gz| {939 .lhs = result_ptr,
934 return astgen.failNode(node, "TODO implement structInitExpr block", .{});940 .field_name_start = str_index,
935 },941 });
942 field_ptr_list[i] = gz.refToIndex(field_ptr).?;
943 _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init);
944 }
945 const validate_inst = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{
946 .body_len = @intCast(u32, field_ptr_list.len),
947 });
948 try astgen.extra.appendSlice(gpa, field_ptr_list);
949 return validate_inst;
950}
951
952pub fn structInitExprRlTy(
953 gz: *GenZir,
954 scope: *Scope,
955 rl: ResultLoc,
956 node: ast.Node.Index,
957 struct_init: ast.full.StructInit,
958 ty_inst: Zir.Inst.Ref,
959) InnerError!Zir.Inst.Ref {
960 const astgen = gz.astgen;
961 const gpa = astgen.gpa;
962 const tree = &astgen.file.tree;
963
964 const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len);
965 defer gpa.free(fields_list);
966
967 for (struct_init.ast.fields) |field_init, i| {
968 const name_token = tree.firstToken(field_init) - 2;
969 const str_index = try gz.identAsString(name_token);
970
971 const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{
972 .container_type = ty_inst,
973 .name_start = str_index,
974 });
975 fields_list[i] = .{
976 .field_type = gz.refToIndex(field_ty_inst).?,
977 .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),
978 };
936 }979 }
980 const init_inst = try gz.addPlNode(.struct_init, node, Zir.Inst.StructInit{
981 .fields_len = @intCast(u32, fields_list.len),
982 });
983 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
984 fields_list.len * @typeInfo(Zir.Inst.StructInit.Item).Struct.fields.len);
985 for (fields_list) |field| {
986 _ = gz.astgen.addExtraAssumeCapacity(field);
987 }
988 return init_inst;
937}989}
938990
939pub fn comptimeExpr(991pub fn comptimeExpr(
...@@ -1318,7 +1370,6 @@ fn blockExprStmts(...@@ -1318,7 +1370,6 @@ fn blockExprStmts(
1318 .elem_val,1370 .elem_val,
1319 .elem_ptr_node,1371 .elem_ptr_node,
1320 .elem_val_node,1372 .elem_val_node,
1321 .floatcast,
1322 .field_ptr,1373 .field_ptr,
1323 .field_val,1374 .field_val,
1324 .field_ptr_named,1375 .field_ptr_named,
...@@ -1403,8 +1454,10 @@ fn blockExprStmts(...@@ -1403,8 +1454,10 @@ fn blockExprStmts(
1403 .switch_capture_else_ref,1454 .switch_capture_else_ref,
1404 .struct_init_empty,1455 .struct_init_empty,
1405 .struct_init,1456 .struct_init,
1457 .struct_init_anon,
1406 .union_init_ptr,1458 .union_init_ptr,
1407 .field_type,1459 .field_type,
1460 .field_type_ref,
1408 .struct_decl,1461 .struct_decl,
1409 .struct_decl_packed,1462 .struct_decl_packed,
1410 .struct_decl_extern,1463 .struct_decl_extern,
...@@ -4706,21 +4759,61 @@ fn as(...@@ -4706,21 +4759,61 @@ fn as(
4706 const result = try expr(gz, scope, .{ .ty = dest_type }, rhs);4759 const result = try expr(gz, scope, .{ .ty = dest_type }, rhs);
4707 return rvalue(gz, scope, rl, result, node);4760 return rvalue(gz, scope, rl, result, node);
4708 },4761 },
47094762 .ptr, .inferred_ptr => |result_ptr| {
4710 .ptr => |result_ptr| {
4711 return asRlPtr(gz, scope, rl, result_ptr, rhs, dest_type);4763 return asRlPtr(gz, scope, rl, result_ptr, rhs, dest_type);
4712 },4764 },
4713 .block_ptr => |block_scope| {4765 .block_ptr => |block_scope| {
4714 return asRlPtr(gz, scope, rl, block_scope.rl_ptr, rhs, dest_type);4766 return asRlPtr(gz, scope, rl, block_scope.rl_ptr, rhs, dest_type);
4715 },4767 },
4768 }
4769}
47164770
4717 .inferred_ptr => |result_alloc| {4771fn unionInit(
4718 // TODO here we should be able to resolve the inference; we now have a type for the result.4772 gz: *GenZir,
4719 return gz.astgen.failNode(node, "TODO implement @as with inferred-type result location pointer", .{});4773 scope: *Scope,
4774 rl: ResultLoc,
4775 node: ast.Node.Index,
4776 params: []const ast.Node.Index,
4777) InnerError!Zir.Inst.Ref {
4778 const union_type = try typeExpr(gz, scope, params[0]);
4779 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
4780 switch (rl) {
4781 .none, .none_or_ref, .discard, .ref, .ty, .inferred_ptr => {
4782 const field_type = try gz.addPlNode(.field_type_ref, params[1], Zir.Inst.FieldTypeRef{
4783 .container_type = union_type,
4784 .field_name = field_name,
4785 });
4786 const result = try expr(gz, scope, .{ .ty = union_type }, params[2]);
4787 return rvalue(gz, scope, rl, result, node);
4788 },
4789 .ptr => |result_ptr| {
4790 return unionInitRlPtr(gz, scope, rl, node, result_ptr, params[2], union_type, field_name);
4791 },
4792 .block_ptr => |block_scope| {
4793 return unionInitRlPtr(gz, scope, rl, node, block_scope.rl_ptr, params[2], union_type, field_name);
4720 },4794 },
4721 }4795 }
4722}4796}
47234797
4798fn unionInitRlPtr(
4799 parent_gz: *GenZir,
4800 scope: *Scope,
4801 rl: ResultLoc,
4802 node: ast.Node.Index,
4803 result_ptr: Zir.Inst.Ref,
4804 expr_node: ast.Node.Index,
4805 union_type: Zir.Inst.Ref,
4806 field_name: Zir.Inst.Ref,
4807) InnerError!Zir.Inst.Ref {
4808 const union_init_ptr = try parent_gz.addPlNode(.union_init_ptr, node, Zir.Inst.UnionInitPtr{
4809 .result_ptr = result_ptr,
4810 .union_type = union_type,
4811 .field_name = field_name,
4812 });
4813 // TODO check if we need to do the elision like below in asRlPtr
4814 return expr(parent_gz, scope, .{ .ptr = union_init_ptr }, expr_node);
4815}
4816
4724fn asRlPtr(4817fn asRlPtr(
4725 parent_gz: *GenZir,4818 parent_gz: *GenZir,
4726 scope: *Scope,4819 scope: *Scope,
...@@ -4750,8 +4843,7 @@ fn asRlPtr(...@@ -4750,8 +4843,7 @@ fn asRlPtr(
4750 // Busted! This expression didn't actually need a pointer.4843 // Busted! This expression didn't actually need a pointer.
4751 const zir_tags = astgen.instructions.items(.tag);4844 const zir_tags = astgen.instructions.items(.tag);
4752 const zir_datas = astgen.instructions.items(.data);4845 const zir_datas = astgen.instructions.items(.data);
4753 const expected_len = parent_zir.items.len + as_scope.instructions.items.len - 2;4846 try parent_zir.ensureUnusedCapacity(astgen.gpa, as_scope.instructions.items.len);
4754 try parent_zir.ensureCapacity(astgen.gpa, expected_len);
4755 for (as_scope.instructions.items) |src_inst| {4847 for (as_scope.instructions.items) |src_inst| {
4756 if (parent_gz.indexToRef(src_inst) == as_scope.rl_ptr) continue;4848 if (parent_gz.indexToRef(src_inst) == as_scope.rl_ptr) continue;
4757 if (zir_tags[src_inst] == .store_to_block_ptr) {4849 if (zir_tags[src_inst] == .store_to_block_ptr) {
...@@ -4759,7 +4851,6 @@ fn asRlPtr(...@@ -4759,7 +4851,6 @@ fn asRlPtr(
4759 }4851 }
4760 parent_zir.appendAssumeCapacity(src_inst);4852 parent_zir.appendAssumeCapacity(src_inst);
4761 }4853 }
4762 assert(parent_zir.items.len == expected_len);
4763 const casted_result = try parent_gz.addBin(.as, dest_type, result);4854 const casted_result = try parent_gz.addBin(.as, dest_type, result);
4764 return rvalue(parent_gz, scope, rl, casted_result, operand_node);4855 return rvalue(parent_gz, scope, rl, casted_result, operand_node);
4765 } else {4856 } else {
...@@ -5445,24 +5536,6 @@ fn cImport(...@@ -5445,24 +5536,6 @@ fn cImport(
5445 return rvalue(gz, scope, rl, .void_value, node);5536 return rvalue(gz, scope, rl, .void_value, node);
5446}5537}
54475538
5448fn unionInit(
5449 gz: *GenZir,
5450 scope: *Scope,
5451 rl: ResultLoc,
5452 node: ast.Node.Index,
5453 params: []const ast.Node.Index,
5454) InnerError!Zir.Inst.Ref {
5455 const union_type = try typeExpr(gz, scope, params[0]);
5456 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
5457 const union_init_ptr = try gz.addPlNode(.union_init_ptr, node, Zir.Inst.UnionInitPtr{
5458 .union_type = union_type,
5459 .field_name = field_name,
5460 });
5461 // TODO: set up a store_to_block_ptr elision thing here
5462 const result = try expr(gz, scope, .{ .ptr = union_init_ptr }, params[2]);
5463 return rvalue(gz, scope, rl, result, node);
5464}
5465
5466fn overflowArithmetic(5539fn overflowArithmetic(
5467 gz: *GenZir,5540 gz: *GenZir,
5468 scope: *Scope,5541 scope: *Scope,
src/Sema.zig+15-8
...@@ -193,7 +193,6 @@ pub fn analyzeBody(...@@ -193,7 +193,6 @@ pub fn analyzeBody(
193 .field_ptr_named => try sema.zirFieldPtrNamed(block, inst),193 .field_ptr_named => try sema.zirFieldPtrNamed(block, inst),
194 .field_val => try sema.zirFieldVal(block, inst),194 .field_val => try sema.zirFieldVal(block, inst),
195 .field_val_named => try sema.zirFieldValNamed(block, inst),195 .field_val_named => try sema.zirFieldValNamed(block, inst),
196 .floatcast => try sema.zirFloatcast(block, inst),
197 .func => try sema.zirFunc(block, inst, false),196 .func => try sema.zirFunc(block, inst, false),
198 .func_extra => try sema.zirFuncExtra(block, inst, false),197 .func_extra => try sema.zirFuncExtra(block, inst, false),
199 .func_extra_var_args => try sema.zirFuncExtra(block, inst, true),198 .func_extra_var_args => try sema.zirFuncExtra(block, inst, true),
...@@ -266,8 +265,10 @@ pub fn analyzeBody(...@@ -266,8 +265,10 @@ pub fn analyzeBody(
266 .xor => try sema.zirBitwise(block, inst, .xor),265 .xor => try sema.zirBitwise(block, inst, .xor),
267 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),266 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
268 .struct_init => try sema.zirStructInit(block, inst),267 .struct_init => try sema.zirStructInit(block, inst),
268 .struct_init_anon => try sema.zirStructInitAnon(block, inst),
269 .union_init_ptr => try sema.zirUnionInitPtr(block, inst),269 .union_init_ptr => try sema.zirUnionInitPtr(block, inst),
270 .field_type => try sema.zirFieldType(block, inst),270 .field_type => try sema.zirFieldType(block, inst),
271 .field_type_ref => try sema.zirFieldTypeRef(block, inst),
271 .error_return_trace => try sema.zirErrorReturnTrace(block, inst),272 .error_return_trace => try sema.zirErrorReturnTrace(block, inst),
272 .frame => try sema.zirFrame(block, inst),273 .frame => try sema.zirFrame(block, inst),
273 .frame_address => try sema.zirFrameAddress(block, inst),274 .frame_address => try sema.zirFrameAddress(block, inst),
...@@ -2904,7 +2905,7 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError...@@ -2904,7 +2905,7 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
2904 return sema.bitcast(block, dest_type, operand);2905 return sema.bitcast(block, dest_type, operand);
2905}2906}
29062907
2907fn zirFloatcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {2908fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
2908 const tracy = trace(@src());2909 const tracy = trace(@src());
2909 defer tracy.end();2910 defer tracy.end();
29102911
...@@ -4984,6 +4985,18 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr...@@ -4984,6 +4985,18 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
4984 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{});4985 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{});
4985}4986}
49864987
4988fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4989 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4990 const src = inst_data.src();
4991 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{});
4992}
4993
4994fn zirFieldTypeRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4995 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4996 const src = inst_data.src();
4997 return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldTypeRef", .{});
4998}
4999
4987fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {5000fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4988 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;5001 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4989 const src = inst_data.src();5002 const src = inst_data.src();
...@@ -5092,12 +5105,6 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -5092,12 +5105,6 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
5092 return sema.mod.fail(&block.base, src, "TODO: Sema.zirIntToPtr", .{});5105 return sema.mod.fail(&block.base, src, "TODO: Sema.zirIntToPtr", .{});
5093}5106}
50945107
5095fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5096 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5097 const src = inst_data.src();
5098 return sema.mod.fail(&block.base, src, "TODO: Sema.zirFloatCast", .{});
5099}
5100
5101fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {5108fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5102 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;5109 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5103 const src = inst_data.src();5110 const src = inst_data.src();
src/Zir.zig+34-11
...@@ -367,11 +367,6 @@ pub const Inst = struct {...@@ -367,11 +367,6 @@ pub const Inst = struct {
367 /// The field name is a comptime instruction. Used by @field.367 /// The field name is a comptime instruction. Used by @field.
368 /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed.368 /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed.
369 field_val_named,369 field_val_named,
370 /// Convert a larger float type to any other float type, possibly causing
371 /// a loss of precision.
372 /// Uses the `pl_node` field. AST is the `@floatCast` syntax.
373 /// Payload is `Bin` with lhs as the dest type, rhs the operand.
374 floatcast,
375 /// Returns a function type, or a function instance, depending on whether370 /// Returns a function type, or a function instance, depending on whether
376 /// the body_len is 0. Calling convention is auto.371 /// the body_len is 0. Calling convention is auto.
377 /// Uses the `pl_node` union field. `payload_index` points to a `Func`.372 /// Uses the `pl_node` union field. `payload_index` points to a `Func`.
...@@ -686,13 +681,19 @@ pub const Inst = struct {...@@ -686,13 +681,19 @@ pub const Inst = struct {
686 /// A struct literal with a specified type, with no fields.681 /// A struct literal with a specified type, with no fields.
687 /// Uses the `un_node` field.682 /// Uses the `un_node` field.
688 struct_init_empty,683 struct_init_empty,
689 /// Given a struct, union, enum, or opaque and a field name, returns the field type.684 /// Given a struct, union, enum, or opaque and a field name as a string index,
690 /// Uses the `pl_node` field. Payload is `FieldType`.685 /// returns the field type. Uses the `pl_node` field. Payload is `FieldType`.
691 field_type,686 field_type,
687 /// Given a struct, union, enum, or opaque and a field name as a Ref,
688 /// returns the field type. Uses the `pl_node` field. Payload is `FieldTypeRef`.
689 field_type_ref,
692 /// Finalizes a typed struct initialization, performs validation, and returns the690 /// Finalizes a typed struct initialization, performs validation, and returns the
693 /// struct value.691 /// struct value.
694 /// Uses the `pl_node` field. Payload is `StructInit`.692 /// Uses the `pl_node` field. Payload is `StructInit`.
695 struct_init,693 struct_init,
694 /// Struct initialization without a type.
695 /// Uses the `pl_node` field. Payload is `StructInitAnon`.
696 struct_init_anon,
696 /// Given a pointer to a union and a comptime known field name, activates that field697 /// Given a pointer to a union and a comptime known field name, activates that field
697 /// and returns a pointer to it.698 /// and returns a pointer to it.
698 /// Uses the `pl_node` field. Payload is `UnionInitPtr`.699 /// Uses the `pl_node` field. Payload is `UnionInitPtr`.
...@@ -813,8 +814,10 @@ pub const Inst = struct {...@@ -813,8 +814,10 @@ pub const Inst = struct {
813 /// Converts an integer into an enum value.814 /// Converts an integer into an enum value.
814 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.815 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
815 int_to_enum,816 int_to_enum,
816 /// Implements the `@floatCast` builtin.817 /// Convert a larger float type to any other float type, possibly causing
817 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.818 /// a loss of precision.
819 /// Uses the `pl_node` field. AST is the `@floatCast` syntax.
820 /// Payload is `Bin` with lhs as the dest type, rhs the operand.
818 float_cast,821 float_cast,
819 /// Implements the `@intCast` builtin.822 /// Implements the `@intCast` builtin.
820 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.823 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
...@@ -1002,7 +1005,6 @@ pub const Inst = struct {...@@ -1002,7 +1005,6 @@ pub const Inst = struct {
1002 .ensure_result_used,1005 .ensure_result_used,
1003 .ensure_result_non_error,1006 .ensure_result_non_error,
1004 .@"export",1007 .@"export",
1005 .floatcast,
1006 .field_ptr,1008 .field_ptr,
1007 .field_val,1009 .field_val,
1008 .field_ptr_named,1010 .field_ptr_named,
...@@ -1099,8 +1101,10 @@ pub const Inst = struct {...@@ -1099,8 +1101,10 @@ pub const Inst = struct {
1099 .validate_struct_init_ptr,1101 .validate_struct_init_ptr,
1100 .struct_init_empty,1102 .struct_init_empty,
1101 .struct_init,1103 .struct_init,
1104 .struct_init_anon,
1102 .union_init_ptr,1105 .union_init_ptr,
1103 .field_type,1106 .field_type,
1107 .field_type_ref,
1104 .int_to_enum,1108 .int_to_enum,
1105 .enum_to_int,1109 .enum_to_int,
1106 .type_info,1110 .type_info,
...@@ -2031,12 +2035,29 @@ pub const Inst = struct {...@@ -2031,12 +2035,29 @@ pub const Inst = struct {
2031 };2035 };
2032 };2036 };
20332037
2038 /// Trailing is an item per field.
2039 pub const StructInitAnon = struct {
2040 fields_len: u32,
2041
2042 pub const Item = struct {
2043 /// Null-terminated string table index.
2044 field_name: u32,
2045 /// The field init expression to be used as the field value.
2046 init: Ref,
2047 };
2048 };
2049
2034 pub const FieldType = struct {2050 pub const FieldType = struct {
2035 container_type: Ref,2051 container_type: Ref,
2036 /// Offset into `string_bytes`, null terminated.2052 /// Offset into `string_bytes`, null terminated.
2037 name_start: u32,2053 name_start: u32,
2038 };2054 };
20392055
2056 pub const FieldTypeRef = struct {
2057 container_type: Ref,
2058 field_name: Ref,
2059 };
2060
2040 pub const OverflowArithmetic = struct {2061 pub const OverflowArithmetic = struct {
2041 lhs: Ref,2062 lhs: Ref,
2042 rhs: Ref,2063 rhs: Ref,
...@@ -2059,6 +2080,7 @@ pub const Inst = struct {...@@ -2059,6 +2080,7 @@ pub const Inst = struct {
2059 };2080 };
20602081
2061 pub const UnionInitPtr = struct {2082 pub const UnionInitPtr = struct {
2083 result_ptr: Ref,
2062 union_type: Ref,2084 union_type: Ref,
2063 field_name: Ref,2085 field_name: Ref,
2064 };2086 };
...@@ -2279,14 +2301,15 @@ const Writer = struct {...@@ -2279,14 +2301,15 @@ const Writer = struct {
2279 .elem_val_node,2301 .elem_val_node,
2280 .field_ptr_named,2302 .field_ptr_named,
2281 .field_val_named,2303 .field_val_named,
2282 .floatcast,
2283 .slice_start,2304 .slice_start,
2284 .slice_end,2305 .slice_end,
2285 .slice_sentinel,2306 .slice_sentinel,
2286 .union_decl,2307 .union_decl,
2287 .struct_init,2308 .struct_init,
2309 .struct_init_anon,
2288 .union_init_ptr,2310 .union_init_ptr,
2289 .field_type,2311 .field_type,
2312 .field_type_ref,
2290 .cmpxchg_strong,2313 .cmpxchg_strong,
2291 .cmpxchg_weak,2314 .cmpxchg_weak,
2292 .shuffle,2315 .shuffle,