# Need help with formatting custom type

**URL:** <https://ziggit.dev/t/need-help-with-formatting-custom-type/13273>\
**Category:** Help\
**Tags:** language, standard-library\
**Created:** [November 29, 2025, 1:25pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273 "2025-11-29T13:25:07Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![CipherPower](https://ziggit.dev/user_avatar/ziggit.dev/cipherpower/32/4641_2.png) [@CipherPower](https://ziggit.dev/u/CipherPower)\
**Post date:** [November 29, 2025, 1:25pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/1 "2025-11-29T13:25:07Z")

</div>

Im attempting to create a generic Linked List implementation in zig, and I wanted to make a custom format function for it. This is my code:

```zig
const std = @import(“std”);

fn Node(comptime T: type) type {
return struct {
value: T,
next: ?\*Node(T),

    const Self = @This();

    pub fn init(value: T) Self {
        return .{ .next = null, .value = value };
    }
};

}

fn List(comptime T: type) type {
return struct {
head: ?\*Node(T),
len: usize,
allocator: std.mem.Allocator,

    const Self = @This();

    pub fn init(allocator: std.mem.Allocator) Self {
        return .{ .allocator = allocator, .head = null, .len = 0 };
    }

    pub fn format(self: Self, writer: anytype) !void {
        if (self.head == null) {
            try writer.print("[]", .{});
            return;
        }

        try writer.print("[", .{});

        var current = self.head.?;
        while (current.next) |next_node| {
            try writer.print("{}, ", .{current.value});
            current = next_node;
        } else {
            try writer.print("{}", .{current.value});
        }
    }

    pub fn push_back(self: *Self, value: T) !void {
        const new_node = try self.allocator.create(Node(T));
        new_node.* = Node(T).init(value);

        if (self.head == null) {
            self.head = new_node;
            self.len += 1;
            return;
        }

        var current = self.head.?;
        while (current.next) |next_node| {
            current = next_node;
        } else {
            current.next = new_node;
            self.len += 1;
        }
    }

    pub fn deinit(self: *Self) void {
        if (self.head == null) return;

        var current = self.head.?;
        while (current.next) |next_node| {
            self.allocator.destroy(current);

            current = next_node;
        } else {
            self.allocator.destroy(current);
        }

        self.len = 0;
    }
};

}

pub fn main() void {}

test “testing list init, deinit and push_back” {
const ally = std.testing.allocator;

var list = List(i32).init(ally);
defer list.deinit();

try list.push_back(20);
try list.push_back(30);
try list.push_back(67);

}

test “list format specifier” {
const ally = std.testing.allocator;

var buffer: [64]u8 = undefined;
var stdout_writer = std.fs.File.stdout().writer(&buffer);

var list = List(i32).init(ally);
defer list.deinit();

try list.push_back(10);
try list.push_back(20);
try list.push_back(30);

try stdout_writer.interface.print("list: {f}\n", .{list});
try stdout_writer.interface.flush();

try std.testing.expect(true);

}

```

when i run zig build test however, it gets stuck on running the format specifier test and never stops running.

I’m completely stuck. I need some help in seeing where i went wrong.

---

<div class="post-metadata">

**Author:** ![smlavine](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/eb9ed0/32.png) [@smlavine](https://ziggit.dev/u/smlavine)\
**Post date:** [November 29, 2025, 1:35pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/2 "2025-11-29T13:35:27Z")

</div>

Have you tried stepping through your code in a debugger to see where it is looping? Some instructions in this thread: [Zig Debugging with LLDB](https://ziggit.dev/t/zig-debugging-with-lldb/3931)

---

<div class="post-metadata">

**Author:** ![dimdin](https://ziggit.dev/user_avatar/ziggit.dev/dimdin/32/1457_2.png) [@dimdin](https://ziggit.dev/u/dimdin)\
**Post date:** [November 29, 2025, 1:41pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/3 "2025-11-29T13:41:39Z")

</div>

`format` calls `print` that uses `format`.

Implement `format` without using `print`. `print` calls `format` and not the other way.

---

<div class="post-metadata">

**Author:** ![CipherPower](https://ziggit.dev/user_avatar/ziggit.dev/cipherpower/32/4641_2.png) [@CipherPower](https://ziggit.dev/u/CipherPower)\
**Post date:** [November 29, 2025, 2:02pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/4 "2025-11-29T14:02:06Z")

</div>

I understand that but I don’t understand why its looping, since Im not calling the List.format() function in the format function. Im only calling the format() function for the type T.

---

<div class="post-metadata">

**Author:** ![CipherPower](https://ziggit.dev/user_avatar/ziggit.dev/cipherpower/32/4641_2.png) [@CipherPower](https://ziggit.dev/u/CipherPower)\
**Post date:** [November 29, 2025, 2:52pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/5 "2025-11-29T14:52:50Z")

</div>

I’m stuck again. I can’t figure this out. It’s confusing as I’ve seen many implementations for format() that use print().

---

<div class="post-metadata">

**Author:** ![CipherPower](https://ziggit.dev/user_avatar/ziggit.dev/cipherpower/32/4641_2.png) [@CipherPower](https://ziggit.dev/u/CipherPower)\
**Post date:** [November 29, 2025, 3:05pm UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/6 "2025-11-29T15:05:00Z")

</div>

This is so odd… I slightly altered the code and now it works?

```zig
pub fn format(self: Self, writer: *std.Io.Writer) !void {
     if (self.len == 0) {
         try writer.writeAll(“[]”);
         return;
     }

        try writer.writeByte('[');

        var current = self.head.?;
        while (current.next) |next| {
            try writer.print("{}, ", .{current.value});
            current = next;
        } else {
            try writer.print("{}]", .{current.value});
        }
    }

```

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [November 30, 2025, 12:04am UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/7 "2025-11-30T00:04:38Z")

</div>

are you using the custom backend? on linux x86\_64 it is enabled in debug builds by default.

If so does the issue persist if you force llvm with `.use_llvm = true` in exe/lib/obj/test options?

---

<div class="post-metadata">

**Author:** ![invlpg](https://ziggit.dev/letter_avatar_proxy/v4/letter/i/13edae/32.png) [@invlpg](https://ziggit.dev/u/invlpg)\
**Post date:** [November 30, 2025, 10:25am UTC](https://ziggit.dev/t/need-help-with-formatting-custom-type/13273/8 "2025-11-30T10:25:12Z")

</div>

Your original code works for me on Linux x86\_64 with both the LLVM and Debug backends on master.
