Skip to content

Commit 91e1176

Browse files
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`.
1 parent fa022d1 commit 91e1176

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

src/type.zig

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,11 @@ pub const Type = struct {
473473
// Pointers to zero-bit types still have a runtime address; however, pointers
474474
// to comptime-only types do not, with the exception of function pointers.
475475
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+
};
478481
},
479482
.anyframe_type => true,
480483
.array_type => |array_type| {
@@ -495,13 +498,12 @@ pub const Type = struct {
495498
// Then the optional is comptime-known to be null.
496499
return false;
497500
}
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+
};
505507
},
506508
.error_union_type,
507509
.error_set_type,

test/behavior/struct.zig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,3 +1766,22 @@ test "pointer to struct initialized through reference to anonymous initializer p
17661766
const str: *const [5]u8 = @ptrCast(s.c);
17671767
try std.testing.expectEqualSlices(u8, "hello", str);
17681768
}
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+
}

0 commit comments

Comments
 (0)