| author | |
| committer | |
| log | 41f3799bf0cfc8241f458094781ba45967e2576e |
| tree | b26beee8643ba7ebac7774898366f6add4667e3b |
| parent | ba0f72363accc19edbfc5a7ae42d5a8970f56f64 |
Previously it emitted an invalid AIR encoding.4 files changed, 63 insertions(+), 43 deletions(-)
src/Sema.zig+20-3| ... | @@ -366,11 +366,21 @@ pub const Block = struct { | ... | @@ -366,11 +366,21 @@ pub const Block = struct { |
| 366 | array_ptr: Air.Inst.Ref, | 366 | array_ptr: Air.Inst.Ref, |
| 367 | elem_index: Air.Inst.Ref, | 367 | elem_index: Air.Inst.Ref, |
| 368 | elem_ptr_ty: Type, | 368 | elem_ptr_ty: Type, |
| 369 | ) !Air.Inst.Ref { | ||
| 370 | const ty_ref = try block.sema.addType(elem_ptr_ty); | ||
| 371 | return block.addPtrElemPtrTypeRef(array_ptr, elem_index, ty_ref); | ||
| 372 | } | ||
| 373 | |||
| 374 | pub fn addPtrElemPtrTypeRef( | ||
| 375 | block: *Block, | ||
| 376 | array_ptr: Air.Inst.Ref, | ||
| 377 | elem_index: Air.Inst.Ref, | ||
| 378 | elem_ptr_ty: Air.Inst.Ref, | ||
| 369 | ) !Air.Inst.Ref { | 379 | ) !Air.Inst.Ref { |
| 370 | return block.addInst(.{ | 380 | return block.addInst(.{ |
| 371 | .tag = .ptr_elem_ptr, | 381 | .tag = .ptr_elem_ptr, |
| 372 | .data = .{ .ty_pl = .{ | 382 | .data = .{ .ty_pl = .{ |
| 373 | .ty = try block.sema.addType(elem_ptr_ty), | 383 | .ty = elem_ptr_ty, |
| 374 | .payload = try block.sema.addExtra(Air.Bin{ | 384 | .payload = try block.sema.addExtra(Air.Bin{ |
| 375 | .lhs = array_ptr, | 385 | .lhs = array_ptr, |
| 376 | .rhs = elem_index, | 386 | .rhs = elem_index, |
| ... | @@ -10538,9 +10548,16 @@ fn zirArrayInit( | ... | @@ -10538,9 +10548,16 @@ fn zirArrayInit( |
| 10538 | }); | 10548 | }); |
| 10539 | const alloc = try block.addTy(.alloc, alloc_ty); | 10549 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 10540 | 10550 | ||
| 10551 | const elem_ptr_ty = try Type.ptr(sema.arena, .{ | ||
| 10552 | .mutable = true, | ||
| 10553 | .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), | ||
| 10554 | .pointee_type = elem_ty, | ||
| 10555 | }); | ||
| 10556 | const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); | ||
| 10557 | |||
| 10541 | for (resolved_args) |arg, i| { | 10558 | for (resolved_args) |arg, i| { |
| 10542 | const index = try sema.addIntUnsigned(Type.initTag(.u64), i); | 10559 | const index = try sema.addIntUnsigned(Type.u64, i); |
| 10543 | const elem_ptr = try block.addBinOp(.ptr_elem_ptr, alloc, index); | 10560 | const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref); |
| 10544 | _ = try block.addBinOp(.store, elem_ptr, arg); | 10561 | _ = try block.addBinOp(.store, elem_ptr, arg); |
| 10545 | } | 10562 | } |
| 10546 | if (is_ref) { | 10563 | if (is_ref) { |
src/type.zig+1| ... | @@ -4511,6 +4511,7 @@ pub const Type = extern union { | ... | @@ -4511,6 +4511,7 @@ pub const Type = extern union { |
| 4511 | 4511 | ||
| 4512 | pub const @"u8" = initTag(.u8); | 4512 | pub const @"u8" = initTag(.u8); |
| 4513 | pub const @"u32" = initTag(.u32); | 4513 | pub const @"u32" = initTag(.u32); |
| 4514 | pub const @"u64" = initTag(.u64); | ||
| 4514 | pub const @"bool" = initTag(.bool); | 4515 | pub const @"bool" = initTag(.bool); |
| 4515 | pub const @"usize" = initTag(.usize); | 4516 | pub const @"usize" = initTag(.usize); |
| 4516 | pub const @"isize" = initTag(.isize); | 4517 | pub const @"isize" = initTag(.isize); |
test/behavior/array_llvm.zig+42| ... | @@ -45,3 +45,45 @@ fn testImplicitCastSingleItemPtr() !void { | ... | @@ -45,3 +45,45 @@ fn testImplicitCastSingleItemPtr() !void { |
| 45 | slice[0] += 1; | 45 | slice[0] += 1; |
| 46 | try expect(byte == 101); | 46 | try expect(byte == 101); |
| 47 | } | 47 | } |
| 48 | |||
| 49 | fn testArrayByValAtComptime(b: [2]u8) u8 { | ||
| 50 | return b[0]; | ||
| 51 | } | ||
| 52 | |||
| 53 | test "comptime evaluating function that takes array by value" { | ||
| 54 | const arr = [_]u8{ 1, 2 }; | ||
| 55 | const x = comptime testArrayByValAtComptime(arr); | ||
| 56 | const y = comptime testArrayByValAtComptime(arr); | ||
| 57 | try expect(x == 1); | ||
| 58 | try expect(y == 1); | ||
| 59 | } | ||
| 60 | |||
| 61 | test "runtime initialize array elem and then implicit cast to slice" { | ||
| 62 | var two: i32 = 2; | ||
| 63 | const x: []const i32 = &[_]i32{two}; | ||
| 64 | try expect(x[0] == 2); | ||
| 65 | } | ||
| 66 | |||
| 67 | test "array literal as argument to function" { | ||
| 68 | const S = struct { | ||
| 69 | fn entry(two: i32) !void { | ||
| 70 | try foo(&[_]i32{ 1, 2, 3 }); | ||
| 71 | try foo(&[_]i32{ 1, two, 3 }); | ||
| 72 | try foo2(true, &[_]i32{ 1, 2, 3 }); | ||
| 73 | try foo2(true, &[_]i32{ 1, two, 3 }); | ||
| 74 | } | ||
| 75 | fn foo(x: []const i32) !void { | ||
| 76 | try expect(x[0] == 1); | ||
| 77 | try expect(x[1] == 2); | ||
| 78 | try expect(x[2] == 3); | ||
| 79 | } | ||
| 80 | fn foo2(trash: bool, x: []const i32) !void { | ||
| 81 | try expect(trash); | ||
| 82 | try expect(x[0] == 1); | ||
| 83 | try expect(x[1] == 2); | ||
| 84 | try expect(x[2] == 3); | ||
| 85 | } | ||
| 86 | }; | ||
| 87 | try S.entry(2); | ||
| 88 | comptime try S.entry(2); | ||
| 89 | } |
test/behavior/array_stage1.zig-40| ... | @@ -4,46 +4,6 @@ const mem = std.mem; | ... | @@ -4,46 +4,6 @@ const mem = std.mem; |
| 4 | const expect = testing.expect; | 4 | const expect = testing.expect; |
| 5 | const expectEqual = testing.expectEqual; | 5 | const expectEqual = testing.expectEqual; |
| 6 | 6 | ||
| 7 | fn testArrayByValAtComptime(b: [2]u8) u8 { | ||
| 8 | return b[0]; | ||
| 9 | } | ||
| 10 | |||
| 11 | test "comptime evaluating function that takes array by value" { | ||
| 12 | const arr = [_]u8{ 0, 1 }; | ||
| 13 | _ = comptime testArrayByValAtComptime(arr); | ||
| 14 | _ = comptime testArrayByValAtComptime(arr); | ||
| 15 | } | ||
| 16 | |||
| 17 | test "runtime initialize array elem and then implicit cast to slice" { | ||
| 18 | var two: i32 = 2; | ||
| 19 | const x: []const i32 = &[_]i32{two}; | ||
| 20 | try expect(x[0] == 2); | ||
| 21 | } | ||
| 22 | |||
| 23 | test "array literal as argument to function" { | ||
| 24 | const S = struct { | ||
| 25 | fn entry(two: i32) !void { | ||
| 26 | try foo(&[_]i32{ 1, 2, 3 }); | ||
| 27 | try foo(&[_]i32{ 1, two, 3 }); | ||
| 28 | try foo2(true, &[_]i32{ 1, 2, 3 }); | ||
| 29 | try foo2(true, &[_]i32{ 1, two, 3 }); | ||
| 30 | } | ||
| 31 | fn foo(x: []const i32) !void { | ||
| 32 | try expect(x[0] == 1); | ||
| 33 | try expect(x[1] == 2); | ||
| 34 | try expect(x[2] == 3); | ||
| 35 | } | ||
| 36 | fn foo2(trash: bool, x: []const i32) !void { | ||
| 37 | try expect(trash); | ||
| 38 | try expect(x[0] == 1); | ||
| 39 | try expect(x[1] == 2); | ||
| 40 | try expect(x[2] == 3); | ||
| 41 | } | ||
| 42 | }; | ||
| 43 | try S.entry(2); | ||
| 44 | comptime try S.entry(2); | ||
| 45 | } | ||
| 46 | |||
| 47 | test "double nested array to const slice cast in array literal" { | 7 | test "double nested array to const slice cast in array literal" { |
| 48 | const S = struct { | 8 | const S = struct { |
| 49 | fn entry(two: i32) !void { | 9 | fn entry(two: i32) !void { |