authorgravatar for 38111406+DilithiumNitrate@users.noreply.github.comDilithiumNitrate <38111406+DilithiumNitrate@users.noreply.github.com> 2023-10-29 22:12:43+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-29 21:12:43+00:00
log91e117697ad90430d9266203415712b6cc59f669
tree5980dcec62fb3fdec01c00e072f0a453e63c5b23
parentfa022d1ecc148280a3b6e95312087b4e8c0c6166
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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`.

2 files changed, 30 insertions(+), 9 deletions(-)

src/type.zig+11-9
...@@ -473,8 +473,11 @@ pub const Type = struct {...@@ -473,8 +473,11 @@ pub const Type = struct {
473 // Pointers to zero-bit types still have a runtime address; however, pointers473 // Pointers to zero-bit types still have a runtime address; however, pointers
474 // to comptime-only types do not, with the exception of function pointers.474 // to comptime-only types do not, with the exception of function pointers.
475 if (ignore_comptime_only) return true;475 if (ignore_comptime_only) return true;
476 if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty));476 return switch (strat) {
477 return !comptimeOnly(ty, mod);477 .sema => |sema| !(try sema.typeRequiresComptime(ty)),
478 .eager => !comptimeOnly(ty, mod),
479 .lazy => error.NeedLazy,
480 };
478 },481 },
479 .anyframe_type => true,482 .anyframe_type => true,
480 .array_type => |array_type| {483 .array_type => |array_type| {
...@@ -495,13 +498,12 @@ pub const Type = struct {...@@ -495,13 +498,12 @@ pub const Type = struct {
495 // Then the optional is comptime-known to be null.498 // Then the optional is comptime-known to be null.
496 return false;499 return false;
497 }500 }
498 if (ignore_comptime_only) {501 if (ignore_comptime_only) return true;
499 return true;502 return switch (strat) {
500 } else if (strat == .sema) {503 .sema => |sema| !(try sema.typeRequiresComptime(child_ty)),
501 return !(try strat.sema.typeRequiresComptime(child_ty));504 .eager => !comptimeOnly(child_ty, mod),
502 } else {505 .lazy => error.NeedLazy,
503 return !comptimeOnly(child_ty, mod);506 };
504 }
505 },507 },
506 .error_union_type,508 .error_union_type,
507 .error_set_type,509 .error_set_type,
test/behavior/struct.zig+19
...@@ -1766,3 +1766,22 @@ test "pointer to struct initialized through reference to anonymous initializer p...@@ -1766,3 +1766,22 @@ test "pointer to struct initialized through reference to anonymous initializer p
1766 const str: *const [5]u8 = @ptrCast(s.c);1766 const str: *const [5]u8 = @ptrCast(s.c);
1767 try std.testing.expectEqualSlices(u8, "hello", str);1767 try std.testing.expectEqualSlices(u8, "hello", str);
1768}1768}
1769
1770test "comptimeness of optional and error union payload is analyzed properly" {
1771 // This is primarily a semantic analysis integrity test.
1772 // The original failure mode for this was a crash.
1773 // Both structs and unions work for this, the point is that
1774 // their comptimeness is lazily evaluated.
1775 const S = struct {};
1776 // Original form of bug #17511, regressed in #17471
1777 const a = @sizeOf(?*S);
1778 _ = a;
1779 // Error union case, fails assertion in debug versions of release 0.11.0
1780 _ = @sizeOf(anyerror!*S);
1781 _ = @sizeOf(anyerror!?S);
1782 // Evaluation case, crashes the actual release 0.11.0
1783 const C = struct { x: comptime_int };
1784 const c: anyerror!?C = .{ .x = 3 };
1785 const x = (try c).?.x;
1786 try std.testing.expectEqual(3, x);
1787}