| author | |
| committer | |
| log | c84f5a5f91d31b20b2e187d84fc8a80a190a1212 |
| tree | f2c580bac4ad1a649b3decd370ddb6f12316337e |
| parent | f846dc420fff629572caa1175bfa64e5fcffaeb5 |
| parent | 0e8307789a3de41759e68c7c04c130889e277991 |
| signature |
Stage2: improve AstGen for array init expressions6 files changed, 152 insertions(+), 124 deletions(-)
src/AstGen.zig+36-58| ... | ... | @@ -1276,12 +1276,10 @@ fn arrayInitExpr( |
| 1276 | 1276 | const types: struct { |
| 1277 | 1277 | array: Zir.Inst.Ref, |
| 1278 | 1278 | elem: Zir.Inst.Ref, |
| 1279 | sentinel: Zir.Inst.Ref, | |
| 1280 | 1279 | } = inst: { |
| 1281 | 1280 | if (array_init.ast.type_expr == 0) break :inst .{ |
| 1282 | 1281 | .array = .none, |
| 1283 | 1282 | .elem = .none, |
| 1284 | .sentinel = .none, | |
| 1285 | 1283 | }; |
| 1286 | 1284 | |
| 1287 | 1285 | infer: { |
| ... | ... | @@ -1301,7 +1299,6 @@ fn arrayInitExpr( |
| 1301 | 1299 | break :inst .{ |
| 1302 | 1300 | .array = array_type_inst, |
| 1303 | 1301 | .elem = elem_type, |
| 1304 | .sentinel = .none, | |
| 1305 | 1302 | }; |
| 1306 | 1303 | } else { |
| 1307 | 1304 | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); |
| ... | ... | @@ -1317,50 +1314,38 @@ fn arrayInitExpr( |
| 1317 | 1314 | break :inst .{ |
| 1318 | 1315 | .array = array_type_inst, |
| 1319 | 1316 | .elem = elem_type, |
| 1320 | .sentinel = sentinel, | |
| 1321 | 1317 | }; |
| 1322 | 1318 | } |
| 1323 | 1319 | } |
| 1324 | 1320 | } |
| 1325 | 1321 | const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr); |
| 1326 | 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 | 1323 | break :inst .{ |
| 1329 | 1324 | .array = array_type_inst, |
| 1330 | .elem = elem_type, | |
| 1331 | .sentinel = .none, | |
| 1325 | .elem = .none, | |
| 1332 | 1326 | }; |
| 1333 | 1327 | }; |
| 1334 | 1328 | |
| 1335 | 1329 | switch (rl) { |
| 1336 | 1330 | .discard => { |
| 1331 | // TODO elements should still be coerced if type is provided | |
| 1337 | 1332 | for (array_init.ast.elements) |elem_init| { |
| 1338 | 1333 | _ = try expr(gz, scope, .discard, elem_init); |
| 1339 | 1334 | } |
| 1340 | 1335 | return Zir.Inst.Ref.void_value; |
| 1341 | 1336 | }, |
| 1342 | 1337 | .ref => { |
| 1343 | if (types.array != .none) { | |
| 1344 | return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, true); | |
| 1345 | } else { | |
| 1346 | return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon_ref); | |
| 1347 | } | |
| 1338 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init_ref else .array_init_anon_ref; | |
| 1339 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); | |
| 1348 | 1340 | }, |
| 1349 | 1341 | .none => { |
| 1350 | if (types.array != .none) { | |
| 1351 | return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, false); | |
| 1352 | } else { | |
| 1353 | return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); | |
| 1354 | } | |
| 1342 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; | |
| 1343 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); | |
| 1355 | 1344 | }, |
| 1356 | 1345 | .ty, .coerced_ty => { |
| 1357 | if (types.array != .none) { | |
| 1358 | const result = try arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, false); | |
| 1359 | 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 | } | |
| 1346 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; | |
| 1347 | const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); | |
| 1348 | return rvalue(gz, rl, result, node); | |
| 1364 | 1349 | }, |
| 1365 | 1350 | .ptr => |ptr_inst| { |
| 1366 | 1351 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array); |
| ... | ... | @@ -1410,52 +1395,47 @@ fn arrayInitExprRlNone( |
| 1410 | 1395 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1411 | 1396 | } |
| 1412 | 1397 | |
| 1413 | fn arrayInitExprRlTy( | |
| 1398 | fn arrayInitExprInner( | |
| 1414 | 1399 | gz: *GenZir, |
| 1415 | 1400 | scope: *Scope, |
| 1416 | 1401 | node: Ast.Node.Index, |
| 1417 | 1402 | elements: []const Ast.Node.Index, |
| 1418 | elem_ty_inst: Zir.Inst.Ref, | |
| 1419 | sentinel: Zir.Inst.Ref, | |
| 1420 | ref: bool, | |
| 1403 | array_ty_inst: Zir.Inst.Ref, | |
| 1404 | elem_ty: Zir.Inst.Ref, | |
| 1405 | tag: Zir.Inst.Tag, | |
| 1421 | 1406 | ) InnerError!Zir.Inst.Ref { |
| 1422 | 1407 | const astgen = gz.astgen; |
| 1423 | 1408 | |
| 1424 | const info: struct { | |
| 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 | ||
| 1409 | const len = elements.len + @boolToInt(array_ty_inst != .none); | |
| 1441 | 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); | |
| 1445 | ||
| 1446 | const elem_rl: ResultLoc = .{ .ty = elem_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); | |
| 1413 | var extra_index = try reserveExtra(astgen, len); | |
| 1414 | if (array_ty_inst != .none) { | |
| 1415 | astgen.extra.items[extra_index] = @enumToInt(array_ty_inst); | |
| 1450 | 1416 | extra_index += 1; |
| 1451 | 1417 | } |
| 1452 | 1418 | |
| 1453 | if (sentinel != .none) { | |
| 1454 | astgen.extra.items[extra_index] = @enumToInt(sentinel); | |
| 1419 | for (elements) |elem_init, i| { | |
| 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 | 1435 | extra_index += 1; |
| 1456 | 1436 | } |
| 1457 | 1437 | |
| 1458 | return try gz.addPlNodePayloadIndex(info.tag, node, payload_index); | |
| 1438 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); | |
| 1459 | 1439 | } |
| 1460 | 1440 | |
| 1461 | 1441 | fn arrayInitExprRlPtr( |
| ... | ... | @@ -2243,8 +2223,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2243 | 2223 | .array_mul, |
| 2244 | 2224 | .array_type, |
| 2245 | 2225 | .array_type_sentinel, |
| 2226 | .elem_type_index, | |
| 2246 | 2227 | .vector_type, |
| 2247 | .elem_type, | |
| 2248 | 2228 | .indexable_ptr_len, |
| 2249 | 2229 | .anyframe_type, |
| 2250 | 2230 | .as, |
| ... | ... | @@ -2347,10 +2327,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2347 | 2327 | .struct_init_anon_ref, |
| 2348 | 2328 | .array_init, |
| 2349 | 2329 | .array_init_anon, |
| 2350 | .array_init_sent, | |
| 2351 | 2330 | .array_init_ref, |
| 2352 | 2331 | .array_init_anon_ref, |
| 2353 | .array_init_sent_ref, | |
| 2354 | 2332 | .union_init, |
| 2355 | 2333 | .field_type, |
| 2356 | 2334 | .field_type_ref, |
src/Sema.zig+64-37| ... | ... | @@ -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,7 +13447,6 @@ 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; |
| ... | ... | @@ -13444,30 +13454,26 @@ fn zirArrayInit( |
| 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); |
src/Zir.zig+6-20| ... | ... | @@ -221,9 +221,9 @@ pub const Inst = struct { |
| 221 | 221 | /// Uses the `pl_node` union field with `Bin` payload. |
| 222 | 222 | /// lhs is length, rhs is element type. |
| 223 | 223 | vector_type, |
| 224 | /// Given an array type, returns the element type. | |
| 225 | /// Uses the `un_node` union field. | |
| 226 | elem_type, | |
| 224 | /// Given an indexable type, returns the type of the element at given index. | |
| 225 | /// Uses the `bin` union field. lhs is the indexable type, rhs is the index. | |
| 226 | elem_type_index, | |
| 227 | 227 | /// Given a pointer to an indexable object, returns the len property. This is |
| 228 | 228 | /// used by for loops. This instruction also emits a for-loop specific compile |
| 229 | 229 | /// error if the indexable object is not indexable. |
| ... | ... | @@ -737,20 +737,12 @@ pub const Inst = struct { |
| 737 | 737 | /// Array initialization syntax. |
| 738 | 738 | /// Uses the `pl_node` field. Payload is `MultiOp`. |
| 739 | 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 | 740 | /// Anonymous array initialization syntax. |
| 745 | 741 | /// Uses the `pl_node` field. Payload is `MultiOp`. |
| 746 | 742 | array_init_anon, |
| 747 | 743 | /// Array initialization syntax, make the result a pointer. |
| 748 | 744 | /// Uses the `pl_node` field. Payload is `MultiOp`. |
| 749 | 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 | 746 | /// Anonymous array initialization syntax, make the result a pointer. |
| 755 | 747 | /// Uses the `pl_node` field. Payload is `MultiOp`. |
| 756 | 748 | array_init_anon_ref, |
| ... | ... | @@ -1019,7 +1011,7 @@ pub const Inst = struct { |
| 1019 | 1011 | .array_type, |
| 1020 | 1012 | .array_type_sentinel, |
| 1021 | 1013 | .vector_type, |
| 1022 | .elem_type, | |
| 1014 | .elem_type_index, | |
| 1023 | 1015 | .indexable_ptr_len, |
| 1024 | 1016 | .anyframe_type, |
| 1025 | 1017 | .as, |
| ... | ... | @@ -1153,10 +1145,8 @@ pub const Inst = struct { |
| 1153 | 1145 | .struct_init_anon, |
| 1154 | 1146 | .struct_init_anon_ref, |
| 1155 | 1147 | .array_init, |
| 1156 | .array_init_sent, | |
| 1157 | 1148 | .array_init_anon, |
| 1158 | 1149 | .array_init_ref, |
| 1159 | .array_init_sent_ref, | |
| 1160 | 1150 | .array_init_anon_ref, |
| 1161 | 1151 | .union_init, |
| 1162 | 1152 | .field_type, |
| ... | ... | @@ -1314,7 +1304,7 @@ pub const Inst = struct { |
| 1314 | 1304 | .array_type, |
| 1315 | 1305 | .array_type_sentinel, |
| 1316 | 1306 | .vector_type, |
| 1317 | .elem_type, | |
| 1307 | .elem_type_index, | |
| 1318 | 1308 | .indexable_ptr_len, |
| 1319 | 1309 | .anyframe_type, |
| 1320 | 1310 | .as, |
| ... | ... | @@ -1426,10 +1416,8 @@ pub const Inst = struct { |
| 1426 | 1416 | .struct_init_anon, |
| 1427 | 1417 | .struct_init_anon_ref, |
| 1428 | 1418 | .array_init, |
| 1429 | .array_init_sent, | |
| 1430 | 1419 | .array_init_anon, |
| 1431 | 1420 | .array_init_ref, |
| 1432 | .array_init_sent_ref, | |
| 1433 | 1421 | .array_init_anon_ref, |
| 1434 | 1422 | .union_init, |
| 1435 | 1423 | .field_type, |
| ... | ... | @@ -1554,7 +1542,7 @@ pub const Inst = struct { |
| 1554 | 1542 | .array_type = .bin, |
| 1555 | 1543 | .array_type_sentinel = .pl_node, |
| 1556 | 1544 | .vector_type = .pl_node, |
| 1557 | .elem_type = .un_node, | |
| 1545 | .elem_type_index = .bin, | |
| 1558 | 1546 | .indexable_ptr_len = .un_node, |
| 1559 | 1547 | .anyframe_type = .un_node, |
| 1560 | 1548 | .as = .bin, |
| ... | ... | @@ -1688,10 +1676,8 @@ pub const Inst = struct { |
| 1688 | 1676 | .struct_init_anon = .pl_node, |
| 1689 | 1677 | .struct_init_anon_ref = .pl_node, |
| 1690 | 1678 | .array_init = .pl_node, |
| 1691 | .array_init_sent = .pl_node, | |
| 1692 | 1679 | .array_init_anon = .pl_node, |
| 1693 | 1680 | .array_init_ref = .pl_node, |
| 1694 | .array_init_sent_ref = .pl_node, | |
| 1695 | 1681 | .array_init_anon_ref = .pl_node, |
| 1696 | 1682 | .union_init = .pl_node, |
| 1697 | 1683 | .type_info = .un_node, |
src/print_zir.zig+11-7| ... | ... | @@ -152,6 +152,8 @@ const Writer = struct { |
| 152 | 152 | .store_to_inferred_ptr, |
| 153 | 153 | => try self.writeBin(stream, inst), |
| 154 | 154 | |
| 155 | .elem_type_index => try self.writeElemTypeIndex(stream, inst), | |
| 156 | ||
| 155 | 157 | .alloc, |
| 156 | 158 | .alloc_mut, |
| 157 | 159 | .alloc_comptime_mut, |
| ... | ... | @@ -226,7 +228,6 @@ const Writer = struct { |
| 226 | 228 | .pop_count, |
| 227 | 229 | .byte_swap, |
| 228 | 230 | .bit_reverse, |
| 229 | .elem_type, | |
| 230 | 231 | .@"resume", |
| 231 | 232 | .@"await", |
| 232 | 233 | .switch_cond, |
| ... | ... | @@ -268,10 +269,6 @@ const Writer = struct { |
| 268 | 269 | .array_init_anon_ref, |
| 269 | 270 | => try self.writeArrayInit(stream, inst), |
| 270 | 271 | |
| 271 | .array_init_sent, | |
| 272 | .array_init_sent_ref, | |
| 273 | => try self.writeArrayInitSent(stream, inst), | |
| 274 | ||
| 275 | 272 | .slice_start => try self.writeSliceStart(stream, inst), |
| 276 | 273 | .slice_end => try self.writeSliceEnd(stream, inst), |
| 277 | 274 | .slice_sentinel => try self.writeSliceSentinel(stream, inst), |
| ... | ... | @@ -543,6 +540,12 @@ const Writer = struct { |
| 543 | 540 | try stream.writeByte(')'); |
| 544 | 541 | } |
| 545 | 542 | |
| 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 | 549 | fn writeUnNode( |
| 547 | 550 | self: *Writer, |
| 548 | 551 | stream: anytype, |
| ... | ... | @@ -2085,8 +2088,9 @@ const Writer = struct { |
| 2085 | 2088 | const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| 2086 | 2089 | const args = self.code.refSlice(extra.end, extra.data.operands_len); |
| 2087 | 2090 | |
| 2088 | try stream.writeAll(".{"); | |
| 2089 | for (args) |arg, i| { | |
| 2091 | try self.writeInstRef(stream, args[0]); | |
| 2092 | try stream.writeAll("{"); | |
| 2093 | for (args[1..]) |arg, i| { | |
| 2090 | 2094 | if (i != 0) try stream.writeAll(", "); |
| 2091 | 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 | 942 | }; |
| 943 | 943 | _ = b; |
| 944 | 944 | } |
| 945 | ||
| 946 | test "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 | ||
| 953 | test "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 | 194 | } |
| 195 | 195 | |
| 196 | 196 | test "initializing tuple with explicit type" { |
| 197 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 198 | ||
| 199 | 197 | const T = @TypeOf(.{ @as(i32, 0), @as(u32, 0) }); |
| 200 | 198 | var a = T{ 0, 0 }; |
| 201 | 199 | _ = a; |