zls doesn't infer types after 2 layers of usage?
Zig Version
0.14.0-dev.3367+1cc388d52
ZLS Version
0.14.0-dev.397+30b0da02
Client / Code Editor / Extensions
Zed dev 0.175.2.r93.gd0a0303 d0a0303428bed88da0c3773740a9cd8b39d8910d
Steps to Reproduce and Observed Behavior
I want to implement this wrapper function for bitset types and zls only predicts type information after 1 layer of function call.
pub fn FBS(BS: type) type {
return struct {
bs: BS,
pub fn format(
self: @This(),
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
_ = writer;
std.debug.print("{}", .{self.bs.count()}); // no type-hint/auto-completion for self.bs
// ....
}
};
}
pub fn fbs(bitset: anytype) FBS(@TypeOf(bitset)) {
// auto-completion works fine here
return FBS(@TypeOf(bitset)){ .bs = bitset };
}
Expected Behavior
Ideally zls should be able to infer that self.bs is a bitset.
Relevant log output
No longer having this problem.
how was it fixed? I'm asking so I can know project's structure better for potential future contributions :)
I think this might have been caused by the changes in the naming of the cache in the Zig build system. After updating Zig and rebuilding ZLS, it was fixed.
I'v updated to following zig:0.14.0-dev.3452+0367d684f , zls:0.14.0-dev.406+336f468c and it still can't recognize types!
Ok, two things then:
- can you try after deleting
.zig-cacheand~/.cache/zig? - if that doesn't work, it might be because I also updated my dependency (which I control) to use the new stuff in the
build.zig.zon. See: https://github.com/bfactory-ai/zignal/commit/10bb0cf5321b7d4ce613e79b719c1f2f6b342fc2
The steps to reproduce are incomplete. There is no call to the fbs function so where is the bitset?
I would expect something like this to be included:
const std = @import("std");
test {
fbs(std.bit_set.DynamicBitSetUnmanaged{});
}
Let me give you the most basic example :
fn layer1(x: anytype) void {
x.layer2(); // zls doesn't know anything about x including x.layer2()
return;
}
fn layer0(x: anytype) void {
// zls shows x.layer2();
return layer1(x);
}
test "breaking zls" {
const X = struct {
fn layer2(self: *const @This()) void {
_ = self;
}
};
const x = X{};
layer0(x);
}
This could be very annoying, especially when you work with multiple layers of abstraction, including working with readers and writers and ...