| author | |
| committer | |
| log | 91e117697ad90430d9266203415712b6cc59f669 |
| tree | 5980dcec62fb3fdec01c00e072f0a453e63c5b23 |
| parent | fa022d1ecc148280a3b6e95312087b4e8c0c6166 |
| signature |
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 | 473 | // Pointers to zero-bit types still have a runtime address; however, pointers |
| 474 | 474 | // to comptime-only types do not, with the exception of function pointers. |
| 475 | 475 | if (ignore_comptime_only) return true; |
| 476 | if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); | |
| 477 | return !comptimeOnly(ty, mod); | |
| 476 | return switch (strat) { | |
| 477 | .sema => |sema| !(try sema.typeRequiresComptime(ty)), | |
| 478 | .eager => !comptimeOnly(ty, mod), | |
| 479 | .lazy => error.NeedLazy, | |
| 480 | }; | |
| 478 | 481 | }, |
| 479 | 482 | .anyframe_type => true, |
| 480 | 483 | .array_type => |array_type| { |
| ... | ... | @@ -495,13 +498,12 @@ pub const Type = struct { |
| 495 | 498 | // Then the optional is comptime-known to be null. |
| 496 | 499 | return false; |
| 497 | 500 | } |
| 498 | if (ignore_comptime_only) { | |
| 499 | return true; | |
| 500 | } else if (strat == .sema) { | |
| 501 | return !(try strat.sema.typeRequiresComptime(child_ty)); | |
| 502 | } else { | |
| 503 | return !comptimeOnly(child_ty, mod); | |
| 504 | } | |
| 501 | if (ignore_comptime_only) return true; | |
| 502 | return switch (strat) { | |
| 503 | .sema => |sema| !(try sema.typeRequiresComptime(child_ty)), | |
| 504 | .eager => !comptimeOnly(child_ty, mod), | |
| 505 | .lazy => error.NeedLazy, | |
| 506 | }; | |
| 505 | 507 | }, |
| 506 | 508 | .error_union_type, |
| 507 | 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 | 1766 | const str: *const [5]u8 = @ptrCast(s.c); |
| 1767 | 1767 | try std.testing.expectEqualSlices(u8, "hello", str); |
| 1768 | 1768 | } |
| 1769 | ||
| 1770 | test "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 | } |