authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-05 18:07:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:28-07:00
logce3cffbd5a00a6ae44ec3f2c6550de1c52c293c4
treed1e44eae010ba81b362e5342d0530ced3ab71cc7
parent0471638734257d479d21abcb490ed9459df42b9b

fill out more InternPool Type methods

particularly, printing types

4 files changed, 206 insertions(+), 100 deletions(-)

src/Sema.zig+24-8
...@@ -31485,11 +31485,18 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31485,11 +31485,18 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3148531485
31486 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {31486 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
31487 .int_type => false,31487 .int_type => false,
31488 .ptr_type => @panic("TODO"),31488 .ptr_type => |ptr_type| {
31489 .array_type => @panic("TODO"),31489 const child_ty = ptr_type.elem_type.toType();
31490 if (child_ty.zigTypeTag(mod) == .Fn) {
31491 return child_ty.fnInfo().is_generic;
31492 } else {
31493 return sema.resolveTypeRequiresComptime(child_ty);
31494 }
31495 },
31496 .array_type => |array_type| return sema.resolveTypeRequiresComptime(array_type.child.toType()),
31490 .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()),31497 .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()),
31491 .opt_type => @panic("TODO"),31498 .opt_type => |child| return sema.resolveTypeRequiresComptime(child.toType()),
31492 .error_union_type => @panic("TODO"),31499 .error_union_type => |error_union_type| return sema.resolveTypeRequiresComptime(error_union_type.payload_type.toType()),
31493 .simple_type => |t| switch (t) {31500 .simple_type => |t| switch (t) {
31494 .f16,31501 .f16,
31495 .f32,31502 .f32,
...@@ -33528,11 +33535,20 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33528,11 +33535,20 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33528 if (ty.ip_index != .none) {33535 if (ty.ip_index != .none) {
33529 switch (mod.intern_pool.indexToKey(ty.ip_index)) {33536 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
33530 .int_type => return false,33537 .int_type => return false,
33531 .ptr_type => @panic("TODO"),33538 .ptr_type => |ptr_type| {
33532 .array_type => @panic("TODO"),33539 const child_ty = ptr_type.elem_type.toType();
33540 if (child_ty.zigTypeTag(mod) == .Fn) {
33541 return child_ty.fnInfo().is_generic;
33542 } else {
33543 return sema.typeRequiresComptime(child_ty);
33544 }
33545 },
33546 .array_type => |array_type| return sema.typeRequiresComptime(array_type.child.toType()),
33533 .vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()),33547 .vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()),
33534 .opt_type => @panic("TODO"),33548 .opt_type => |child| return sema.typeRequiresComptime(child.toType()),
33535 .error_union_type => @panic("TODO"),33549 .error_union_type => |error_union_type| {
33550 return sema.typeRequiresComptime(error_union_type.payload_type.toType());
33551 },
33536 .simple_type => |t| return switch (t) {33552 .simple_type => |t| return switch (t) {
33537 .f16,33553 .f16,
33538 .f32,33554 .f32,
src/print_air.zig+1-1
...@@ -95,7 +95,7 @@ const Writer = struct {...@@ -95,7 +95,7 @@ const Writer = struct {
95 for (w.air.instructions.items(.tag), 0..) |tag, i| {95 for (w.air.instructions.items(.tag), 0..) |tag, i| {
96 const inst = @intCast(Air.Inst.Index, i);96 const inst = @intCast(Air.Inst.Index, i);
97 switch (tag) {97 switch (tag) {
98 .constant, .const_ty => {98 .constant, .const_ty, .interned => {
99 try w.writeInst(s, inst);99 try w.writeInst(s, inst);
100 try s.writeByte('\n');100 try s.writeByte('\n');
101 },101 },
src/type.zig+143-65
...@@ -1274,11 +1274,77 @@ pub const Type = struct {...@@ -1274,11 +1274,77 @@ pub const Type = struct {
1274 };1274 };
1275 return writer.print("{c}{d}", .{ sign_char, int_type.bits });1275 return writer.print("{c}{d}", .{ sign_char, int_type.bits });
1276 },1276 },
1277 .ptr_type => @panic("TODO"),1277 .ptr_type => {
1278 .array_type => @panic("TODO"),1278 const info = ty.ptrInfo(mod);
1279 .vector_type => @panic("TODO"),1279
1280 .opt_type => @panic("TODO"),1280 if (info.sentinel) |s| switch (info.size) {
1281 .error_union_type => @panic("TODO"),1281 .One, .C => unreachable,
1282 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
1283 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
1284 } else switch (info.size) {
1285 .One => try writer.writeAll("*"),
1286 .Many => try writer.writeAll("[*]"),
1287 .C => try writer.writeAll("[*c]"),
1288 .Slice => try writer.writeAll("[]"),
1289 }
1290 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {
1291 if (info.@"align" != 0) {
1292 try writer.print("align({d}", .{info.@"align"});
1293 } else {
1294 const alignment = info.pointee_type.abiAlignment(mod);
1295 try writer.print("align({d}", .{alignment});
1296 }
1297
1298 if (info.bit_offset != 0 or info.host_size != 0) {
1299 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
1300 }
1301 if (info.vector_index == .runtime) {
1302 try writer.writeAll(":?");
1303 } else if (info.vector_index != .none) {
1304 try writer.print(":{d}", .{@enumToInt(info.vector_index)});
1305 }
1306 try writer.writeAll(") ");
1307 }
1308 if (info.@"addrspace" != .generic) {
1309 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
1310 }
1311 if (!info.mutable) try writer.writeAll("const ");
1312 if (info.@"volatile") try writer.writeAll("volatile ");
1313 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
1314
1315 try print(info.pointee_type, writer, mod);
1316 return;
1317 },
1318 .array_type => |array_type| {
1319 if (array_type.sentinel == .none) {
1320 try writer.print("[{d}]", .{array_type.len});
1321 try print(array_type.child.toType(), writer, mod);
1322 } else {
1323 try writer.print("[{d}:{}]", .{
1324 array_type.len,
1325 array_type.sentinel.toValue().fmtValue(array_type.child.toType(), mod),
1326 });
1327 try print(array_type.child.toType(), writer, mod);
1328 }
1329 return;
1330 },
1331 .vector_type => |vector_type| {
1332 try writer.print("@Vector({d}, ", .{vector_type.len});
1333 try print(vector_type.child.toType(), writer, mod);
1334 try writer.writeAll(")");
1335 return;
1336 },
1337 .opt_type => |child| {
1338 try writer.writeByte('?');
1339 try print(child.toType(), writer, mod);
1340 return;
1341 },
1342 .error_union_type => |error_union_type| {
1343 try print(error_union_type.error_set_type.toType(), writer, mod);
1344 try writer.writeByte('!');
1345 try print(error_union_type.payload_type.toType(), writer, mod);
1346 return;
1347 },
1282 .simple_type => |s| return writer.writeAll(@tagName(s)),1348 .simple_type => |s| return writer.writeAll(@tagName(s)),
1283 .struct_type => @panic("TODO"),1349 .struct_type => @panic("TODO"),
1284 .union_type => @panic("TODO"),1350 .union_type => @panic("TODO"),
...@@ -2055,8 +2121,8 @@ pub const Type = struct {...@@ -2055,8 +2121,8 @@ pub const Type = struct {
2055 return AbiAlignmentAdvanced{ .scalar = alignment };2121 return AbiAlignmentAdvanced{ .scalar = alignment };
2056 },2122 },
20572123
2058 .opt_type => @panic("TODO"),2124 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),
2059 .error_union_type => @panic("TODO"),2125 .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
2060 .simple_type => |t| switch (t) {2126 .simple_type => |t| switch (t) {
2061 .bool,2127 .bool,
2062 .atomic_order,2128 .atomic_order,
...@@ -2157,64 +2223,8 @@ pub const Type = struct {...@@ -2157,64 +2223,8 @@ pub const Type = struct {
21572223
2158 .array, .array_sentinel => return ty.childType(mod).abiAlignmentAdvanced(mod, strat),2224 .array, .array_sentinel => return ty.childType(mod).abiAlignmentAdvanced(mod, strat),
21592225
2160 .optional => {2226 .optional => return abiAlignmentAdvancedOptional(ty, mod, strat),
2161 const child_type = ty.optionalChild(mod);2227 .error_union => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
2162
2163 switch (child_type.zigTypeTag(mod)) {
2164 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
2165 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat),
2166 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },
2167 else => {},
2168 }
2169
2170 switch (strat) {
2171 .eager, .sema => {
2172 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2173 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
2174 else => |e| return e,
2175 })) {
2176 return AbiAlignmentAdvanced{ .scalar = 1 };
2177 }
2178 return child_type.abiAlignmentAdvanced(mod, strat);
2179 },
2180 .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(mod, strat)) {
2181 .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) },
2182 .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
2183 },
2184 }
2185 },
2186
2187 .error_union => {
2188 // This code needs to be kept in sync with the equivalent switch prong
2189 // in abiSizeAdvanced.
2190 const data = ty.castTag(.error_union).?.data;
2191 const code_align = abiAlignment(Type.anyerror, mod);
2192 switch (strat) {
2193 .eager, .sema => {
2194 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2195 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
2196 else => |e| return e,
2197 })) {
2198 return AbiAlignmentAdvanced{ .scalar = code_align };
2199 }
2200 return AbiAlignmentAdvanced{ .scalar = @max(
2201 code_align,
2202 (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar,
2203 ) };
2204 },
2205 .lazy => |arena| {
2206 switch (try data.payload.abiAlignmentAdvanced(mod, strat)) {
2207 .scalar => |payload_align| {
2208 return AbiAlignmentAdvanced{
2209 .scalar = @max(code_align, payload_align),
2210 };
2211 },
2212 .val => {},
2213 }
2214 return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) };
2215 },
2216 }
2217 },
22182228
2219 .@"struct" => {2229 .@"struct" => {
2220 const struct_obj = ty.castTag(.@"struct").?.data;2230 const struct_obj = ty.castTag(.@"struct").?.data;
...@@ -2321,6 +2331,74 @@ pub const Type = struct {...@@ -2321,6 +2331,74 @@ pub const Type = struct {
2321 }2331 }
2322 }2332 }
23232333
2334 fn abiAlignmentAdvancedErrorUnion(
2335 ty: Type,
2336 mod: *const Module,
2337 strat: AbiAlignmentAdvancedStrat,
2338 ) Module.CompileError!AbiAlignmentAdvanced {
2339 // This code needs to be kept in sync with the equivalent switch prong
2340 // in abiSizeAdvanced.
2341 const data = ty.castTag(.error_union).?.data;
2342 const code_align = abiAlignment(Type.anyerror, mod);
2343 switch (strat) {
2344 .eager, .sema => {
2345 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2346 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
2347 else => |e| return e,
2348 })) {
2349 return AbiAlignmentAdvanced{ .scalar = code_align };
2350 }
2351 return AbiAlignmentAdvanced{ .scalar = @max(
2352 code_align,
2353 (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar,
2354 ) };
2355 },
2356 .lazy => |arena| {
2357 switch (try data.payload.abiAlignmentAdvanced(mod, strat)) {
2358 .scalar => |payload_align| {
2359 return AbiAlignmentAdvanced{
2360 .scalar = @max(code_align, payload_align),
2361 };
2362 },
2363 .val => {},
2364 }
2365 return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) };
2366 },
2367 }
2368 }
2369
2370 fn abiAlignmentAdvancedOptional(
2371 ty: Type,
2372 mod: *const Module,
2373 strat: AbiAlignmentAdvancedStrat,
2374 ) Module.CompileError!AbiAlignmentAdvanced {
2375 const target = mod.getTarget();
2376 const child_type = ty.optionalChild(mod);
2377
2378 switch (child_type.zigTypeTag(mod)) {
2379 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
2380 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat),
2381 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },
2382 else => {},
2383 }
2384
2385 switch (strat) {
2386 .eager, .sema => {
2387 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
2388 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
2389 else => |e| return e,
2390 })) {
2391 return AbiAlignmentAdvanced{ .scalar = 1 };
2392 }
2393 return child_type.abiAlignmentAdvanced(mod, strat);
2394 },
2395 .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(mod, strat)) {
2396 .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) },
2397 .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
2398 },
2399 }
2400 }
2401
2324 pub fn abiAlignmentAdvancedUnion(2402 pub fn abiAlignmentAdvancedUnion(
2325 ty: Type,2403 ty: Type,
2326 mod: *const Module,2404 mod: *const Module,
src/value.zig+38-26
...@@ -1848,8 +1848,6 @@ pub const Value = struct {...@@ -1848,8 +1848,6 @@ pub const Value = struct {
1848 /// Asserts the value is comparable.1848 /// Asserts the value is comparable.
1849 /// If opt_sema is null then this function asserts things are resolved and cannot fail.1849 /// If opt_sema is null then this function asserts things are resolved and cannot fail.
1850 pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *const Module, opt_sema: ?*Sema) !std.math.Order {1850 pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *const Module, opt_sema: ?*Sema) !std.math.Order {
1851 const lhs_tag = lhs.tag();
1852 const rhs_tag = rhs.tag();
1853 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);1851 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);
1854 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);1852 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);
1855 switch (lhs_against_zero) {1853 switch (lhs_against_zero) {
...@@ -1866,6 +1864,8 @@ pub const Value = struct {...@@ -1866,6 +1864,8 @@ pub const Value = struct {
1866 const lhs_float = lhs.isFloat();1864 const lhs_float = lhs.isFloat();
1867 const rhs_float = rhs.isFloat();1865 const rhs_float = rhs.isFloat();
1868 if (lhs_float and rhs_float) {1866 if (lhs_float and rhs_float) {
1867 const lhs_tag = lhs.tag();
1868 const rhs_tag = rhs.tag();
1869 if (lhs_tag == rhs_tag) {1869 if (lhs_tag == rhs_tag) {
1870 return switch (lhs.tag()) {1870 return switch (lhs.tag()) {
1871 .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data),1871 .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data),
...@@ -2601,12 +2601,15 @@ pub const Value = struct {...@@ -2601,12 +2601,15 @@ pub const Value = struct {
2601 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),2601 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),
2602 /// this function returns null.2602 /// this function returns null.
2603 pub fn pointerDecl(val: Value) ?Module.Decl.Index {2603 pub fn pointerDecl(val: Value) ?Module.Decl.Index {
2604 return switch (val.tag()) {2604 return switch (val.ip_index) {
2605 .decl_ref_mut => val.castTag(.decl_ref_mut).?.data.decl_index,2605 .none => switch (val.tag()) {
2606 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,2606 .decl_ref_mut => val.castTag(.decl_ref_mut).?.data.decl_index,
2607 .function => val.castTag(.function).?.data.owner_decl,2607 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
2608 .variable => val.castTag(.variable).?.data.owner_decl,2608 .function => val.castTag(.function).?.data.owner_decl,
2609 .decl_ref => val.cast(Payload.Decl).?.data,2609 .variable => val.castTag(.variable).?.data.owner_decl,
2610 .decl_ref => val.cast(Payload.Decl).?.data,
2611 else => null,
2612 },
2610 else => null,2613 else => null,
2611 };2614 };
2612 }2615 }
...@@ -3831,35 +3834,44 @@ pub const Value = struct {...@@ -3831,35 +3834,44 @@ pub const Value = struct {
38313834
3832 /// Returns true if the value is a floating point type and is NaN. Returns false otherwise.3835 /// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
3833 pub fn isNan(val: Value) bool {3836 pub fn isNan(val: Value) bool {
3834 return switch (val.tag()) {3837 return switch (val.ip_index) {
3835 .float_16 => std.math.isNan(val.castTag(.float_16).?.data),3838 .none => switch (val.tag()) {
3836 .float_32 => std.math.isNan(val.castTag(.float_32).?.data),3839 .float_16 => std.math.isNan(val.castTag(.float_16).?.data),
3837 .float_64 => std.math.isNan(val.castTag(.float_64).?.data),3840 .float_32 => std.math.isNan(val.castTag(.float_32).?.data),
3838 .float_80 => std.math.isNan(val.castTag(.float_80).?.data),3841 .float_64 => std.math.isNan(val.castTag(.float_64).?.data),
3839 .float_128 => std.math.isNan(val.castTag(.float_128).?.data),3842 .float_80 => std.math.isNan(val.castTag(.float_80).?.data),
3843 .float_128 => std.math.isNan(val.castTag(.float_128).?.data),
3844 else => false,
3845 },
3840 else => false,3846 else => false,
3841 };3847 };
3842 }3848 }
38433849
3844 /// Returns true if the value is a floating point type and is infinite. Returns false otherwise.3850 /// Returns true if the value is a floating point type and is infinite. Returns false otherwise.
3845 pub fn isInf(val: Value) bool {3851 pub fn isInf(val: Value) bool {
3846 return switch (val.tag()) {3852 return switch (val.ip_index) {
3847 .float_16 => std.math.isInf(val.castTag(.float_16).?.data),3853 .none => switch (val.tag()) {
3848 .float_32 => std.math.isInf(val.castTag(.float_32).?.data),3854 .float_16 => std.math.isInf(val.castTag(.float_16).?.data),
3849 .float_64 => std.math.isInf(val.castTag(.float_64).?.data),3855 .float_32 => std.math.isInf(val.castTag(.float_32).?.data),
3850 .float_80 => std.math.isInf(val.castTag(.float_80).?.data),3856 .float_64 => std.math.isInf(val.castTag(.float_64).?.data),
3851 .float_128 => std.math.isInf(val.castTag(.float_128).?.data),3857 .float_80 => std.math.isInf(val.castTag(.float_80).?.data),
3858 .float_128 => std.math.isInf(val.castTag(.float_128).?.data),
3859 else => false,
3860 },
3852 else => false,3861 else => false,
3853 };3862 };
3854 }3863 }
38553864
3856 pub fn isNegativeInf(val: Value) bool {3865 pub fn isNegativeInf(val: Value) bool {
3857 return switch (val.tag()) {3866 return switch (val.ip_index) {
3858 .float_16 => std.math.isNegativeInf(val.castTag(.float_16).?.data),3867 .none => switch (val.tag()) {
3859 .float_32 => std.math.isNegativeInf(val.castTag(.float_32).?.data),3868 .float_16 => std.math.isNegativeInf(val.castTag(.float_16).?.data),
3860 .float_64 => std.math.isNegativeInf(val.castTag(.float_64).?.data),3869 .float_32 => std.math.isNegativeInf(val.castTag(.float_32).?.data),
3861 .float_80 => std.math.isNegativeInf(val.castTag(.float_80).?.data),3870 .float_64 => std.math.isNegativeInf(val.castTag(.float_64).?.data),
3862 .float_128 => std.math.isNegativeInf(val.castTag(.float_128).?.data),3871 .float_80 => std.math.isNegativeInf(val.castTag(.float_80).?.data),
3872 .float_128 => std.math.isNegativeInf(val.castTag(.float_128).?.data),
3873 else => false,
3874 },
3863 else => false,3875 else => false,
3864 };3876 };
3865 }3877 }