Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion lib/std/zon/parse.zig
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,16 @@ const Parser = struct {
const fields: @FieldType(Zoir.Node, "struct_literal") = switch (repr) {
.struct_literal => |nodes| nodes,
.empty_literal => .{ .names = &.{}, .vals = .{ .start = node, .len = 0 } },
.enum_literal => |lit| {
const decl_name = lit.get(self.zoir);
inline for (@typeInfo(T).@"struct".decls) |decl| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be more in depth. Decl literals can exist on structs unions, enums, and even pointers to any of those things (or opaques). Additionally, we can probably save on eval branch quota by checking for the decl with @hasDecl instead of a for loop. (forget that last part, I forgot this check was happening at runtime!)

Anyways, we should also be validating that the decl is of the correct type before returning it, or else we will just have a compile error when parsing any type that has decls which aren't valid decl literals.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah I can add this for those also. Also I do check the type on line 811

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opaques are not supported in zon files and pointers should be handled by parseExprInner. However the pointer won't be a reference to the Declaration with my current implementation and propagating that information might be tricky.

if (@TypeOf(@field(T,decl.name)) != T) continue;
if (std.mem.eql(u8, decl_name, decl.name)) {
return @field(T, decl.name);
}
}
return self.failNodeFmt(node, "Declaration Literal `{s}` does not exist in {s}",.{decl_name, @typeName(T)});
},
else => return error.WrongType,
};

Expand Down Expand Up @@ -1541,7 +1551,12 @@ test "std.zon structs" {
const Vec0 = struct {};
const Vec1 = struct { x: f32 };
const Vec2 = struct { x: f32, y: f32 };
const Vec3 = struct { x: f32, y: f32, z: f32 };
const Vec3 = struct {
pub const Zero: @This() = .{ .x = 0,.y = 0, .z = 0 };
x: f32,
y: f32,
z: f32,
};

const zero = try fromSlice(Vec0, gpa, ".{}", null, .{});
try std.testing.expectEqual(Vec0{}, zero);
Expand All @@ -1554,6 +1569,12 @@ test "std.zon structs" {

const three = try fromSlice(Vec3, gpa, ".{.x = 1.2, .y = 3.4, .z = 5.6}", null, .{});
try std.testing.expectEqual(Vec3{ .x = 1.2, .y = 3.4, .z = 5.6 }, three);

const decl_literal_Zero = try fromSlice(Vec3, gpa, ".Zero", null, .{});
try std.testing.expectEqual(decl_literal_Zero, @as(Vec3, .Zero));

const decl_literal_One: ?Vec3 = fromSlice(Vec3, gpa, ".DeclarationThatDoesNotExist", null, .{}) catch null;
try std.testing.expectEqual(decl_literal_One, null);
}

// Deep free (structs and arrays)
Expand Down
Loading