authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-30 17:35:18-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-05-30 17:35:18-04:00
logc84f5a5f91d31b20b2e187d84fc8a80a190a1212
treef2c580bac4ad1a649b3decd370ddb6f12316337e
parentf846dc420fff629572caa1175bfa64e5fcffaeb5
parent0e8307789a3de41759e68c7c04c130889e277991
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11749 from Vexu/stage2

Stage2: improve AstGen for array init expressions

6 files changed, 152 insertions(+), 124 deletions(-)

src/AstGen.zig+36-58
...@@ -1276,12 +1276,10 @@ fn arrayInitExpr(...@@ -1276,12 +1276,10 @@ fn arrayInitExpr(
1276 const types: struct {1276 const types: struct {
1277 array: Zir.Inst.Ref,1277 array: Zir.Inst.Ref,
1278 elem: Zir.Inst.Ref,1278 elem: Zir.Inst.Ref,
1279 sentinel: Zir.Inst.Ref,
1280 } = inst: {1279 } = inst: {
1281 if (array_init.ast.type_expr == 0) break :inst .{1280 if (array_init.ast.type_expr == 0) break :inst .{
1282 .array = .none,1281 .array = .none,
1283 .elem = .none,1282 .elem = .none,
1284 .sentinel = .none,
1285 };1283 };
12861284
1287 infer: {1285 infer: {
...@@ -1301,7 +1299,6 @@ fn arrayInitExpr(...@@ -1301,7 +1299,6 @@ fn arrayInitExpr(
1301 break :inst .{1299 break :inst .{
1302 .array = array_type_inst,1300 .array = array_type_inst,
1303 .elem = elem_type,1301 .elem = elem_type,
1304 .sentinel = .none,
1305 };1302 };
1306 } else {1303 } else {
1307 const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel);1304 const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel);
...@@ -1317,50 +1314,38 @@ fn arrayInitExpr(...@@ -1317,50 +1314,38 @@ fn arrayInitExpr(
1317 break :inst .{1314 break :inst .{
1318 .array = array_type_inst,1315 .array = array_type_inst,
1319 .elem = elem_type,1316 .elem = elem_type,
1320 .sentinel = sentinel,
1321 };1317 };
1322 }1318 }
1323 }1319 }
1324 }1320 }
1325 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);1321 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
1326 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);1322 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);
1327 const elem_type = try gz.addUnNode(.elem_type, array_type_inst, array_init.ast.type_expr);
1328 break :inst .{1323 break :inst .{
1329 .array = array_type_inst,1324 .array = array_type_inst,
1330 .elem = elem_type,1325 .elem = .none,
1331 .sentinel = .none,
1332 };1326 };
1333 };1327 };
13341328
1335 switch (rl) {1329 switch (rl) {
1336 .discard => {1330 .discard => {
1331 // TODO elements should still be coerced if type is provided
1337 for (array_init.ast.elements) |elem_init| {1332 for (array_init.ast.elements) |elem_init| {
1338 _ = try expr(gz, scope, .discard, elem_init);1333 _ = try expr(gz, scope, .discard, elem_init);
1339 }1334 }
1340 return Zir.Inst.Ref.void_value;1335 return Zir.Inst.Ref.void_value;
1341 },1336 },
1342 .ref => {1337 .ref => {
1343 if (types.array != .none) {1338 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init_ref else .array_init_anon_ref;
1344 return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, true);1339 return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);
1345 } else {
1346 return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon_ref);
1347 }
1348 },1340 },
1349 .none => {1341 .none => {
1350 if (types.array != .none) {1342 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon;
1351 return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, false);1343 return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);
1352 } else {
1353 return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon);
1354 }
1355 },1344 },
1356 .ty, .coerced_ty => {1345 .ty, .coerced_ty => {
1357 if (types.array != .none) {1346 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon;
1358 const result = try arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, false);1347 const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);
1359 return rvalue(gz, rl, result, node);1348 return rvalue(gz, rl, result, node);
1360 } else {
1361 const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon);
1362 return rvalue(gz, rl, result, node);
1363 }
1364 },1349 },
1365 .ptr => |ptr_inst| {1350 .ptr => |ptr_inst| {
1366 return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array);1351 return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array);
...@@ -1410,52 +1395,47 @@ fn arrayInitExprRlNone(...@@ -1410,52 +1395,47 @@ fn arrayInitExprRlNone(
1410 return try gz.addPlNodePayloadIndex(tag, node, payload_index);1395 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1411}1396}
14121397
1413fn arrayInitExprRlTy(1398fn arrayInitExprInner(
1414 gz: *GenZir,1399 gz: *GenZir,
1415 scope: *Scope,1400 scope: *Scope,
1416 node: Ast.Node.Index,1401 node: Ast.Node.Index,
1417 elements: []const Ast.Node.Index,1402 elements: []const Ast.Node.Index,
1418 elem_ty_inst: Zir.Inst.Ref,1403 array_ty_inst: Zir.Inst.Ref,
1419 sentinel: Zir.Inst.Ref,1404 elem_ty: Zir.Inst.Ref,
1420 ref: bool,1405 tag: Zir.Inst.Tag,
1421) InnerError!Zir.Inst.Ref {1406) InnerError!Zir.Inst.Ref {
1422 const astgen = gz.astgen;1407 const astgen = gz.astgen;
14231408
1424 const info: struct {1409 const len = elements.len + @boolToInt(array_ty_inst != .none);
1425 len: usize,
1426 tag: Zir.Inst.Tag,
1427 } = blk: {
1428 if (sentinel != .none) {
1429 break :blk .{
1430 .len = elements.len + 1,
1431 .tag = if (ref) .array_init_sent_ref else .array_init_sent,
1432 };
1433 } else {
1434 break :blk .{
1435 .len = elements.len,
1436 .tag = if (ref) .array_init_ref else .array_init,
1437 };
1438 }
1439 };
1440
1441 const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{1410 const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{
1442 .operands_len = @intCast(u32, info.len),1411 .operands_len = @intCast(u32, len),
1443 });1412 });
1444 var extra_index = try reserveExtra(astgen, info.len);1413 var extra_index = try reserveExtra(astgen, len);
14451414 if (array_ty_inst != .none) {
1446 const elem_rl: ResultLoc = .{ .ty = elem_ty_inst };1415 astgen.extra.items[extra_index] = @enumToInt(array_ty_inst);
1447 for (elements) |elem_init| {
1448 const elem_ref = try expr(gz, scope, elem_rl, elem_init);
1449 astgen.extra.items[extra_index] = @enumToInt(elem_ref);
1450 extra_index += 1;1416 extra_index += 1;
1451 }1417 }
14521418
1453 if (sentinel != .none) {1419 for (elements) |elem_init, i| {
1454 astgen.extra.items[extra_index] = @enumToInt(sentinel);1420 const rl = if (elem_ty != .none)
1421 ResultLoc{ .coerced_ty = elem_ty }
1422 else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) rl: {
1423 const ty_expr = try gz.add(.{
1424 .tag = .elem_type_index,
1425 .data = .{ .bin = .{
1426 .lhs = array_ty_inst,
1427 .rhs = @intToEnum(Zir.Inst.Ref, i),
1428 } },
1429 });
1430 break :rl ResultLoc{ .coerced_ty = ty_expr };
1431 } else ResultLoc{ .none = {} };
1432
1433 const elem_ref = try expr(gz, scope, rl, elem_init);
1434 astgen.extra.items[extra_index] = @enumToInt(elem_ref);
1455 extra_index += 1;1435 extra_index += 1;
1456 }1436 }
14571437
1458 return try gz.addPlNodePayloadIndex(info.tag, node, payload_index);1438 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1459}1439}
14601440
1461fn arrayInitExprRlPtr(1441fn arrayInitExprRlPtr(
...@@ -2243,8 +2223,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner...@@ -2243,8 +2223,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
2243 .array_mul,2223 .array_mul,
2244 .array_type,2224 .array_type,
2245 .array_type_sentinel,2225 .array_type_sentinel,
2226 .elem_type_index,
2246 .vector_type,2227 .vector_type,
2247 .elem_type,
2248 .indexable_ptr_len,2228 .indexable_ptr_len,
2249 .anyframe_type,2229 .anyframe_type,
2250 .as,2230 .as,
...@@ -2347,10 +2327,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner...@@ -2347,10 +2327,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
2347 .struct_init_anon_ref,2327 .struct_init_anon_ref,
2348 .array_init,2328 .array_init,
2349 .array_init_anon,2329 .array_init_anon,
2350 .array_init_sent,
2351 .array_init_ref,2330 .array_init_ref,
2352 .array_init_anon_ref,2331 .array_init_anon_ref,
2353 .array_init_sent_ref,
2354 .union_init,2332 .union_init,
2355 .field_type,2333 .field_type,
2356 .field_type_ref,2334 .field_type_ref,
src/Sema.zig+64-37
...@@ -726,7 +726,7 @@ fn analyzeBodyInner(...@@ -726,7 +726,7 @@ fn analyzeBodyInner(
726 .elem_ptr_imm => try sema.zirElemPtrImm(block, inst),726 .elem_ptr_imm => try sema.zirElemPtrImm(block, inst),
727 .elem_val => try sema.zirElemVal(block, inst),727 .elem_val => try sema.zirElemVal(block, inst),
728 .elem_val_node => try sema.zirElemValNode(block, inst),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 .enum_literal => try sema.zirEnumLiteral(block, inst),730 .enum_literal => try sema.zirEnumLiteral(block, inst),
731 .enum_to_int => try sema.zirEnumToInt(block, inst),731 .enum_to_int => try sema.zirEnumToInt(block, inst),
732 .int_to_enum => try sema.zirIntToEnum(block, inst),732 .int_to_enum => try sema.zirIntToEnum(block, inst),
...@@ -798,10 +798,8 @@ fn analyzeBodyInner(...@@ -798,10 +798,8 @@ fn analyzeBodyInner(
798 .struct_init_ref => try sema.zirStructInit(block, inst, true),798 .struct_init_ref => try sema.zirStructInit(block, inst, true),
799 .struct_init_anon => try sema.zirStructInitAnon(block, inst, false),799 .struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
800 .struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),800 .struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
801 .array_init => try sema.zirArrayInit(block, inst, false, false),801 .array_init => try sema.zirArrayInit(block, inst, false),
802 .array_init_sent => try sema.zirArrayInit(block, inst, false, true),802 .array_init_ref => try sema.zirArrayInit(block, inst, true),
803 .array_init_ref => try sema.zirArrayInit(block, inst, true, false),
804 .array_init_sent_ref => try sema.zirArrayInit(block, inst, true, true),
805 .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),803 .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
806 .array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),804 .array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
807 .union_init => try sema.zirUnionInit(block, inst),805 .union_init => try sema.zirUnionInit(block, inst),
...@@ -3024,7 +3022,10 @@ fn zirArrayBasePtr(...@@ -3024,7 +3022,10 @@ fn zirArrayBasePtr(
3024 const elem_ty = sema.typeOf(base_ptr).childType();3022 const elem_ty = sema.typeOf(base_ptr).childType();
3025 switch (elem_ty.zigTypeTag()) {3023 switch (elem_ty.zigTypeTag()) {
3026 .Array, .Vector => return base_ptr,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 else => {},3029 else => {},
3029 }3030 }
3030 return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType());3031 return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType());
...@@ -3065,7 +3066,10 @@ fn validateArrayInitTy(...@@ -3065,7 +3066,10 @@ fn validateArrayInitTy(
30653066
3066 switch (ty.zigTypeTag()) {3067 switch (ty.zigTypeTag()) {
3067 .Array, .Vector => return,3068 .Array, .Vector => return,
3068 .Struct => if (ty.isTuple()) return,3069 .Struct => if (ty.isTuple()) {
3070 // TODO validate element count
3071 return;
3072 },
3069 else => {},3073 else => {},
3070 }3074 }
3071 return sema.failWithArrayInitNotSupported(block, src, ty);3075 return sema.failWithArrayInitNotSupported(block, src, ty);
...@@ -5808,12 +5812,17 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5808,12 +5812,17 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
5808 return sema.addType(opt_type);5812 return sema.addType(opt_type);
5809}5813}
58105814
5811fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5815fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5812 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5816 const bin = sema.code.instructions.items(.data)[inst].bin;
5813 const src = inst_data.src();5817 const indexable_ty = try sema.resolveType(block, .unneeded, bin.lhs);
5814 const array_type = try sema.resolveType(block, src, inst_data.operand);5818 assert(indexable_ty.isIndexable()); // validated by a previous instruction
5815 const elem_type = array_type.elemType();5819 if (indexable_ty.zigTypeTag() == .Struct) {
5816 return sema.addType(elem_type);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}
58185827
5819fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5828fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -13280,6 +13289,8 @@ fn zirStructInit(...@@ -13280,6 +13289,8 @@ fn zirStructInit(
13280 try sema.requireRuntimeBlock(block, src);13289 try sema.requireRuntimeBlock(block, src);
13281 try sema.queueFullTypeResolution(resolved_ty);13290 try sema.queueFullTypeResolution(resolved_ty);
13282 return block.addUnionInit(resolved_ty, field_index, init_inst);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 unreachable;13295 unreachable;
13285}13296}
...@@ -13436,7 +13447,6 @@ fn zirArrayInit(...@@ -13436,7 +13447,6 @@ fn zirArrayInit(
13436 block: *Block,13447 block: *Block,
13437 inst: Zir.Inst.Index,13448 inst: Zir.Inst.Index,
13438 is_ref: bool,13449 is_ref: bool,
13439 is_sent: bool,
13440) CompileError!Air.Inst.Ref {13450) CompileError!Air.Inst.Ref {
13441 const gpa = sema.gpa;13451 const gpa = sema.gpa;
13442 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13452 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
...@@ -13444,30 +13454,26 @@ fn zirArrayInit(...@@ -13444,30 +13454,26 @@ fn zirArrayInit(
1344413454
13445 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);13455 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
13446 const args = sema.code.refSlice(extra.end, extra.data.operands_len);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
1344813458
13449 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len);13459 const array_ty = try sema.resolveType(block, src, args[0]);
13450 defer gpa.free(resolved_args);13460 const sentinel_val = array_ty.sentinel();
13451
13452 for (args) |arg, i| resolved_args[i] = try sema.resolveInst(arg);
1345313461
13454 const elem_ty = sema.typeOf(resolved_args[0]);13462 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null));
13455 const array_ty = blk: {13463 defer gpa.free(resolved_args);
13456 if (!is_sent) {13464 for (args[1..]) |arg, i| {
13457 break :blk try Type.Tag.array.create(sema.arena, .{13465 const resolved_arg = try sema.resolveInst(arg);
13458 .len = resolved_args.len,13466 const arg_src = src; // TODO better source location
13459 .elem_type = elem_ty,13467 const elem_ty = if (array_ty.zigTypeTag() == .Struct)
13460 });13468 array_ty.tupleFields().types[i]
13461 }13469 else
13470 array_ty.elemType2();
13471 resolved_args[i] = try sema.coerce(block, elem_ty, resolved_arg, arg_src);
13472 }
1346213473
13463 const sentinel_ref = resolved_args[resolved_args.len - 1];13474 if (sentinel_val) |some| {
13464 const val = try sema.resolveConstValue(block, src, sentinel_ref);13475 resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(), some);
13465 break :blk try Type.Tag.array_sentinel.create(sema.arena, .{13476 }
13466 .len = resolved_args.len - 1,
13467 .sentinel = val,
13468 .elem_type = elem_ty,
13469 });
13470 };
1347113477
13472 const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| {13478 const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| {
13473 const arg_src = src; // TODO better source location13479 const arg_src = src; // TODO better source location
...@@ -13488,7 +13494,7 @@ fn zirArrayInit(...@@ -13488,7 +13494,7 @@ fn zirArrayInit(
13488 };13494 };
1348913495
13490 try sema.requireRuntimeBlock(block, runtime_src);13496 try sema.requireRuntimeBlock(block, runtime_src);
13491 try sema.queueFullTypeResolution(elem_ty);13497 try sema.queueFullTypeResolution(array_ty);
1349213498
13493 if (is_ref) {13499 if (is_ref) {
13494 const target = sema.mod.getTarget();13500 const target = sema.mod.getTarget();
...@@ -13498,10 +13504,27 @@ fn zirArrayInit(...@@ -13498,10 +13504,27 @@ fn zirArrayInit(
13498 });13504 });
13499 const alloc = try block.addTy(.alloc, alloc_ty);13505 const alloc = try block.addTy(.alloc, alloc_ty);
1350013506
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 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{13524 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
13502 .mutable = true,13525 .mutable = true,
13503 .@"addrspace" = target_util.defaultAddressSpace(target, .local),13526 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
13504 .pointee_type = elem_ty,13527 .pointee_type = array_ty.elemType2(),
13505 });13528 });
13506 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);13529 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1350713530
...@@ -13643,6 +13666,10 @@ fn fieldType(...@@ -13643,6 +13666,10 @@ fn fieldType(
13643 while (true) {13666 while (true) {
13644 switch (cur_ty.zigTypeTag()) {13667 switch (cur_ty.zigTypeTag()) {
13645 .Struct => {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 const struct_obj = cur_ty.castTag(.@"struct").?.data;13673 const struct_obj = cur_ty.castTag(.@"struct").?.data;
13647 const field = struct_obj.fields.get(field_name) orelse13674 const field = struct_obj.fields.get(field_name) orelse
13648 return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);13675 return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);
src/Zir.zig+6-20
...@@ -221,9 +221,9 @@ pub const Inst = struct {...@@ -221,9 +221,9 @@ pub const Inst = struct {
221 /// Uses the `pl_node` union field with `Bin` payload.221 /// Uses the `pl_node` union field with `Bin` payload.
222 /// lhs is length, rhs is element type.222 /// lhs is length, rhs is element type.
223 vector_type,223 vector_type,
224 /// Given an array type, returns the element type.224 /// Given an indexable type, returns the type of the element at given index.
225 /// Uses the `un_node` union field.225 /// Uses the `bin` union field. lhs is the indexable type, rhs is the index.
226 elem_type,226 elem_type_index,
227 /// Given a pointer to an indexable object, returns the len property. This is227 /// Given a pointer to an indexable object, returns the len property. This is
228 /// used by for loops. This instruction also emits a for-loop specific compile228 /// used by for loops. This instruction also emits a for-loop specific compile
229 /// error if the indexable object is not indexable.229 /// error if the indexable object is not indexable.
...@@ -737,20 +737,12 @@ pub const Inst = struct {...@@ -737,20 +737,12 @@ pub const Inst = struct {
737 /// Array initialization syntax.737 /// Array initialization syntax.
738 /// Uses the `pl_node` field. Payload is `MultiOp`.738 /// Uses the `pl_node` field. Payload is `MultiOp`.
739 array_init,739 array_init,
740 /// Array initialization with sentinel.
741 /// Uses the `pl_node` field. Payload is `MultiOp`.
742 /// Final op in MultiOp is the sentinel.
743 array_init_sent,
744 /// Anonymous array initialization syntax.740 /// Anonymous array initialization syntax.
745 /// Uses the `pl_node` field. Payload is `MultiOp`.741 /// Uses the `pl_node` field. Payload is `MultiOp`.
746 array_init_anon,742 array_init_anon,
747 /// Array initialization syntax, make the result a pointer.743 /// Array initialization syntax, make the result a pointer.
748 /// Uses the `pl_node` field. Payload is `MultiOp`.744 /// Uses the `pl_node` field. Payload is `MultiOp`.
749 array_init_ref,745 array_init_ref,
750 /// Array initialization with sentinel.
751 /// Uses the `pl_node` field. Payload is `MultiOp`.
752 /// Final op in MultiOp is the sentinel.
753 array_init_sent_ref,
754 /// Anonymous array initialization syntax, make the result a pointer.746 /// Anonymous array initialization syntax, make the result a pointer.
755 /// Uses the `pl_node` field. Payload is `MultiOp`.747 /// Uses the `pl_node` field. Payload is `MultiOp`.
756 array_init_anon_ref,748 array_init_anon_ref,
...@@ -1019,7 +1011,7 @@ pub const Inst = struct {...@@ -1019,7 +1011,7 @@ pub const Inst = struct {
1019 .array_type,1011 .array_type,
1020 .array_type_sentinel,1012 .array_type_sentinel,
1021 .vector_type,1013 .vector_type,
1022 .elem_type,1014 .elem_type_index,
1023 .indexable_ptr_len,1015 .indexable_ptr_len,
1024 .anyframe_type,1016 .anyframe_type,
1025 .as,1017 .as,
...@@ -1153,10 +1145,8 @@ pub const Inst = struct {...@@ -1153,10 +1145,8 @@ pub const Inst = struct {
1153 .struct_init_anon,1145 .struct_init_anon,
1154 .struct_init_anon_ref,1146 .struct_init_anon_ref,
1155 .array_init,1147 .array_init,
1156 .array_init_sent,
1157 .array_init_anon,1148 .array_init_anon,
1158 .array_init_ref,1149 .array_init_ref,
1159 .array_init_sent_ref,
1160 .array_init_anon_ref,1150 .array_init_anon_ref,
1161 .union_init,1151 .union_init,
1162 .field_type,1152 .field_type,
...@@ -1314,7 +1304,7 @@ pub const Inst = struct {...@@ -1314,7 +1304,7 @@ pub const Inst = struct {
1314 .array_type,1304 .array_type,
1315 .array_type_sentinel,1305 .array_type_sentinel,
1316 .vector_type,1306 .vector_type,
1317 .elem_type,1307 .elem_type_index,
1318 .indexable_ptr_len,1308 .indexable_ptr_len,
1319 .anyframe_type,1309 .anyframe_type,
1320 .as,1310 .as,
...@@ -1426,10 +1416,8 @@ pub const Inst = struct {...@@ -1426,10 +1416,8 @@ pub const Inst = struct {
1426 .struct_init_anon,1416 .struct_init_anon,
1427 .struct_init_anon_ref,1417 .struct_init_anon_ref,
1428 .array_init,1418 .array_init,
1429 .array_init_sent,
1430 .array_init_anon,1419 .array_init_anon,
1431 .array_init_ref,1420 .array_init_ref,
1432 .array_init_sent_ref,
1433 .array_init_anon_ref,1421 .array_init_anon_ref,
1434 .union_init,1422 .union_init,
1435 .field_type,1423 .field_type,
...@@ -1554,7 +1542,7 @@ pub const Inst = struct {...@@ -1554,7 +1542,7 @@ pub const Inst = struct {
1554 .array_type = .bin,1542 .array_type = .bin,
1555 .array_type_sentinel = .pl_node,1543 .array_type_sentinel = .pl_node,
1556 .vector_type = .pl_node,1544 .vector_type = .pl_node,
1557 .elem_type = .un_node,1545 .elem_type_index = .bin,
1558 .indexable_ptr_len = .un_node,1546 .indexable_ptr_len = .un_node,
1559 .anyframe_type = .un_node,1547 .anyframe_type = .un_node,
1560 .as = .bin,1548 .as = .bin,
...@@ -1688,10 +1676,8 @@ pub const Inst = struct {...@@ -1688,10 +1676,8 @@ pub const Inst = struct {
1688 .struct_init_anon = .pl_node,1676 .struct_init_anon = .pl_node,
1689 .struct_init_anon_ref = .pl_node,1677 .struct_init_anon_ref = .pl_node,
1690 .array_init = .pl_node,1678 .array_init = .pl_node,
1691 .array_init_sent = .pl_node,
1692 .array_init_anon = .pl_node,1679 .array_init_anon = .pl_node,
1693 .array_init_ref = .pl_node,1680 .array_init_ref = .pl_node,
1694 .array_init_sent_ref = .pl_node,
1695 .array_init_anon_ref = .pl_node,1681 .array_init_anon_ref = .pl_node,
1696 .union_init = .pl_node,1682 .union_init = .pl_node,
1697 .type_info = .un_node,1683 .type_info = .un_node,
src/print_zir.zig+11-7
...@@ -152,6 +152,8 @@ const Writer = struct {...@@ -152,6 +152,8 @@ const Writer = struct {
152 .store_to_inferred_ptr,152 .store_to_inferred_ptr,
153 => try self.writeBin(stream, inst),153 => try self.writeBin(stream, inst),
154154
155 .elem_type_index => try self.writeElemTypeIndex(stream, inst),
156
155 .alloc,157 .alloc,
156 .alloc_mut,158 .alloc_mut,
157 .alloc_comptime_mut,159 .alloc_comptime_mut,
...@@ -226,7 +228,6 @@ const Writer = struct {...@@ -226,7 +228,6 @@ const Writer = struct {
226 .pop_count,228 .pop_count,
227 .byte_swap,229 .byte_swap,
228 .bit_reverse,230 .bit_reverse,
229 .elem_type,
230 .@"resume",231 .@"resume",
231 .@"await",232 .@"await",
232 .switch_cond,233 .switch_cond,
...@@ -268,10 +269,6 @@ const Writer = struct {...@@ -268,10 +269,6 @@ const Writer = struct {
268 .array_init_anon_ref,269 .array_init_anon_ref,
269 => try self.writeArrayInit(stream, inst),270 => try self.writeArrayInit(stream, inst),
270271
271 .array_init_sent,
272 .array_init_sent_ref,
273 => try self.writeArrayInitSent(stream, inst),
274
275 .slice_start => try self.writeSliceStart(stream, inst),272 .slice_start => try self.writeSliceStart(stream, inst),
276 .slice_end => try self.writeSliceEnd(stream, inst),273 .slice_end => try self.writeSliceEnd(stream, inst),
277 .slice_sentinel => try self.writeSliceSentinel(stream, inst),274 .slice_sentinel => try self.writeSliceSentinel(stream, inst),
...@@ -543,6 +540,12 @@ const Writer = struct {...@@ -543,6 +540,12 @@ const Writer = struct {
543 try stream.writeByte(')');540 try stream.writeByte(')');
544 }541 }
545542
543 fn writeElemTypeIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
544 const inst_data = self.code.instructions.items(.data)[inst].bin;
545 try self.writeInstRef(stream, inst_data.lhs);
546 try stream.print(", {d})", .{inst_data.rhs});
547 }
548
546 fn writeUnNode(549 fn writeUnNode(
547 self: *Writer,550 self: *Writer,
548 stream: anytype,551 stream: anytype,
...@@ -2085,8 +2088,9 @@ const Writer = struct {...@@ -2085,8 +2088,9 @@ const Writer = struct {
2085 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);2088 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
2086 const args = self.code.refSlice(extra.end, extra.data.operands_len);2089 const args = self.code.refSlice(extra.end, extra.data.operands_len);
20872090
2088 try stream.writeAll(".{");2091 try self.writeInstRef(stream, args[0]);
2089 for (args) |arg, i| {2092 try stream.writeAll("{");
2093 for (args[1..]) |arg, i| {
2090 if (i != 0) try stream.writeAll(", ");2094 if (i != 0) try stream.writeAll(", ");
2091 try self.writeInstRef(stream, arg);2095 try self.writeInstRef(stream, arg);
2092 }2096 }
test/behavior/basic.zig+35
...@@ -942,3 +942,38 @@ test "comptime int in switch in catch is casted to correct inferred type" {...@@ -942,3 +942,38 @@ test "comptime int in switch in catch is casted to correct inferred type" {
942 };942 };
943 _ = b;943 _ = b;
944}944}
945
946test "vector initialized with array init syntax has proper type" {
947 comptime {
948 const actual = -@Vector(4, i32){ 1, 2, 3, 4 };
949 try std.testing.expectEqual(@Vector(4, i32){ -1, -2, -3, -4 }, actual);
950 }
951}
952
953test "weird array and tuple initializations" {
954 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
955 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
956 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
957
958 const E = enum { a, b };
959 const S = struct { e: E };
960 var a = false;
961 const b = S{ .e = .a };
962
963 _ = &[_]S{
964 if (a) .{ .e = .a } else .{ .e = .b },
965 };
966
967 if (true) return error.SkipZigTest;
968
969 const S2 = @TypeOf(.{ false, b });
970 _ = &S2{
971 true,
972 if (a) .{ .e = .a } else .{ .e = .b },
973 };
974 const S3 = @TypeOf(.{ .a = false, .b = b });
975 _ = &S3{
976 .a = true,
977 .b = if (a) .{ .e = .a } else .{ .e = .b },
978 };
979}
test/behavior/tuple.zig-2
...@@ -194,8 +194,6 @@ test "tuple as the result from a labeled block" {...@@ -194,8 +194,6 @@ test "tuple as the result from a labeled block" {
194}194}
195195
196test "initializing tuple with explicit type" {196test "initializing tuple with explicit type" {
197 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
198
199 const T = @TypeOf(.{ @as(i32, 0), @as(u32, 0) });197 const T = @TypeOf(.{ @as(i32, 0), @as(u32, 0) });
200 var a = T{ 0, 0 };198 var a = T{ 0, 0 };
201 _ = a;199 _ = a;