From 91e117697ad90430d9266203415712b6cc59f669 Mon Sep 17 00:00:00 2001 From: DilithiumNitrate <38111406+DilithiumNitrate@users.noreply.github.com> Date: Sun, 29 Oct 2023 22:12:43 +0100 Subject: [PATCH] Fix hasRuntimeBitsAdvanced lazy case for pointers and optionals As suggested by mlugg, always returns `error.NeedLazy`. If this has a performance impact, it could be replaced by adding lazy handling to `comptimeOnlyAdvanced`. --- src/type.zig | 20 +++++++++++--------- test/behavior/struct.zig | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/type.zig b/src/type.zig index 812a753987..086a293351 100644 --- a/src/type.zig +++ b/src/type.zig @@ -473,8 +473,11 @@ pub const Type = struct { // Pointers to zero-bit types still have a runtime address; however, pointers // to comptime-only types do not, with the exception of function pointers. if (ignore_comptime_only) return true; - if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); - return !comptimeOnly(ty, mod); + return switch (strat) { + .sema => |sema| !(try sema.typeRequiresComptime(ty)), + .eager => !comptimeOnly(ty, mod), + .lazy => error.NeedLazy, + }; }, .anyframe_type => true, .array_type => |array_type| { @@ -495,13 +498,12 @@ pub const Type = struct { // Then the optional is comptime-known to be null. return false; } - if (ignore_comptime_only) { - return true; - } else if (strat == .sema) { - return !(try strat.sema.typeRequiresComptime(child_ty)); - } else { - return !comptimeOnly(child_ty, mod); - } + if (ignore_comptime_only) return true; + return switch (strat) { + .sema => |sema| !(try sema.typeRequiresComptime(child_ty)), + .eager => !comptimeOnly(child_ty, mod), + .lazy => error.NeedLazy, + }; }, .error_union_type, .error_set_type, diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index dbd33c2bb5..b8dde719cf 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1766,3 +1766,22 @@ test "pointer to struct initialized through reference to anonymous initializer p const str: *const [5]u8 = @ptrCast(s.c); try std.testing.expectEqualSlices(u8, "hello", str); } + +test "comptimeness of optional and error union payload is analyzed properly" { + // This is primarily a semantic analysis integrity test. + // The original failure mode for this was a crash. + // Both structs and unions work for this, the point is that + // their comptimeness is lazily evaluated. + const S = struct {}; + // Original form of bug #17511, regressed in #17471 + const a = @sizeOf(?*S); + _ = a; + // Error union case, fails assertion in debug versions of release 0.11.0 + _ = @sizeOf(anyerror!*S); + _ = @sizeOf(anyerror!?S); + // Evaluation case, crashes the actual release 0.11.0 + const C = struct { x: comptime_int }; + const c: anyerror!?C = .{ .x = 3 }; + const x = (try c).?.x; + try std.testing.expectEqual(3, x); +}