From 7b8cb881df7e034a8626caabf355055ee81a0fef Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 23 Jul 2021 22:23:03 -0700 Subject: stage2: improvements towards `zig test` * There is now a main_pkg in addition to root_pkg. They are usually the same. When using `zig test`, main_pkg is the user's source file and root_pkg has the test runner. * scanDecl no longer looks for test decls outside the package being tested. honoring `--test-filter` is still TODO. * test runner main function has a void return value rather than `anyerror!void` * Sema is improved to generate better AIR for for loops on slices. * Sema: fix incorrect capacity calculation in zirBoolBr * Sema: add compile errors for trying to use slice fields as an lvalue. * Sema: fix type coercion for error unions * Sema: fix analyzeVarRef generating garbage AIR * C codegen: fix renderValue for error unions with 0 bit payload * C codegen: implement function pointer calls * CLI: fix usage text Adds 4 new AIR instructions: * slice_len, slice_ptr: to get the ptr and len fields of a slice. * slice_elem_val, ptr_slice_elem_val: to get the element value of a slice, and a pointer to a slice. AstGen gains a new functionality: * One of the unused flags of struct decls is now used to indicate structs that are known to have non-zero size based on the AST alone. --- src/type.zig | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'src/type.zig') diff --git a/src/type.zig b/src/type.zig index 52a82c0b93..bbb3ee667a 100644 --- a/src/type.zig +++ b/src/type.zig @@ -525,9 +525,19 @@ pub const Type = extern union { const b_data = b.castTag(.error_union).?.data; return a_data.error_set.eql(b_data.error_set) and a_data.payload.eql(b_data.payload); }, + .ErrorSet => { + const a_is_anyerror = a.tag() == .anyerror; + const b_is_anyerror = b.tag() == .anyerror; + + if (a_is_anyerror and b_is_anyerror) return true; + if (a_is_anyerror or b_is_anyerror) return false; + + std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ + a.tag(), b.tag(), + }); + }, .Opaque, .Float, - .ErrorSet, .BoundFn, .Frame, => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }), @@ -1190,6 +1200,9 @@ pub const Type = extern union { .@"struct" => { // TODO introduce lazy value mechanism const struct_obj = self.castTag(.@"struct").?.data; + if (struct_obj.known_has_bits) { + return true; + } assert(struct_obj.status == .have_field_types or struct_obj.status == .layout_wip or struct_obj.status == .have_layout); @@ -1645,7 +1658,7 @@ pub const Type = extern union { } else if (!payload.payload.hasCodeGenBits()) { return payload.error_set.abiSize(target); } - @panic("TODO abiSize error union"); + std.debug.panic("TODO abiSize error union {}", .{self}); }, }; } @@ -2038,7 +2051,7 @@ pub const Type = extern union { return ty.optionalChild(&buf).isValidVarType(is_extern); }, .Pointer, .Array, .Vector => ty = ty.elemType(), - .ErrorUnion => ty = ty.errorUnionChild(), + .ErrorUnion => ty = ty.errorUnionPayload(), .Fn => @panic("TODO fn isValidVarType"), .Struct => { @@ -2119,13 +2132,10 @@ pub const Type = extern union { } /// Asserts that the type is an error union. - pub fn errorUnionChild(self: Type) Type { + pub fn errorUnionPayload(self: Type) Type { return switch (self.tag()) { - .anyerror_void_error_union => Type.initTag(.anyerror), - .error_union => { - const payload = self.castTag(.error_union).?; - return payload.data.payload; - }, + .anyerror_void_error_union => Type.initTag(.void), + .error_union => self.castTag(.error_union).?.data.payload, else => unreachable, }; } @@ -2133,10 +2143,7 @@ pub const Type = extern union { pub fn errorUnionSet(self: Type) Type { return switch (self.tag()) { .anyerror_void_error_union => Type.initTag(.anyerror), - .error_union => { - const payload = self.castTag(.error_union).?; - return payload.data.error_set; - }, + .error_union => self.castTag(.error_union).?.data.error_set, else => unreachable, }; } -- cgit v1.2.3