authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2025-05-26 12:20:14-07:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-05-27 02:40:58+01:00
log3ed9155f10b725e6d24c01f5ecbebf359f3599a7
treea79ffded35e02e05eea958b8b9054bb8ce8abe02
parentef35c3d5fefb8c14e17f3c7036bb21e808ee59be

Sema: simplify comptime `@intFromPtr` logic


2 files changed, 20 insertions(+), 15 deletions(-)

src/Sema.zig+7-15
...@@ -2287,19 +2287,6 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value...@@ -2287,19 +2287,6 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value
2287 return try sema.resolveLazyValue((try sema.resolveValue(inst)) orelse return null);2287 return try sema.resolveLazyValue((try sema.resolveValue(inst)) orelse return null);
2288}2288}
22892289
2290/// Like `resolveValue`, but any pointer value which does not correspond
2291/// to a comptime-known integer (e.g. a decl pointer) returns `null`.
2292/// Lazy values are recursively resolved.
2293fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2294 const val = (try sema.resolveValue(inst)) orelse return null;
2295 if (sema.pt.zcu.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {
2296 .nav, .uav, .comptime_alloc, .comptime_field => return null,
2297 .int => {},
2298 .eu_payload, .opt_payload, .arr_elem, .field => unreachable,
2299 };
2300 return try sema.resolveLazyValue(val);
2301}
2302
2303/// Value Tag may be `undef` or `variable`.2290/// Value Tag may be `undef` or `variable`.
2304pub fn resolveFinalDeclValue(2291pub fn resolveFinalDeclValue(
2305 sema: *Sema,2292 sema: *Sema,
...@@ -10144,14 +10131,19 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10144,14 +10131,19 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10144 }10131 }
10145 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;10132 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;
10146 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .usize_type, .len = len }) else .usize;10133 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .usize_type, .len = len }) else .usize;
10147 if (try sema.resolveValueIntable(operand)) |operand_val| ct: {10134
10135 if (try sema.resolveValue(operand)) |operand_val| ct: {
10148 if (!is_vector) {10136 if (!is_vector) {
10149 if (operand_val.isUndef(zcu)) {10137 if (operand_val.isUndef(zcu)) {
10150 return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern());10138 return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern());
10151 }10139 }
10140 const addr = try operand_val.getUnsignedIntSema(pt) orelse {
10141 // Wasn't an integer pointer. This is a runtime operation.
10142 break :ct;
10143 };
10152 return Air.internedToRef((try pt.intValue(10144 return Air.internedToRef((try pt.intValue(
10153 Type.usize,10145 Type.usize,
10154 (try operand_val.toUnsignedIntSema(pt)),10146 addr,
10155 )).toIntern());10147 )).toIntern());
10156 }10148 }
10157 const new_elems = try sema.arena.alloc(InternPool.Index, len);10149 const new_elems = try sema.arena.alloc(InternPool.Index, len);
test/cases/compile_errors/int_from_ptr_to_optional.zig created+13
...@@ -0,0 +1,13 @@
1comptime {
2 const num: usize = 4;
3 const y: ?*const usize = &num;
4 _ = @intFromPtr(y);
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :4:9: error: unable to evaluate comptime expression
12// :4:21: note: operation is runtime due to this operand
13// :1:1: note: 'comptime' keyword forces comptime evaluation