| author | |
| committer | |
| log | 850b053ea6b7d6f0f5e0e8dbcf37080ca012024f |
| tree | 8b69d615d0c9172ccce051c8b87e73deddf1c845 |
| parent | c710d5eefe3f83226f1651947239730e77af43cb |
| parent | 67449b659dc752b6cc6d9359637af687a4618609 |
| signature |
stage 2 stuff5 files changed, 118 insertions(+), 71 deletions(-)
src/Sema.zig+48-2| ... | ... | @@ -3888,6 +3888,14 @@ fn analyzeCall( |
| 3888 | 3888 | |
| 3889 | 3889 | if (is_comptime_call) { |
| 3890 | 3890 | const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, casted_arg); |
| 3891 | switch (arg_val.tag()) { | |
| 3892 | .generic_poison, .generic_poison_type => { | |
| 3893 | // This function is currently evaluated as part of an as-of-yet unresolvable | |
| 3894 | // parameter or return type. | |
| 3895 | return error.GenericPoison; | |
| 3896 | }, | |
| 3897 | else => {}, | |
| 3898 | } | |
| 3891 | 3899 | memoized_call_key.args[arg_i] = .{ |
| 3892 | 3900 | .ty = param_ty, |
| 3893 | 3901 | .val = arg_val, |
| ... | ... | @@ -3905,6 +3913,14 @@ fn analyzeCall( |
| 3905 | 3913 | if (is_comptime_call) { |
| 3906 | 3914 | const arg_src = call_src; // TODO: better source location |
| 3907 | 3915 | const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, uncasted_arg); |
| 3916 | switch (arg_val.tag()) { | |
| 3917 | .generic_poison, .generic_poison_type => { | |
| 3918 | // This function is currently evaluated as part of an as-of-yet unresolvable | |
| 3919 | // parameter or return type. | |
| 3920 | return error.GenericPoison; | |
| 3921 | }, | |
| 3922 | else => {}, | |
| 3923 | } | |
| 3908 | 3924 | memoized_call_key.args[arg_i] = .{ |
| 3909 | 3925 | .ty = sema.typeOf(uncasted_arg), |
| 3910 | 3926 | .val = arg_val, |
| ... | ... | @@ -10253,11 +10269,41 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 10253 | 10269 | var buffer: Value.ToTypeBuffer = undefined; |
| 10254 | 10270 | const child_ty = child_val.toType(&buffer); |
| 10255 | 10271 | |
| 10256 | const ty = try Type.vector(sema.arena, len, child_ty); | |
| 10272 | const ty = try Type.vector(sema.arena, len, try child_ty.copy(sema.arena)); | |
| 10257 | 10273 | return sema.addType(ty); |
| 10258 | 10274 | }, |
| 10259 | 10275 | .Float => return sema.fail(block, src, "TODO: Sema.zirReify for Float", .{}), |
| 10260 | .Pointer => return sema.fail(block, src, "TODO: Sema.zirReify for Pointer", .{}), | |
| 10276 | .Pointer => { | |
| 10277 | const struct_val = union_val.val.castTag(.@"struct").?.data; | |
| 10278 | // TODO use reflection instead of magic numbers here | |
| 10279 | const size_val = struct_val[0]; | |
| 10280 | const is_const_val = struct_val[1]; | |
| 10281 | const is_volatile_val = struct_val[2]; | |
| 10282 | const alignment_val = struct_val[3]; | |
| 10283 | const address_space_val = struct_val[4]; | |
| 10284 | const child_val = struct_val[5]; | |
| 10285 | const is_allowzero_val = struct_val[6]; | |
| 10286 | const sentinel_val = struct_val[7]; | |
| 10287 | ||
| 10288 | var buffer: Value.ToTypeBuffer = undefined; | |
| 10289 | const child_ty = child_val.toType(&buffer); | |
| 10290 | ||
| 10291 | if (!sentinel_val.isNull()) { | |
| 10292 | return sema.fail(block, src, "TODO: implement zirReify for pointer with non-null sentinel", .{}); | |
| 10293 | } | |
| 10294 | ||
| 10295 | const ty = try Type.ptr(sema.arena, .{ | |
| 10296 | .size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size), | |
| 10297 | .mutable = !is_const_val.toBool(), | |
| 10298 | .@"volatile" = is_volatile_val.toBool(), | |
| 10299 | .@"align" = @intCast(u8, alignment_val.toUnsignedInt()), // TODO: Validate this value. | |
| 10300 | .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace), | |
| 10301 | .pointee_type = try child_ty.copy(sema.arena), | |
| 10302 | .@"allowzero" = is_allowzero_val.toBool(), | |
| 10303 | .sentinel = null, | |
| 10304 | }); | |
| 10305 | return sema.addType(ty); | |
| 10306 | }, | |
| 10261 | 10307 | .Array => return sema.fail(block, src, "TODO: Sema.zirReify for Array", .{}), |
| 10262 | 10308 | .Struct => return sema.fail(block, src, "TODO: Sema.zirReify for Struct", .{}), |
| 10263 | 10309 | .Optional => return sema.fail(block, src, "TODO: Sema.zirReify for Optional", .{}), |
test/behavior/type.zig+45| ... | ... | @@ -57,3 +57,48 @@ test "Type.EnumLiteral" { |
| 57 | 57 | @TypeOf(.Dummy), |
| 58 | 58 | }); |
| 59 | 59 | } |
| 60 | ||
| 61 | test "Type.Pointer" { | |
| 62 | try testTypes(&[_]type{ | |
| 63 | // One Value Pointer Types | |
| 64 | *u8, *const u8, | |
| 65 | *volatile u8, *const volatile u8, | |
| 66 | *align(4) u8, *align(4) const u8, | |
| 67 | *align(4) volatile u8, *align(4) const volatile u8, | |
| 68 | *align(8) u8, *align(8) const u8, | |
| 69 | *align(8) volatile u8, *align(8) const volatile u8, | |
| 70 | *allowzero u8, *allowzero const u8, | |
| 71 | *allowzero volatile u8, *allowzero const volatile u8, | |
| 72 | *allowzero align(4) u8, *allowzero align(4) const u8, | |
| 73 | *allowzero align(4) volatile u8, *allowzero align(4) const volatile u8, | |
| 74 | // Many Values Pointer Types | |
| 75 | [*]u8, [*]const u8, | |
| 76 | [*]volatile u8, [*]const volatile u8, | |
| 77 | [*]align(4) u8, [*]align(4) const u8, | |
| 78 | [*]align(4) volatile u8, [*]align(4) const volatile u8, | |
| 79 | [*]align(8) u8, [*]align(8) const u8, | |
| 80 | [*]align(8) volatile u8, [*]align(8) const volatile u8, | |
| 81 | [*]allowzero u8, [*]allowzero const u8, | |
| 82 | [*]allowzero volatile u8, [*]allowzero const volatile u8, | |
| 83 | [*]allowzero align(4) u8, [*]allowzero align(4) const u8, | |
| 84 | [*]allowzero align(4) volatile u8, [*]allowzero align(4) const volatile u8, | |
| 85 | // Slice Types | |
| 86 | []u8, []const u8, | |
| 87 | []volatile u8, []const volatile u8, | |
| 88 | []align(4) u8, []align(4) const u8, | |
| 89 | []align(4) volatile u8, []align(4) const volatile u8, | |
| 90 | []align(8) u8, []align(8) const u8, | |
| 91 | []align(8) volatile u8, []align(8) const volatile u8, | |
| 92 | []allowzero u8, []allowzero const u8, | |
| 93 | []allowzero volatile u8, []allowzero const volatile u8, | |
| 94 | []allowzero align(4) u8, []allowzero align(4) const u8, | |
| 95 | []allowzero align(4) volatile u8, []allowzero align(4) const volatile u8, | |
| 96 | // C Pointer Types | |
| 97 | [*c]u8, [*c]const u8, | |
| 98 | [*c]volatile u8, [*c]const volatile u8, | |
| 99 | [*c]align(4) u8, [*c]align(4) const u8, | |
| 100 | [*c]align(4) volatile u8, [*c]align(4) const volatile u8, | |
| 101 | [*c]align(8) u8, [*c]align(8) const u8, | |
| 102 | [*c]align(8) volatile u8, [*c]align(8) const volatile u8, | |
| 103 | }); | |
| 104 | } |
test/behavior/type_info.zig+23| ... | ... | @@ -34,3 +34,26 @@ fn testOptional() !void { |
| 34 | 34 | try expect(null_info == .Optional); |
| 35 | 35 | try expect(null_info.Optional.child == void); |
| 36 | 36 | } |
| 37 | ||
| 38 | test "type info: C pointer type info" { | |
| 39 | try testCPtr(); | |
| 40 | comptime try testCPtr(); | |
| 41 | } | |
| 42 | ||
| 43 | fn testCPtr() !void { | |
| 44 | const ptr_info = @typeInfo([*c]align(4) const i8); | |
| 45 | try expect(ptr_info == .Pointer); | |
| 46 | try expect(ptr_info.Pointer.size == .C); | |
| 47 | try expect(ptr_info.Pointer.is_const); | |
| 48 | try expect(!ptr_info.Pointer.is_volatile); | |
| 49 | try expect(ptr_info.Pointer.alignment == 4); | |
| 50 | try expect(ptr_info.Pointer.child == i8); | |
| 51 | } | |
| 52 | ||
| 53 | test "type info: value is correctly copied" { | |
| 54 | comptime { | |
| 55 | var ptrInfo = @typeInfo([]u32); | |
| 56 | ptrInfo.Pointer.size = .One; | |
| 57 | try expect(@typeInfo([]u32).Pointer.size == .Slice); | |
| 58 | } | |
| 59 | } |
test/behavior/type_info_stage1.zig+1-24| ... | ... | @@ -68,21 +68,6 @@ fn testNullTerminatedPtr() !void { |
| 68 | 68 | try expect(@typeInfo([:0]u8).Pointer.sentinel != null); |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | test "type info: C pointer type info" { | |
| 72 | try testCPtr(); | |
| 73 | comptime try testCPtr(); | |
| 74 | } | |
| 75 | ||
| 76 | fn testCPtr() !void { | |
| 77 | const ptr_info = @typeInfo([*c]align(4) const i8); | |
| 78 | try expect(ptr_info == .Pointer); | |
| 79 | try expect(ptr_info.Pointer.size == .C); | |
| 80 | try expect(ptr_info.Pointer.is_const); | |
| 81 | try expect(!ptr_info.Pointer.is_volatile); | |
| 82 | try expect(ptr_info.Pointer.alignment == 4); | |
| 83 | try expect(ptr_info.Pointer.child == i8); | |
| 84 | } | |
| 85 | ||
| 86 | 71 | test "type info: slice type info" { |
| 87 | 72 | try testSlice(); |
| 88 | 73 | comptime try testSlice(); |
| ... | ... | @@ -395,7 +380,7 @@ test "@typeInfo does not force declarations into existence" { |
| 395 | 380 | comptime try expect(@typeInfo(S).Struct.fields.len == 1); |
| 396 | 381 | } |
| 397 | 382 | |
| 398 | test "defaut value for a var-typed field" { | |
| 383 | test "default value for a var-typed field" { | |
| 399 | 384 | const S = struct { x: anytype }; |
| 400 | 385 | try expect(@typeInfo(S).Struct.fields[0].default_value == null); |
| 401 | 386 | } |
| ... | ... | @@ -413,14 +398,6 @@ test "type info for async frames" { |
| 413 | 398 | } |
| 414 | 399 | } |
| 415 | 400 | |
| 416 | test "type info: value is correctly copied" { | |
| 417 | comptime { | |
| 418 | var ptrInfo = @typeInfo([]u32); | |
| 419 | ptrInfo.Pointer.size = .One; | |
| 420 | try expect(@typeInfo([]u32).Pointer.size == .Slice); | |
| 421 | } | |
| 422 | } | |
| 423 | ||
| 424 | 401 | test "Declarations are returned in declaration order" { |
| 425 | 402 | const S = struct { |
| 426 | 403 | const a = 1; |
test/behavior/type_stage1.zig+1-45| ... | ... | @@ -17,51 +17,6 @@ test "Type.Float" { |
| 17 | 17 | try testTypes(&[_]type{ f16, f32, f64, f128 }); |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | test "Type.Pointer" { | |
| 21 | try testTypes(&[_]type{ | |
| 22 | // One Value Pointer Types | |
| 23 | *u8, *const u8, | |
| 24 | *volatile u8, *const volatile u8, | |
| 25 | *align(4) u8, *align(4) const u8, | |
| 26 | *align(4) volatile u8, *align(4) const volatile u8, | |
| 27 | *align(8) u8, *align(8) const u8, | |
| 28 | *align(8) volatile u8, *align(8) const volatile u8, | |
| 29 | *allowzero u8, *allowzero const u8, | |
| 30 | *allowzero volatile u8, *allowzero const volatile u8, | |
| 31 | *allowzero align(4) u8, *allowzero align(4) const u8, | |
| 32 | *allowzero align(4) volatile u8, *allowzero align(4) const volatile u8, | |
| 33 | // Many Values Pointer Types | |
| 34 | [*]u8, [*]const u8, | |
| 35 | [*]volatile u8, [*]const volatile u8, | |
| 36 | [*]align(4) u8, [*]align(4) const u8, | |
| 37 | [*]align(4) volatile u8, [*]align(4) const volatile u8, | |
| 38 | [*]align(8) u8, [*]align(8) const u8, | |
| 39 | [*]align(8) volatile u8, [*]align(8) const volatile u8, | |
| 40 | [*]allowzero u8, [*]allowzero const u8, | |
| 41 | [*]allowzero volatile u8, [*]allowzero const volatile u8, | |
| 42 | [*]allowzero align(4) u8, [*]allowzero align(4) const u8, | |
| 43 | [*]allowzero align(4) volatile u8, [*]allowzero align(4) const volatile u8, | |
| 44 | // Slice Types | |
| 45 | []u8, []const u8, | |
| 46 | []volatile u8, []const volatile u8, | |
| 47 | []align(4) u8, []align(4) const u8, | |
| 48 | []align(4) volatile u8, []align(4) const volatile u8, | |
| 49 | []align(8) u8, []align(8) const u8, | |
| 50 | []align(8) volatile u8, []align(8) const volatile u8, | |
| 51 | []allowzero u8, []allowzero const u8, | |
| 52 | []allowzero volatile u8, []allowzero const volatile u8, | |
| 53 | []allowzero align(4) u8, []allowzero align(4) const u8, | |
| 54 | []allowzero align(4) volatile u8, []allowzero align(4) const volatile u8, | |
| 55 | // C Pointer Types | |
| 56 | [*c]u8, [*c]const u8, | |
| 57 | [*c]volatile u8, [*c]const volatile u8, | |
| 58 | [*c]align(4) u8, [*c]align(4) const u8, | |
| 59 | [*c]align(4) volatile u8, [*c]align(4) const volatile u8, | |
| 60 | [*c]align(8) u8, [*c]align(8) const u8, | |
| 61 | [*c]align(8) volatile u8, [*c]align(8) const volatile u8, | |
| 62 | }); | |
| 63 | } | |
| 64 | ||
| 65 | 20 | test "Type.Array" { |
| 66 | 21 | try testing.expect([123]u8 == @Type(TypeInfo{ |
| 67 | 22 | .Array = TypeInfo.Array{ |
| ... | ... | @@ -102,6 +57,7 @@ test "@Type create slice with null sentinel" { |
| 102 | 57 | }); |
| 103 | 58 | try testing.expect(Slice == []align(8) const *i32); |
| 104 | 59 | } |
| 60 | ||
| 105 | 61 | test "@Type picks up the sentinel value from TypeInfo" { |
| 106 | 62 | try testTypes(&[_]type{ |
| 107 | 63 | [11:0]u8, [4:10]u8, |