| author | |
| committer | |
| log | 32c90cb5539c3b340ae1b0b13d2b1521ebb6b1b0 |
| tree | 149e21f6afdce496a95d29d97a1d6e3ccd6d0f4d |
| parent | f1cff4fa4a28d42ac9055f94ee9a8f7fd2831cd7 |
4 files changed, 37 insertions(+), 16 deletions(-)
src/Sema.zig+1-3| ... | ... | @@ -25048,9 +25048,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 25048 | 25048 | } |
| 25049 | 25049 | |
| 25050 | 25050 | pub fn typeHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { |
| 25051 | if ((try sema.typeHasOnePossibleValue(block, src, ty)) != null) return false; | |
| 25052 | if (try sema.typeRequiresComptime(block, src, ty)) return false; | |
| 25053 | return true; | |
| 25051 | return ty.hasRuntimeBitsAdvanced(false, sema.kit(block, src)); | |
| 25054 | 25052 | } |
| 25055 | 25053 | |
| 25056 | 25054 | fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 { |
src/codegen/llvm.zig+3-3| ... | ... | @@ -9185,7 +9185,7 @@ fn isByRef(ty: Type) bool { |
| 9185 | 9185 | .AnyFrame, |
| 9186 | 9186 | => return false, |
| 9187 | 9187 | |
| 9188 | .Array, .Frame => return ty.hasRuntimeBitsIgnoreComptime(), | |
| 9188 | .Array, .Frame => return ty.hasRuntimeBits(), | |
| 9189 | 9189 | .Struct => { |
| 9190 | 9190 | // Packed structs are represented to LLVM as integers. |
| 9191 | 9191 | if (ty.containerLayout() == .Packed) return false; |
| ... | ... | @@ -9204,7 +9204,7 @@ fn isByRef(ty: Type) bool { |
| 9204 | 9204 | var count: usize = 0; |
| 9205 | 9205 | const fields = ty.structFields(); |
| 9206 | 9206 | for (fields.values()) |field| { |
| 9207 | if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue; | |
| 9207 | if (field.is_comptime or !field.ty.hasRuntimeBits()) continue; | |
| 9208 | 9208 | |
| 9209 | 9209 | count += 1; |
| 9210 | 9210 | if (count > max_fields_byval) return true; |
| ... | ... | @@ -9212,7 +9212,7 @@ fn isByRef(ty: Type) bool { |
| 9212 | 9212 | } |
| 9213 | 9213 | return false; |
| 9214 | 9214 | }, |
| 9215 | .Union => return ty.hasRuntimeBitsIgnoreComptime(), | |
| 9215 | .Union => return ty.hasRuntimeBits(), | |
| 9216 | 9216 | .ErrorUnion => return isByRef(ty.errorUnionPayload()), |
| 9217 | 9217 | .Optional => { |
| 9218 | 9218 | var buf: Type.Payload.ElemType = undefined; |
src/type.zig+1-9| ... | ... | @@ -2365,6 +2365,7 @@ pub const Type = extern union { |
| 2365 | 2365 | .@"anyframe", |
| 2366 | 2366 | .anyopaque, |
| 2367 | 2367 | .@"opaque", |
| 2368 | .type_info, | |
| 2368 | 2369 | => return true, |
| 2369 | 2370 | |
| 2370 | 2371 | // These are false because they are comptime-only types. |
| ... | ... | @@ -2379,7 +2380,6 @@ pub const Type = extern union { |
| 2379 | 2380 | .enum_literal, |
| 2380 | 2381 | .empty_struct, |
| 2381 | 2382 | .empty_struct_literal, |
| 2382 | .type_info, | |
| 2383 | 2383 | .bound_fn, |
| 2384 | 2384 | // These are function *bodies*, not pointers. |
| 2385 | 2385 | // Special exceptions have to be made when emitting functions due to |
| ... | ... | @@ -2464,14 +2464,6 @@ pub const Type = extern union { |
| 2464 | 2464 | |
| 2465 | 2465 | .@"struct" => { |
| 2466 | 2466 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 2467 | if (sema_kit) |sk| { | |
| 2468 | _ = try sk.sema.typeRequiresComptime(sk.block, sk.src, ty); | |
| 2469 | } | |
| 2470 | switch (struct_obj.requires_comptime) { | |
| 2471 | .yes => return false, | |
| 2472 | .wip, .no => if (struct_obj.known_non_opv) return true, | |
| 2473 | .unknown => {}, | |
| 2474 | } | |
| 2475 | 2467 | if (struct_obj.status == .field_types_wip) { |
| 2476 | 2468 | // In this case, we guess that hasRuntimeBits() for this type is true, |
| 2477 | 2469 | // and then later if our guess was incorrect, we emit a compile error. |
test/behavior/eval.zig+32-1| ... | ... | @@ -1196,7 +1196,9 @@ test "equality of pointers to comptime const" { |
| 1196 | 1196 | } |
| 1197 | 1197 | |
| 1198 | 1198 | test "storing an array of type in a field" { |
| 1199 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 1199 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1200 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 1201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1200 | 1202 | |
| 1201 | 1203 | const S = struct { |
| 1202 | 1204 | fn doTheTest() void { |
| ... | ... | @@ -1221,3 +1223,32 @@ test "storing an array of type in a field" { |
| 1221 | 1223 | |
| 1222 | 1224 | S.doTheTest(); |
| 1223 | 1225 | } |
| 1226 | ||
| 1227 | test "pass pointer to field of comptime-only type as a runtime parameter" { | |
| 1228 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1229 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 1230 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1231 | ||
| 1232 | const S = struct { | |
| 1233 | const Mixed = struct { | |
| 1234 | T: type, | |
| 1235 | x: i32, | |
| 1236 | }; | |
| 1237 | const bag: Mixed = .{ | |
| 1238 | .T = bool, | |
| 1239 | .x = 1234, | |
| 1240 | }; | |
| 1241 | ||
| 1242 | var ok = false; | |
| 1243 | ||
| 1244 | fn doTheTest() !void { | |
| 1245 | foo(&bag.x); | |
| 1246 | try expect(ok); | |
| 1247 | } | |
| 1248 | ||
| 1249 | fn foo(ptr: *const i32) void { | |
| 1250 | ok = ptr.* == 1234; | |
| 1251 | } | |
| 1252 | }; | |
| 1253 | try S.doTheTest(); | |
| 1254 | } |