Error when using `discardRemaining()`

Hi I’m a complete beginner in zig. I’m trying to make a simple REPL program but I’m running into an error when I use the discardRemaining() function for the reader. I’m looking for some help to get it working, I have provided the code and a stacktrace below.

var should_quit: bool = false;
    while (!should_quit) {
        try stdout_writer.writeAll(">>> ");
        try stdout_writer.flush();

        const input = stdin_reader.takeDelimiterExclusive('\n') catch |err| switch (err) {
            error.EndOfStream => {
                return err;
            },
            error.ReadFailed => {
                return err;
            },
            error.StreamTooLong => {
                // I think this is the only one I want to handle?
                try stdout_writer.writeAll("useful message\n");
                try stdout_writer.flush();
                const thing: usize = try stdin_reader.discardRemaining();
                std.debug.print("{d}\n", .{thing});

                continue;
            },
        };
        stdin_reader.toss(1);

        const trimmed_input = std.mem.trim(u8, input, " \n\r\t");
        const is_equal = std.mem.eql(u8, trimmed_input, "exit");

        if (is_equal) {
            should_quit = true;
        }
    }

The reason why I’m using this function is to get rid of the leftovers of what the user typed if a StreamTooLong error is reached.

I’m getting this stacktrace, but I’m not sure what the problem is. It looks like maybe it’s a bug in the version of the compiler for Windows? However I don’t want to jump the gun by making an issue if I’m totally wrong.

error.Unexpected NTSTATUS=0xc0000010 (INVALID_DEVICE_REQUEST)
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\Io\Threaded.zig:1462:40: 0x7ff652e10509 in unexpectedNtstatus (int_converter_zcu.obj)
        return windows.unexpectedStatus(status);
                                       ^
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\Io\Threaded.zig:4078:58: 0x7ff652e76b70 in fileStatWindows (int_converter_zcu.obj)
            else => |s| return syscall.unexpectedNtstatus(s),
                                                         ^
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\Io\File.zig:142:30: 0x7ff652d8a945 in stat (int_converter_zcu.obj)
    return io.vtable.fileStat(io.userdata, file);
                             ^
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\Io\File\Reader.zig:118:24: 0x7ff652d8a59a in getSize (int_converter_zcu.obj)
        if (r.file.stat(r.io)) |st| {
                       ^
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\Io\File\Reader.zig:306:35: 0x7ff652d8b64e in discard (int_converter_zcu.obj)
            const size = r.getSize() catch {
                                  ^
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\Io\Reader.zig:278:35: 0x7ff652eaf18f in discardRemaining (int_converter_zcu.obj)
        offset += r.vtable.discard(r, .unlimited) catch |err| switch (err) {
                                  ^
C:\Users\nirva\proj\zig\int-converter\src\main.zig:56:71: 0x7ff652ea81f0 in main (int_converter_zcu.obj)
                const thing: usize = try stdin_reader.discardRemaining();
                                                                      ^
C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\start.zig:827: 0x7ff652ea8610 in callMain (int_converter_zcu.obj)
    return wrapMain(root.main(.{

C:\Users\nirva\software\zig-x86_64-windows-0.17.0\zig-x86_64-windows-0.17.0\lib\std\start.zig:576:17: 0x7ff652ea8610 in WinStartup (int_converter_zcu.obj)
        callMain(std.os.windows.peb().ProcessParameters.CommandLine.slice(), .global),
                ^
???:?:?: 0x7ffc9779cd86 in ??? (KERNEL32.DLL)
???:?:?: 0x7ffc9936caeb in ??? (ntdll.dll)

I’m open to any advice on how to fix it, maybe there’s a much better way to accomplish this. Also, if you have feedback for the code in general I would love to hear it!

discardRemaining will discard the remaining data of the whole file, the issue is that the implementation is doing an operation that is not valid for stdio–that being stat if your curious.

Std returns error.Unexpected when the error is either, not supposed to be possible, or indicates a programmer bug like: doing operations on a file that doesn’t support it.

Now it could still be a bug in std if its possible to avoid those operations or have a fallback, but I don’t know enough about windows to know this.


Explanation aside, discardRemaining is certainly not the behaviour you want in a REPL.

The take family of functions return sub-slices of the interface buffer; error.StreamTooLong is returned when the buffer is not big enough.

I am guessing you were trying to discard the rest of the line, in which case you’d use discardDelimiterInclusive

If you want different behaviour explain what it is and we’d be glad to help.

I changed to discardDelimiterInclusive('\n') and it’s working now. Thanks for the explanation :blush: