mirror of
https://github.com/ziglang/zig.git
synced 2024-11-17 01:23:54 +00:00
Sema: fix array_init with runtime element
Previously it emitted an invalid AIR encoding.
This commit is contained in:
parent
ba0f72363a
commit
41f3799bf0
23
src/Sema.zig
23
src/Sema.zig
@ -366,11 +366,21 @@ pub const Block = struct {
|
||||
array_ptr: Air.Inst.Ref,
|
||||
elem_index: Air.Inst.Ref,
|
||||
elem_ptr_ty: Type,
|
||||
) !Air.Inst.Ref {
|
||||
const ty_ref = try block.sema.addType(elem_ptr_ty);
|
||||
return block.addPtrElemPtrTypeRef(array_ptr, elem_index, ty_ref);
|
||||
}
|
||||
|
||||
pub fn addPtrElemPtrTypeRef(
|
||||
block: *Block,
|
||||
array_ptr: Air.Inst.Ref,
|
||||
elem_index: Air.Inst.Ref,
|
||||
elem_ptr_ty: Air.Inst.Ref,
|
||||
) !Air.Inst.Ref {
|
||||
return block.addInst(.{
|
||||
.tag = .ptr_elem_ptr,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = try block.sema.addType(elem_ptr_ty),
|
||||
.ty = elem_ptr_ty,
|
||||
.payload = try block.sema.addExtra(Air.Bin{
|
||||
.lhs = array_ptr,
|
||||
.rhs = elem_index,
|
||||
@ -10538,9 +10548,16 @@ fn zirArrayInit(
|
||||
});
|
||||
const alloc = try block.addTy(.alloc, alloc_ty);
|
||||
|
||||
const elem_ptr_ty = try Type.ptr(sema.arena, .{
|
||||
.mutable = true,
|
||||
.@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
.pointee_type = elem_ty,
|
||||
});
|
||||
const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
|
||||
|
||||
for (resolved_args) |arg, i| {
|
||||
const index = try sema.addIntUnsigned(Type.initTag(.u64), i);
|
||||
const elem_ptr = try block.addBinOp(.ptr_elem_ptr, alloc, index);
|
||||
const index = try sema.addIntUnsigned(Type.u64, i);
|
||||
const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);
|
||||
_ = try block.addBinOp(.store, elem_ptr, arg);
|
||||
}
|
||||
if (is_ref) {
|
||||
|
@ -4511,6 +4511,7 @@ pub const Type = extern union {
|
||||
|
||||
pub const @"u8" = initTag(.u8);
|
||||
pub const @"u32" = initTag(.u32);
|
||||
pub const @"u64" = initTag(.u64);
|
||||
pub const @"bool" = initTag(.bool);
|
||||
pub const @"usize" = initTag(.usize);
|
||||
pub const @"isize" = initTag(.isize);
|
||||
|
@ -45,3 +45,45 @@ fn testImplicitCastSingleItemPtr() !void {
|
||||
slice[0] += 1;
|
||||
try expect(byte == 101);
|
||||
}
|
||||
|
||||
fn testArrayByValAtComptime(b: [2]u8) u8 {
|
||||
return b[0];
|
||||
}
|
||||
|
||||
test "comptime evaluating function that takes array by value" {
|
||||
const arr = [_]u8{ 1, 2 };
|
||||
const x = comptime testArrayByValAtComptime(arr);
|
||||
const y = comptime testArrayByValAtComptime(arr);
|
||||
try expect(x == 1);
|
||||
try expect(y == 1);
|
||||
}
|
||||
|
||||
test "runtime initialize array elem and then implicit cast to slice" {
|
||||
var two: i32 = 2;
|
||||
const x: []const i32 = &[_]i32{two};
|
||||
try expect(x[0] == 2);
|
||||
}
|
||||
|
||||
test "array literal as argument to function" {
|
||||
const S = struct {
|
||||
fn entry(two: i32) !void {
|
||||
try foo(&[_]i32{ 1, 2, 3 });
|
||||
try foo(&[_]i32{ 1, two, 3 });
|
||||
try foo2(true, &[_]i32{ 1, 2, 3 });
|
||||
try foo2(true, &[_]i32{ 1, two, 3 });
|
||||
}
|
||||
fn foo(x: []const i32) !void {
|
||||
try expect(x[0] == 1);
|
||||
try expect(x[1] == 2);
|
||||
try expect(x[2] == 3);
|
||||
}
|
||||
fn foo2(trash: bool, x: []const i32) !void {
|
||||
try expect(trash);
|
||||
try expect(x[0] == 1);
|
||||
try expect(x[1] == 2);
|
||||
try expect(x[2] == 3);
|
||||
}
|
||||
};
|
||||
try S.entry(2);
|
||||
comptime try S.entry(2);
|
||||
}
|
||||
|
@ -4,46 +4,6 @@ const mem = std.mem;
|
||||
const expect = testing.expect;
|
||||
const expectEqual = testing.expectEqual;
|
||||
|
||||
fn testArrayByValAtComptime(b: [2]u8) u8 {
|
||||
return b[0];
|
||||
}
|
||||
|
||||
test "comptime evaluating function that takes array by value" {
|
||||
const arr = [_]u8{ 0, 1 };
|
||||
_ = comptime testArrayByValAtComptime(arr);
|
||||
_ = comptime testArrayByValAtComptime(arr);
|
||||
}
|
||||
|
||||
test "runtime initialize array elem and then implicit cast to slice" {
|
||||
var two: i32 = 2;
|
||||
const x: []const i32 = &[_]i32{two};
|
||||
try expect(x[0] == 2);
|
||||
}
|
||||
|
||||
test "array literal as argument to function" {
|
||||
const S = struct {
|
||||
fn entry(two: i32) !void {
|
||||
try foo(&[_]i32{ 1, 2, 3 });
|
||||
try foo(&[_]i32{ 1, two, 3 });
|
||||
try foo2(true, &[_]i32{ 1, 2, 3 });
|
||||
try foo2(true, &[_]i32{ 1, two, 3 });
|
||||
}
|
||||
fn foo(x: []const i32) !void {
|
||||
try expect(x[0] == 1);
|
||||
try expect(x[1] == 2);
|
||||
try expect(x[2] == 3);
|
||||
}
|
||||
fn foo2(trash: bool, x: []const i32) !void {
|
||||
try expect(trash);
|
||||
try expect(x[0] == 1);
|
||||
try expect(x[1] == 2);
|
||||
try expect(x[2] == 3);
|
||||
}
|
||||
};
|
||||
try S.entry(2);
|
||||
comptime try S.entry(2);
|
||||
}
|
||||
|
||||
test "double nested array to const slice cast in array literal" {
|
||||
const S = struct {
|
||||
fn entry(two: i32) !void {
|
||||
|
Loading…
Reference in New Issue
Block a user