From 6f560c99094eec2210f2d76a2449b5f60191e11b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 8 Mar 2022 20:52:38 -0700 Subject: [PATCH] Sema: implement comptime struct fields --- src/Module.zig | 1 + src/Sema.zig | 17 +++++++++++++++++ test/behavior/struct.zig | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Module.zig b/src/Module.zig index 68e3a56752..b7299ebdab 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -884,6 +884,7 @@ pub const Struct = struct { default_val: Value, /// undefined until `status` is `have_layout`. offset: u32, + /// If true then `default_val` is the comptime field value. is_comptime: bool, /// Returns the field alignment, assuming the struct is not packed. diff --git a/src/Sema.zig b/src/Sema.zig index 5bddead0ba..2602cdc21e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -15282,6 +15282,19 @@ fn structFieldPtrByIndex( const target = sema.mod.getTarget(); const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data); + if (field.is_comptime) { + var anon_decl = try block.startAnonDecl(field_src); + defer anon_decl.deinit(); + const decl = try anon_decl.finish( + try field.ty.copy(anon_decl.arena()), + try field.default_val.copy(anon_decl.arena()), + ); + if (ptr_ty_data.@"align" != 0) { + decl.align_val = field.abi_align; + } + return sema.analyzeDeclRef(decl); + } + if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { return sema.addConstant( ptr_field_ty, @@ -15330,6 +15343,10 @@ fn structFieldVal( const field_index = @intCast(u32, field_index_usize); const field = struct_obj.fields.values()[field_index]; + if (field.is_comptime) { + return sema.addConstant(field.ty, field.default_val); + } + if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| { if (struct_val.isUndef()) return sema.addConstUndef(field.ty); if ((try sema.typeHasOnePossibleValue(block, src, field.ty))) |opv| { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 35e6e3a3a3..d4190fcd21 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -982,7 +982,8 @@ test "tuple assigned to variable" { } test "comptime struct field" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { a: i32,