Captured value in inline else is different from actual value

For context, Value struct is defined as follow

pub const Value = union(Type) {
    Bool: bool,
    Nil: void,
    Number: f64,
    Obj: *Obj,

    pub fn eql(self: Value, other: Value) bool {
        switch (self) {
            .Obj => |obj| {
                if (!other.isObj(obj.type)) return false;
                switch (obj.type) {
                    inline else => |t| {
                        const obj_a = self.asObj(t).?;
                        const obj_b = self.asObj(t).?;
                        return obj_a.eql(obj_b);
                    },
                }
            },
            inline else => |value, tag| {
                return tag == std.meta.activeTag(other) and value == @field(other, @tagName(tag));
            },
        }
    }
}

The function in question is a method that compares two Values.
Here’s the screenshot of the function and the debugging state:

As you can see in the debugger, the actual value of obj.type is String, but the captured value t comes back as Closure. It’s not obvious to me why this happens, so I would appreciate some help. I’m not sure what else to provide as context so please feel free to ask.

The debugger state is wrong. The bug came from my code, the fix is

- const obj_b = self.asObj(t).?;
+ const obj_b = other.asObj(t).?;

It seems most people are using the Crafting Interpreters book to learn Zig. I’m one of those, too, only a few pages in front of you. Welcome!

3 Likes

I don’t know about most, but a quick search here seems to show that it’s a common path! I’ve seen a few people say that they do Go for the first half and Zig for the second, which is what I did!