| 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,9 +25048,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 25048 | } | 25048 | } |
| 25049 | 25049 | ||
| 25050 | pub fn typeHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { | 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; | 25051 | return ty.hasRuntimeBitsAdvanced(false, sema.kit(block, src)); |
| 25052 | if (try sema.typeRequiresComptime(block, src, ty)) return false; | ||
| 25053 | return true; | ||
| 25054 | } | 25052 | } |
| 25055 | 25053 | ||
| 25056 | fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 { | 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,7 +9185,7 @@ fn isByRef(ty: Type) bool { |
| 9185 | .AnyFrame, | 9185 | .AnyFrame, |
| 9186 | => return false, | 9186 | => return false, |
| 9187 | 9187 | ||
| 9188 | .Array, .Frame => return ty.hasRuntimeBitsIgnoreComptime(), | 9188 | .Array, .Frame => return ty.hasRuntimeBits(), |
| 9189 | .Struct => { | 9189 | .Struct => { |
| 9190 | // Packed structs are represented to LLVM as integers. | 9190 | // Packed structs are represented to LLVM as integers. |
| 9191 | if (ty.containerLayout() == .Packed) return false; | 9191 | if (ty.containerLayout() == .Packed) return false; |
| ... | @@ -9204,7 +9204,7 @@ fn isByRef(ty: Type) bool { | ... | @@ -9204,7 +9204,7 @@ fn isByRef(ty: Type) bool { |
| 9204 | var count: usize = 0; | 9204 | var count: usize = 0; |
| 9205 | const fields = ty.structFields(); | 9205 | const fields = ty.structFields(); |
| 9206 | for (fields.values()) |field| { | 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 | count += 1; | 9209 | count += 1; |
| 9210 | if (count > max_fields_byval) return true; | 9210 | if (count > max_fields_byval) return true; |
| ... | @@ -9212,7 +9212,7 @@ fn isByRef(ty: Type) bool { | ... | @@ -9212,7 +9212,7 @@ fn isByRef(ty: Type) bool { |
| 9212 | } | 9212 | } |
| 9213 | return false; | 9213 | return false; |
| 9214 | }, | 9214 | }, |
| 9215 | .Union => return ty.hasRuntimeBitsIgnoreComptime(), | 9215 | .Union => return ty.hasRuntimeBits(), |
| 9216 | .ErrorUnion => return isByRef(ty.errorUnionPayload()), | 9216 | .ErrorUnion => return isByRef(ty.errorUnionPayload()), |
| 9217 | .Optional => { | 9217 | .Optional => { |
| 9218 | var buf: Type.Payload.ElemType = undefined; | 9218 | var buf: Type.Payload.ElemType = undefined; |
src/type.zig+1-9| ... | @@ -2365,6 +2365,7 @@ pub const Type = extern union { | ... | @@ -2365,6 +2365,7 @@ pub const Type = extern union { |
| 2365 | .@"anyframe", | 2365 | .@"anyframe", |
| 2366 | .anyopaque, | 2366 | .anyopaque, |
| 2367 | .@"opaque", | 2367 | .@"opaque", |
| 2368 | .type_info, | ||
| 2368 | => return true, | 2369 | => return true, |
| 2369 | 2370 | ||
| 2370 | // These are false because they are comptime-only types. | 2371 | // These are false because they are comptime-only types. |
| ... | @@ -2379,7 +2380,6 @@ pub const Type = extern union { | ... | @@ -2379,7 +2380,6 @@ pub const Type = extern union { |
| 2379 | .enum_literal, | 2380 | .enum_literal, |
| 2380 | .empty_struct, | 2381 | .empty_struct, |
| 2381 | .empty_struct_literal, | 2382 | .empty_struct_literal, |
| 2382 | .type_info, | ||
| 2383 | .bound_fn, | 2383 | .bound_fn, |
| 2384 | // These are function *bodies*, not pointers. | 2384 | // These are function *bodies*, not pointers. |
| 2385 | // Special exceptions have to be made when emitting functions due to | 2385 | // Special exceptions have to be made when emitting functions due to |
| ... | @@ -2464,14 +2464,6 @@ pub const Type = extern union { | ... | @@ -2464,14 +2464,6 @@ pub const Type = extern union { |
| 2464 | 2464 | ||
| 2465 | .@"struct" => { | 2465 | .@"struct" => { |
| 2466 | const struct_obj = ty.castTag(.@"struct").?.data; | 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 | if (struct_obj.status == .field_types_wip) { | 2467 | if (struct_obj.status == .field_types_wip) { |
| 2476 | // In this case, we guess that hasRuntimeBits() for this type is true, | 2468 | // In this case, we guess that hasRuntimeBits() for this type is true, |
| 2477 | // and then later if our guess was incorrect, we emit a compile error. | 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,7 +1196,9 @@ test "equality of pointers to comptime const" { |
| 1196 | } | 1196 | } |
| 1197 | 1197 | ||
| 1198 | test "storing an array of type in a field" { | 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 | const S = struct { | 1203 | const S = struct { |
| 1202 | fn doTheTest() void { | 1204 | fn doTheTest() void { |
| ... | @@ -1221,3 +1223,32 @@ test "storing an array of type in a field" { | ... | @@ -1221,3 +1223,32 @@ test "storing an array of type in a field" { |
| 1221 | 1223 | ||
| 1222 | S.doTheTest(); | 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 | } |