| author | |
| committer | |
| log | 0e8307789a3de41759e68c7c04c130889e277991 |
| tree | 68d53b0b5669c002f26937d8f38244aed18c8ec2 |
| parent | c7b778992ec539e237d8afa7c105dcbad7ee280c |
5 files changed, 141 insertions(+), 29 deletions(-)
src/AstGen.zig+50-18| ... | @@ -1273,8 +1273,14 @@ fn arrayInitExpr( | ... | @@ -1273,8 +1273,14 @@ fn arrayInitExpr( |
| 1273 | 1273 | ||
| 1274 | assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init. | 1274 | assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init. |
| 1275 | 1275 | ||
| 1276 | const array_ty: Zir.Inst.Ref = inst: { | 1276 | const types: struct { |
| 1277 | if (array_init.ast.type_expr == 0) break :inst .none; | 1277 | array: Zir.Inst.Ref, |
| 1278 | elem: Zir.Inst.Ref, | ||
| 1279 | } = inst: { | ||
| 1280 | if (array_init.ast.type_expr == 0) break :inst .{ | ||
| 1281 | .array = .none, | ||
| 1282 | .elem = .none, | ||
| 1283 | }; | ||
| 1278 | 1284 | ||
| 1279 | infer: { | 1285 | infer: { |
| 1280 | const array_type: Ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) { | 1286 | const array_type: Ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) { |
| ... | @@ -1289,10 +1295,14 @@ fn arrayInitExpr( | ... | @@ -1289,10 +1295,14 @@ fn arrayInitExpr( |
| 1289 | const len_inst = try gz.addInt(array_init.ast.elements.len); | 1295 | const len_inst = try gz.addInt(array_init.ast.elements.len); |
| 1290 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); | 1296 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); |
| 1291 | if (array_type.ast.sentinel == 0) { | 1297 | if (array_type.ast.sentinel == 0) { |
| 1292 | break :inst try gz.addBin(.array_type, len_inst, elem_type); | 1298 | const array_type_inst = try gz.addBin(.array_type, len_inst, elem_type); |
| 1299 | break :inst .{ | ||
| 1300 | .array = array_type_inst, | ||
| 1301 | .elem = elem_type, | ||
| 1302 | }; | ||
| 1293 | } else { | 1303 | } else { |
| 1294 | 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); |
| 1295 | break :inst try gz.addPlNode( | 1305 | const array_type_inst = try gz.addPlNode( |
| 1296 | .array_type_sentinel, | 1306 | .array_type_sentinel, |
| 1297 | array_init.ast.type_expr, | 1307 | array_init.ast.type_expr, |
| 1298 | Zir.Inst.ArrayTypeSentinel{ | 1308 | Zir.Inst.ArrayTypeSentinel{ |
| ... | @@ -1301,12 +1311,19 @@ fn arrayInitExpr( | ... | @@ -1301,12 +1311,19 @@ fn arrayInitExpr( |
| 1301 | .sentinel = sentinel, | 1311 | .sentinel = sentinel, |
| 1302 | }, | 1312 | }, |
| 1303 | ); | 1313 | ); |
| 1314 | break :inst .{ | ||
| 1315 | .array = array_type_inst, | ||
| 1316 | .elem = elem_type, | ||
| 1317 | }; | ||
| 1304 | } | 1318 | } |
| 1305 | } | 1319 | } |
| 1306 | } | 1320 | } |
| 1307 | 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); |
| 1308 | _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node); | 1322 | _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node); |
| 1309 | break :inst array_type_inst; | 1323 | break :inst .{ |
| 1324 | .array = array_type_inst, | ||
| 1325 | .elem = .none, | ||
| 1326 | }; | ||
| 1310 | }; | 1327 | }; |
| 1311 | 1328 | ||
| 1312 | switch (rl) { | 1329 | switch (rl) { |
| ... | @@ -1318,40 +1335,40 @@ fn arrayInitExpr( | ... | @@ -1318,40 +1335,40 @@ fn arrayInitExpr( |
| 1318 | return Zir.Inst.Ref.void_value; | 1335 | return Zir.Inst.Ref.void_value; |
| 1319 | }, | 1336 | }, |
| 1320 | .ref => { | 1337 | .ref => { |
| 1321 | const tag: Zir.Inst.Tag = if (array_ty != .none) .array_init_ref else .array_init_anon_ref; | 1338 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init_ref else .array_init_anon_ref; |
| 1322 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, array_ty, tag); | 1339 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1323 | }, | 1340 | }, |
| 1324 | .none => { | 1341 | .none => { |
| 1325 | const tag: Zir.Inst.Tag = if (array_ty != .none) .array_init else .array_init_anon; | 1342 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; |
| 1326 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, array_ty, tag); | 1343 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1327 | }, | 1344 | }, |
| 1328 | .ty, .coerced_ty => { | 1345 | .ty, .coerced_ty => { |
| 1329 | const tag: Zir.Inst.Tag = if (array_ty != .none) .array_init else .array_init_anon; | 1346 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; |
| 1330 | const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, array_ty, tag); | 1347 | const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1331 | return rvalue(gz, rl, result, node); | 1348 | return rvalue(gz, rl, result, node); |
| 1332 | }, | 1349 | }, |
| 1333 | .ptr => |ptr_inst| { | 1350 | .ptr => |ptr_inst| { |
| 1334 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, array_ty); | 1351 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array); |
| 1335 | }, | 1352 | }, |
| 1336 | .inferred_ptr => |ptr_inst| { | 1353 | .inferred_ptr => |ptr_inst| { |
| 1337 | if (array_ty == .none) { | 1354 | if (types.array == .none) { |
| 1338 | // We treat this case differently so that we don't get a crash when | 1355 | // We treat this case differently so that we don't get a crash when |
| 1339 | // analyzing array_base_ptr against an alloc_inferred_mut. | 1356 | // analyzing array_base_ptr against an alloc_inferred_mut. |
| 1340 | // See corresponding logic in structInitExpr. | 1357 | // See corresponding logic in structInitExpr. |
| 1341 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); | 1358 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); |
| 1342 | return rvalue(gz, rl, result, node); | 1359 | return rvalue(gz, rl, result, node); |
| 1343 | } else { | 1360 | } else { |
| 1344 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, array_ty); | 1361 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array); |
| 1345 | } | 1362 | } |
| 1346 | }, | 1363 | }, |
| 1347 | .block_ptr => |block_gz| { | 1364 | .block_ptr => |block_gz| { |
| 1348 | // This condition is here for the same reason as the above condition in `inferred_ptr`. | 1365 | // This condition is here for the same reason as the above condition in `inferred_ptr`. |
| 1349 | // See corresponding logic in structInitExpr. | 1366 | // See corresponding logic in structInitExpr. |
| 1350 | if (array_ty == .none and astgen.isInferred(block_gz.rl_ptr)) { | 1367 | if (types.array == .none and astgen.isInferred(block_gz.rl_ptr)) { |
| 1351 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); | 1368 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); |
| 1352 | return rvalue(gz, rl, result, node); | 1369 | return rvalue(gz, rl, result, node); |
| 1353 | } | 1370 | } |
| 1354 | return arrayInitExprRlPtr(gz, scope, rl, node, block_gz.rl_ptr, array_init.ast.elements, array_ty); | 1371 | return arrayInitExprRlPtr(gz, scope, rl, node, block_gz.rl_ptr, array_init.ast.elements, types.array); |
| 1355 | }, | 1372 | }, |
| 1356 | } | 1373 | } |
| 1357 | } | 1374 | } |
| ... | @@ -1384,6 +1401,7 @@ fn arrayInitExprInner( | ... | @@ -1384,6 +1401,7 @@ fn arrayInitExprInner( |
| 1384 | node: Ast.Node.Index, | 1401 | node: Ast.Node.Index, |
| 1385 | elements: []const Ast.Node.Index, | 1402 | elements: []const Ast.Node.Index, |
| 1386 | array_ty_inst: Zir.Inst.Ref, | 1403 | array_ty_inst: Zir.Inst.Ref, |
| 1404 | elem_ty: Zir.Inst.Ref, | ||
| 1387 | tag: Zir.Inst.Tag, | 1405 | tag: Zir.Inst.Tag, |
| 1388 | ) InnerError!Zir.Inst.Ref { | 1406 | ) InnerError!Zir.Inst.Ref { |
| 1389 | const astgen = gz.astgen; | 1407 | const astgen = gz.astgen; |
| ... | @@ -1398,8 +1416,21 @@ fn arrayInitExprInner( | ... | @@ -1398,8 +1416,21 @@ fn arrayInitExprInner( |
| 1398 | extra_index += 1; | 1416 | extra_index += 1; |
| 1399 | } | 1417 | } |
| 1400 | 1418 | ||
| 1401 | for (elements) |elem_init| { | 1419 | for (elements) |elem_init, i| { |
| 1402 | const elem_ref = try expr(gz, scope, .none, elem_init); | 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); | ||
| 1403 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); | 1434 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| 1404 | extra_index += 1; | 1435 | extra_index += 1; |
| 1405 | } | 1436 | } |
| ... | @@ -2192,6 +2223,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner | ... | @@ -2192,6 +2223,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2192 | .array_mul, | 2223 | .array_mul, |
| 2193 | .array_type, | 2224 | .array_type, |
| 2194 | .array_type_sentinel, | 2225 | .array_type_sentinel, |
| 2226 | .elem_type_index, | ||
| 2195 | .vector_type, | 2227 | .vector_type, |
| 2196 | .indexable_ptr_len, | 2228 | .indexable_ptr_len, |
| 2197 | .anyframe_type, | 2229 | .anyframe_type, |
src/Sema.zig+49-11| ... | @@ -726,6 +726,7 @@ fn analyzeBodyInner( | ... | @@ -726,6 +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_index => try sema.zirElemTypeIndex(block, inst), | ||
| 729 | .enum_literal => try sema.zirEnumLiteral(block, inst), | 730 | .enum_literal => try sema.zirEnumLiteral(block, inst), |
| 730 | .enum_to_int => try sema.zirEnumToInt(block, inst), | 731 | .enum_to_int => try sema.zirEnumToInt(block, inst), |
| 731 | .int_to_enum => try sema.zirIntToEnum(block, inst), | 732 | .int_to_enum => try sema.zirIntToEnum(block, inst), |
| ... | @@ -3021,7 +3022,10 @@ fn zirArrayBasePtr( | ... | @@ -3021,7 +3022,10 @@ fn zirArrayBasePtr( |
| 3021 | const elem_ty = sema.typeOf(base_ptr).childType(); | 3022 | const elem_ty = sema.typeOf(base_ptr).childType(); |
| 3022 | switch (elem_ty.zigTypeTag()) { | 3023 | switch (elem_ty.zigTypeTag()) { |
| 3023 | .Array, .Vector => return base_ptr, | 3024 | .Array, .Vector => return base_ptr, |
| 3024 | .Struct => if (elem_ty.isTuple()) return base_ptr, | 3025 | .Struct => if (elem_ty.isTuple()) { |
| 3026 | // TODO validate element count | ||
| 3027 | return base_ptr; | ||
| 3028 | }, | ||
| 3025 | else => {}, | 3029 | else => {}, |
| 3026 | } | 3030 | } |
| 3027 | return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType()); | 3031 | return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType()); |
| ... | @@ -3062,7 +3066,10 @@ fn validateArrayInitTy( | ... | @@ -3062,7 +3066,10 @@ fn validateArrayInitTy( |
| 3062 | 3066 | ||
| 3063 | switch (ty.zigTypeTag()) { | 3067 | switch (ty.zigTypeTag()) { |
| 3064 | .Array, .Vector => return, | 3068 | .Array, .Vector => return, |
| 3065 | .Struct => if (ty.isTuple()) return, | 3069 | .Struct => if (ty.isTuple()) { |
| 3070 | // TODO validate element count | ||
| 3071 | return; | ||
| 3072 | }, | ||
| 3066 | else => {}, | 3073 | else => {}, |
| 3067 | } | 3074 | } |
| 3068 | return sema.failWithArrayInitNotSupported(block, src, ty); | 3075 | return sema.failWithArrayInitNotSupported(block, src, ty); |
| ... | @@ -5805,12 +5812,17 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -5805,12 +5812,17 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 5805 | return sema.addType(opt_type); | 5812 | return sema.addType(opt_type); |
| 5806 | } | 5813 | } |
| 5807 | 5814 | ||
| 5808 | fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5815 | fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 5809 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 5816 | const bin = sema.code.instructions.items(.data)[inst].bin; |
| 5810 | const src = inst_data.src(); | 5817 | const indexable_ty = try sema.resolveType(block, .unneeded, bin.lhs); |
| 5811 | const array_type = try sema.resolveType(block, src, inst_data.operand); | 5818 | assert(indexable_ty.isIndexable()); // validated by a previous instruction |
| 5812 | const elem_type = array_type.elemType(); | 5819 | if (indexable_ty.zigTypeTag() == .Struct) { |
| 5813 | 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 | } | ||
| 5814 | } | 5826 | } |
| 5815 | 5827 | ||
| 5816 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5828 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -13277,6 +13289,8 @@ fn zirStructInit( | ... | @@ -13277,6 +13289,8 @@ fn zirStructInit( |
| 13277 | try sema.requireRuntimeBlock(block, src); | 13289 | try sema.requireRuntimeBlock(block, src); |
| 13278 | try sema.queueFullTypeResolution(resolved_ty); | 13290 | try sema.queueFullTypeResolution(resolved_ty); |
| 13279 | 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", .{}); | ||
| 13280 | } | 13294 | } |
| 13281 | unreachable; | 13295 | unreachable; |
| 13282 | } | 13296 | } |
| ... | @@ -13447,15 +13461,18 @@ fn zirArrayInit( | ... | @@ -13447,15 +13461,18 @@ fn zirArrayInit( |
| 13447 | 13461 | ||
| 13448 | const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null)); | 13462 | const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null)); |
| 13449 | defer gpa.free(resolved_args); | 13463 | defer gpa.free(resolved_args); |
| 13450 | const elem_ty = array_ty.elemType2(); | ||
| 13451 | for (args[1..]) |arg, i| { | 13464 | for (args[1..]) |arg, i| { |
| 13452 | const resolved_arg = try sema.resolveInst(arg); | 13465 | const resolved_arg = try sema.resolveInst(arg); |
| 13453 | const arg_src = src; // TODO better source location | 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(); | ||
| 13454 | resolved_args[i] = try sema.coerce(block, elem_ty, resolved_arg, arg_src); | 13471 | resolved_args[i] = try sema.coerce(block, elem_ty, resolved_arg, arg_src); |
| 13455 | } | 13472 | } |
| 13456 | 13473 | ||
| 13457 | if (sentinel_val) |some| { | 13474 | if (sentinel_val) |some| { |
| 13458 | resolved_args[resolved_args.len - 1] = try sema.addConstant(elem_ty, some); | 13475 | resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(), some); |
| 13459 | } | 13476 | } |
| 13460 | 13477 | ||
| 13461 | const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| { | 13478 | const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| { |
| ... | @@ -13487,10 +13504,27 @@ fn zirArrayInit( | ... | @@ -13487,10 +13504,27 @@ fn zirArrayInit( |
| 13487 | }); | 13504 | }); |
| 13488 | const alloc = try block.addTy(.alloc, alloc_ty); | 13505 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 13489 | 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 | |||
| 13490 | const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ | 13524 | const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13491 | .mutable = true, | 13525 | .mutable = true, |
| 13492 | .@"addrspace" = target_util.defaultAddressSpace(target, .local), | 13526 | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 13493 | .pointee_type = elem_ty, | 13527 | .pointee_type = array_ty.elemType2(), |
| 13494 | }); | 13528 | }); |
| 13495 | const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); | 13529 | const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); |
| 13496 | 13530 | ||
| ... | @@ -13632,6 +13666,10 @@ fn fieldType( | ... | @@ -13632,6 +13666,10 @@ fn fieldType( |
| 13632 | while (true) { | 13666 | while (true) { |
| 13633 | switch (cur_ty.zigTypeTag()) { | 13667 | switch (cur_ty.zigTypeTag()) { |
| 13634 | .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 | } | ||
| 13635 | const struct_obj = cur_ty.castTag(.@"struct").?.data; | 13673 | const struct_obj = cur_ty.castTag(.@"struct").?.data; |
| 13636 | const field = struct_obj.fields.get(field_name) orelse | 13674 | const field = struct_obj.fields.get(field_name) orelse |
| 13637 | 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| ... | @@ -221,6 +221,9 @@ pub const Inst = struct { | ... | @@ -221,6 +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 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, | ||
| 224 | /// Given a pointer to an indexable object, returns the len property. This is | 227 | /// Given a pointer to an indexable object, returns the len property. This is |
| 225 | /// used by for loops. This instruction also emits a for-loop specific compile | 228 | /// used by for loops. This instruction also emits a for-loop specific compile |
| 226 | /// error if the indexable object is not indexable. | 229 | /// error if the indexable object is not indexable. |
| ... | @@ -1008,6 +1011,7 @@ pub const Inst = struct { | ... | @@ -1008,6 +1011,7 @@ pub const Inst = struct { |
| 1008 | .array_type, | 1011 | .array_type, |
| 1009 | .array_type_sentinel, | 1012 | .array_type_sentinel, |
| 1010 | .vector_type, | 1013 | .vector_type, |
| 1014 | .elem_type_index, | ||
| 1011 | .indexable_ptr_len, | 1015 | .indexable_ptr_len, |
| 1012 | .anyframe_type, | 1016 | .anyframe_type, |
| 1013 | .as, | 1017 | .as, |
| ... | @@ -1300,6 +1304,7 @@ pub const Inst = struct { | ... | @@ -1300,6 +1304,7 @@ pub const Inst = struct { |
| 1300 | .array_type, | 1304 | .array_type, |
| 1301 | .array_type_sentinel, | 1305 | .array_type_sentinel, |
| 1302 | .vector_type, | 1306 | .vector_type, |
| 1307 | .elem_type_index, | ||
| 1303 | .indexable_ptr_len, | 1308 | .indexable_ptr_len, |
| 1304 | .anyframe_type, | 1309 | .anyframe_type, |
| 1305 | .as, | 1310 | .as, |
| ... | @@ -1537,6 +1542,7 @@ pub const Inst = struct { | ... | @@ -1537,6 +1542,7 @@ pub const Inst = struct { |
| 1537 | .array_type = .bin, | 1542 | .array_type = .bin, |
| 1538 | .array_type_sentinel = .pl_node, | 1543 | .array_type_sentinel = .pl_node, |
| 1539 | .vector_type = .pl_node, | 1544 | .vector_type = .pl_node, |
| 1545 | .elem_type_index = .bin, | ||
| 1540 | .indexable_ptr_len = .un_node, | 1546 | .indexable_ptr_len = .un_node, |
| 1541 | .anyframe_type = .un_node, | 1547 | .anyframe_type = .un_node, |
| 1542 | .as = .bin, | 1548 | .as = .bin, |
src/print_zir.zig+8| ... | @@ -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), |
| 154 | 154 | ||
| 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, |
| ... | @@ -538,6 +540,12 @@ const Writer = struct { | ... | @@ -538,6 +540,12 @@ const Writer = struct { |
| 538 | try stream.writeByte(')'); | 540 | try stream.writeByte(')'); |
| 539 | } | 541 | } |
| 540 | 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 | |||
| 541 | fn writeUnNode( | 549 | fn writeUnNode( |
| 542 | self: *Writer, | 550 | self: *Writer, |
| 543 | stream: anytype, | 551 | stream: anytype, |
test/behavior/basic.zig+28| ... | @@ -949,3 +949,31 @@ test "vector initialized with array init syntax has proper type" { | ... | @@ -949,3 +949,31 @@ test "vector initialized with array init syntax has proper type" { |
| 949 | try std.testing.expectEqual(@Vector(4, i32){ -1, -2, -3, -4 }, actual); | 949 | try std.testing.expectEqual(@Vector(4, i32){ -1, -2, -3, -4 }, actual); |
| 950 | } | 950 | } |
| 951 | } | 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 | } |