@@ -726,7 +726,7 @@ fn analyzeBodyInner(
726
726
.elem_ptr_imm => try sema.zirElemPtrImm(block, inst),
727
727
.elem_val => try sema.zirElemVal(block, inst),
728
728
.elem_val_node => try sema.zirElemValNode(block, inst),
729
- .elem_type => try sema.zirElemType (block, inst),
729
+ .elem_type_index => try sema.zirElemTypeIndex (block, inst),
730
730
.enum_literal => try sema.zirEnumLiteral(block, inst),
731
731
.enum_to_int => try sema.zirEnumToInt(block, inst),
732
732
.int_to_enum => try sema.zirIntToEnum(block, inst),
@@ -798,10 +798,8 @@ fn analyzeBodyInner(
798
798
.struct_init_ref => try sema.zirStructInit(block, inst, true),
799
799
.struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
800
800
.struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
801
- .array_init => try sema.zirArrayInit(block, inst, false, false),
802
- .array_init_sent => try sema.zirArrayInit(block, inst, false, true),
803
- .array_init_ref => try sema.zirArrayInit(block, inst, true, false),
804
- .array_init_sent_ref => try sema.zirArrayInit(block, inst, true, true),
801
+ .array_init => try sema.zirArrayInit(block, inst, false),
802
+ .array_init_ref => try sema.zirArrayInit(block, inst, true),
805
803
.array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
806
804
.array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
807
805
.union_init => try sema.zirUnionInit(block, inst),
@@ -3024,7 +3022,10 @@ fn zirArrayBasePtr(
3024
3022
const elem_ty = sema.typeOf(base_ptr).childType();
3025
3023
switch (elem_ty.zigTypeTag()) {
3026
3024
.Array, .Vector => return base_ptr,
3027
- .Struct => if (elem_ty.isTuple()) return base_ptr,
3025
+ .Struct => if (elem_ty.isTuple()) {
3026
+ // TODO validate element count
3027
+ return base_ptr;
3028
+ },
3028
3029
else => {},
3029
3030
}
3030
3031
return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType());
@@ -3065,7 +3066,10 @@ fn validateArrayInitTy(
3065
3066
3066
3067
switch (ty.zigTypeTag()) {
3067
3068
.Array, .Vector => return,
3068
- .Struct => if (ty.isTuple()) return,
3069
+ .Struct => if (ty.isTuple()) {
3070
+ // TODO validate element count
3071
+ return;
3072
+ },
3069
3073
else => {},
3070
3074
}
3071
3075
return sema.failWithArrayInitNotSupported(block, src, ty);
@@ -5808,12 +5812,17 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
5808
5812
return sema.addType(opt_type);
5809
5813
}
5810
5814
5811
- fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5812
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5813
- const src = inst_data.src();
5814
- const array_type = try sema.resolveType(block, src, inst_data.operand);
5815
- const elem_type = array_type.elemType();
5816
- return sema.addType(elem_type);
5815
+ fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5816
+ const bin = sema.code.instructions.items(.data)[inst].bin;
5817
+ const indexable_ty = try sema.resolveType(block, .unneeded, bin.lhs);
5818
+ assert(indexable_ty.isIndexable()); // validated by a previous instruction
5819
+ if (indexable_ty.zigTypeTag() == .Struct) {
5820
+ const elem_type = indexable_ty.tupleFields().types[@enumToInt(bin.rhs)];
5821
+ return sema.addType(elem_type);
5822
+ } else {
5823
+ const elem_type = indexable_ty.elemType2();
5824
+ return sema.addType(elem_type);
5825
+ }
5817
5826
}
5818
5827
5819
5828
fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -13280,6 +13289,8 @@ fn zirStructInit(
13280
13289
try sema.requireRuntimeBlock(block, src);
13281
13290
try sema.queueFullTypeResolution(resolved_ty);
13282
13291
return block.addUnionInit(resolved_ty, field_index, init_inst);
13292
+ } else if (resolved_ty.isAnonStruct()) {
13293
+ return sema.fail(block, src, "TODO anon struct init validation", .{});
13283
13294
}
13284
13295
unreachable;
13285
13296
}
@@ -13436,38 +13447,33 @@ fn zirArrayInit(
13436
13447
block: *Block,
13437
13448
inst: Zir.Inst.Index,
13438
13449
is_ref: bool,
13439
- is_sent: bool,
13440
13450
) CompileError!Air.Inst.Ref {
13441
13451
const gpa = sema.gpa;
13442
13452
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13443
13453
const src = inst_data.src();
13444
13454
13445
13455
const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
13446
13456
const args = sema.code.refSlice(extra.end, extra.data.operands_len);
13447
- assert(args.len != 0);
13457
+ assert(args.len >= 2); // array_ty + at least one element
13448
13458
13449
- const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len);
13450
- defer gpa.free(resolved_args);
13451
-
13452
- for (args) |arg, i| resolved_args[i] = try sema.resolveInst(arg);
13459
+ const array_ty = try sema.resolveType(block, src, args[0]);
13460
+ const sentinel_val = array_ty.sentinel();
13453
13461
13454
- const elem_ty = sema.typeOf(resolved_args[0]);
13455
- const array_ty = blk: {
13456
- if (!is_sent) {
13457
- break :blk try Type.Tag.array.create(sema.arena, .{
13458
- .len = resolved_args.len,
13459
- .elem_type = elem_ty,
13460
- });
13461
- }
13462
+ const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null));
13463
+ defer gpa.free(resolved_args);
13464
+ for (args[1..]) |arg, i| {
13465
+ const resolved_arg = try sema.resolveInst(arg);
13466
+ const arg_src = src; // TODO better source location
13467
+ const elem_ty = if (array_ty.zigTypeTag() == .Struct)
13468
+ array_ty.tupleFields().types[i]
13469
+ else
13470
+ array_ty.elemType2();
13471
+ resolved_args[i] = try sema.coerce(block, elem_ty, resolved_arg, arg_src);
13472
+ }
13462
13473
13463
- const sentinel_ref = resolved_args[resolved_args.len - 1];
13464
- const val = try sema.resolveConstValue(block, src, sentinel_ref);
13465
- break :blk try Type.Tag.array_sentinel.create(sema.arena, .{
13466
- .len = resolved_args.len - 1,
13467
- .sentinel = val,
13468
- .elem_type = elem_ty,
13469
- });
13470
- };
13474
+ if (sentinel_val) |some| {
13475
+ resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(), some);
13476
+ }
13471
13477
13472
13478
const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| {
13473
13479
const arg_src = src; // TODO better source location
@@ -13488,7 +13494,7 @@ fn zirArrayInit(
13488
13494
};
13489
13495
13490
13496
try sema.requireRuntimeBlock(block, runtime_src);
13491
- try sema.queueFullTypeResolution(elem_ty );
13497
+ try sema.queueFullTypeResolution(array_ty );
13492
13498
13493
13499
if (is_ref) {
13494
13500
const target = sema.mod.getTarget();
@@ -13498,10 +13504,27 @@ fn zirArrayInit(
13498
13504
});
13499
13505
const alloc = try block.addTy(.alloc, alloc_ty);
13500
13506
13507
+ if (array_ty.isTuple()) {
13508
+ const types = array_ty.tupleFields().types;
13509
+ for (resolved_args) |arg, i| {
13510
+ const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
13511
+ .mutable = true,
13512
+ .@"addrspace" = target_util.defaultAddressSpace(target, .local),
13513
+ .pointee_type = types[i],
13514
+ });
13515
+ const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
13516
+
13517
+ const index = try sema.addIntUnsigned(Type.usize, i);
13518
+ const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);
13519
+ _ = try block.addBinOp(.store, elem_ptr, arg);
13520
+ }
13521
+ return alloc;
13522
+ }
13523
+
13501
13524
const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
13502
13525
.mutable = true,
13503
13526
.@"addrspace" = target_util.defaultAddressSpace(target, .local),
13504
- .pointee_type = elem_ty ,
13527
+ .pointee_type = array_ty.elemType2() ,
13505
13528
});
13506
13529
const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
13507
13530
@@ -13643,6 +13666,10 @@ fn fieldType(
13643
13666
while (true) {
13644
13667
switch (cur_ty.zigTypeTag()) {
13645
13668
.Struct => {
13669
+ if (cur_ty.isAnonStruct()) {
13670
+ const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
13671
+ return sema.addType(cur_ty.tupleFields().types[field_index]);
13672
+ }
13646
13673
const struct_obj = cur_ty.castTag(.@"struct").?.data;
13647
13674
const field = struct_obj.fields.get(field_name) orelse
13648
13675
return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);
0 commit comments