From a5d2fd75192a75f2733868af9dba548c1e2d0234 Mon Sep 17 00:00:00 2001 From: Biom4st3r Date: Thu, 6 Nov 2025 17:38:17 -0600 Subject: [PATCH] * Added support for @import'ing Decl Literals --- src/Sema.zig | 2 +- src/Sema/LowerZon.zig | 33 ++++++++++++++++++++++++++++++ test/behavior/zon.zig | 30 +++++++++++++++++++++++++++ test/behavior/zon/DeclLiterals.zon | 5 +++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/behavior/zon/DeclLiterals.zon diff --git a/src/Sema.zig b/src/Sema.zig index 4016041d82..51bd50b615 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -26793,7 +26793,7 @@ fn fieldPtrLoad( return analyzeLoad(sema, block, src, field_ptr, field_name_src); } -fn fieldVal( +pub fn fieldVal( sema: *Sema, block: *Block, src: LazySrcLoc, diff --git a/src/Sema/LowerZon.zig b/src/Sema/LowerZon.zig index eb1fba121a..c8038f2e31 100644 --- a/src/Sema/LowerZon.zig +++ b/src/Sema/LowerZon.zig @@ -645,6 +645,9 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I field_name.get(self.file.zoir.?), .no_embedded_nulls, ); + + const enum_info = ip.loadEnumType(res_ty.ip_index); + if (try self.lowerDeclLiteral(node, res_ty, field_name, enum_info.namespace)) |val| return val; const field_index = res_ty.enumFieldIndex(field_name_interned, self.sema.pt.zcu) orelse { return self.fail( node, @@ -746,6 +749,29 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool. return (try self.sema.pt.aggregateValue(res_ty, elems)).toIntern(); } +fn lowerDeclLiteral(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type, name: Zoir.NullTerminatedString, namespace: InternPool.NamespaceIndex) !?InternPool.Index { + const ip = &self.sema.pt.zcu.intern_pool; + + const air = Air.internedToRef(res_ty.toIntern()); + // Intern the incoming name + const decl_name = try ip.getOrPutString( + self.sema.gpa, + self.sema.pt.tid, + name.get(self.file.zoir.?), + .no_embedded_nulls, + ); + + for (ip.namespacePtr(namespace).pub_decls.keys()) |decl| { + const nav = ip.getNav(decl); + if (nav.name == decl_name) { + const src = self.nodeSrc(node); + const val = try self.sema.fieldVal(self.block, src, air, decl_name, src); + return val.toInterned().?; + } + } + return null; +} + fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.Index { const ip = &self.sema.pt.zcu.intern_pool; const gpa = self.sema.gpa; @@ -757,6 +783,10 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) { .struct_literal => |fields| fields, .empty_literal => .{ .names = &.{}, .vals = .{ .start = node, .len = 0 } }, + .enum_literal => |name| { + if (try self.lowerDeclLiteral(node, res_ty, name, struct_info.namespace)) |val| return val; + return error.WrongType; + }, else => return error.WrongType, }; @@ -905,6 +935,9 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool. name.get(self.file.zoir.?), .no_embedded_nulls, ); + + if (try self.lowerDeclLiteral(node, res_ty, name, union_info.namespace)) |val| return val; + break :b .{ field_name, null }; }, .struct_literal => b: { diff --git a/test/behavior/zon.zig b/test/behavior/zon.zig index 8a43b4894e..18bdeb7877 100644 --- a/test/behavior/zon.zig +++ b/test/behavior/zon.zig @@ -571,3 +571,33 @@ test "build.zig.zon" { try expectEqual(.{ "build.zig", "build.zig.zon", "src" }, build.paths); } + +test "decl literal" { + const Struct = struct { + pub const ADeclLitStruct: @This() = .{.a = 5,.b = 0.6}; + a: u64, + b: f64, + }; + const Union = union(enum){ + pub const ADeclLitUnion: @This() = .{.a = 5,}; + a: u64, + b: f64, + }; + const Enum = enum { + pub const ADeclLitEnum: @This() = .B; + A, + B, + C, + }; + + const Lits = struct { + a: Struct, + b: Union, + c: Enum, + }; + + const Preset: Lits = @import("zon/DeclLiterals.zon"); + try expectEqual(Preset.a, Struct.ADeclLitStruct); + try expectEqual(Preset.b, Union.ADeclLitUnion); + try expectEqual(Preset.c, Enum.ADeclLitEnum); +} diff --git a/test/behavior/zon/DeclLiterals.zon b/test/behavior/zon/DeclLiterals.zon new file mode 100644 index 0000000000..3ec33ece78 --- /dev/null +++ b/test/behavior/zon/DeclLiterals.zon @@ -0,0 +1,5 @@ +.{ + .a = .ADeclLitStruct, + .b = .ADeclLitUnion, + .c = .ADeclLitEnum, +}