A comptime value parsed as type by the compiler

const std = @import("std");
const Allocator = std.mem.Allocator;
const Io = std.Io;
const Reader = Io.Reader;

const treader = @import("token_reader.zig");
const TokenReader = treader.TokenReader;
pub const Token = treader.Token;
pub const Position = treader.Position;
pub const TokenPosition = treader.TokenPosition;

pub fn tokenizeToQueue(
    io: Io,
    allocator: Allocator,
    reader: *Io.Reader,
    token_queue: *Io.Queue(TokenPosition),
    progress: *Position,
    comptime simd_lanes: u8,
) treader.TokenizeToQueueError!void {
    defer token_queue.close(io);

    @compileLog(@TypeOf(simd_lanes));
    @compileLog(@typeName(@TypeOf(simd_lanes)));

    var token_reader: treader.TokenReader(simd_lanes) = .{
        .stream = reader,
        .progress = progress,
    };

    defer token_reader.deinit(allocator);

    token_reader.readQueueAll(io, allocator, token_queue, false) catch |err| if (err == error.OutOfMemory) {
        try token_reader.readQueueAll(io, allocator, token_queue, true);
    } else {
        return err;
    };
}

The compiler considers simd_lanes variable to be a type for some reason…

$ zig build
install
└─ install varlink-gen
   └─ compile exe vt debug native 1 errors
src/tokenizer/tokenizer.zig:25:43: error: expected type 'u8', found 'type'
    var token_reader: treader.TokenReader(simd_lanes) = .{
                                          ^~~~~~~~~~
src/tokenizer/token_reader.zig:55:41: note: parameter type declared here
pub fn TokenReader(comptime simd_lanes: u8) type {
                                        ^~
referenced by:
    start: /usr/lib/zig/std/Io.zig:2543:31
    async__func_792: /usr/lib/zig/std/Io.zig:2553:19
    6 reference(s) hidden; use '-freference-trace=8' to see all references

Compile Log Output:
@as(type, type)
@as(*const [4:0]u8, "type")

If I remove comptime keyword its logged as u8 as expected.

The actual type doesn’t matter: I can change it to u64 or std.ArrayList and it still will be logged as type.

Not sure If i’m doing something wrong or its a compiler bug.

I use zig 0.17.1 on x86_64-linux

This looks like a bug, I’d go ahead and file an issue on Codeberg to track it. I think I’ve hit this before but forgot how to repro it before I was able to write it up.

Are you calling tokenizeToQueue via @call, cause that had a similar error in the past.

I’m calling it with io.async

seems like comptimes don’t work with async functions

const std = @import("std");

pub fn main(init: std.process.Init) !void {
    var fut = init.io.async(f, .{1});
    _ = fut.await(init.io);
}

pub fn f(comptime n: u8) void {
    @compileLog(@TypeOf(n));
    @compileLog(@typeName(@TypeOf(n)));
    std.debug.print("{d}\n", .{n});
}
$ zig build
install
└─ install foo
   └─ compile exe foo debug native 1 errors
/usr/lib/zig/std/Io/Writer.zig:1935:5: error: invalid format string 'd' for type 'type'
    @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    printValue__func_825: /usr/lib/zig/std/Io/Writer.zig:1188:40
    print__func_823: /usr/lib/zig/std/Io/Writer.zig:805:25
    10 reference(s) hidden; use '-freference-trace=12' to see all references

Compile Log Output:
@as(type, type)
@as(*const [4:0]u8, "type")

Calling it just with @call prints u8, so the main reason is async

const std = @import("std");

pub fn main(_: std.process.Init) !void {
    @call(.auto, f, .{1});
}

pub fn f(comptime n: u8) void {
    std.debug.print("{s}\n", .{@typeName(@TypeOf(n))});
}
$ zig build run
u8

io.async does use necessarily @call.

I think this is the relevant issue

Try this workaround:

const std = @import("std");

pub fn main(_: std.process.Init) !void {
    @call(.auto, curriedF, .{});
    // or to make it configurable
    @call(.auto, curryF(5), .{});
}

pub fn curriedF() void {
      f(2);
}
// or to make it configurable
pub fn curryF(comptime N: u8) fn() void {
    return struct {
        fn curried() void {
            f(N);
        }
    }.curried;
}

pub fn f(comptime n: u8) void {
    std.debug.print("{s}\n", .{@typeName(@TypeOf(n))});
}

Worth pointing out the feature that is supposed to allow @call to work with comptime args is planned to be removed, which will make the above canonical instead of a workaround.

currying helps, thanks!