Allocator usage causes zls inline types to get very confused
Zig Version
0.12.0-dev.3439+31a7f22b8
Zig Language Server Version
0.12.0-dev.496+96eddd0
Client / Code Editor / Extensions
VSCode with official extension
Steps to Reproduce and Observed Behavior
Put this code into a file
const std = @import("std");
pub fn main() !void {
const one = try std.heap.c_allocator.alloc(u16, 10);
_ = one; // autofix
const two = try std.heap.c_allocator.alloc(u8, 10);
_ = two; // autofix
}
You'll see ZLS incorrectly show the type of two as []u16
This behaviour gets very weird when its spread across multiple functions https://github.com/zigtools/zls/assets/34501060/c0f9498b-a24e-403b-921e-b026b93a516c
Expected Behavior
The type of all the alloc calls is correctly resolved
Relevant log output
No response
I think I got to the root of this. The cause is caching of the node types (link to code). The cache does not take into account the fact that the return type depends on the arguments to the function.
Here is the minimal reproduction:
fn foo(comptime T: type) T {
return 42;
}
const bar = foo(u1); // hints `u1`
const baz = foo(u2); // hints `u1`
In this code, the type of foo gets resolved once for bar, but for baz, the type of foo is already in cache.
Now what could be the solution here?
- Add function param types to the cache's key
- Do not cache function calls
- Do not cache function calls with type variables
- Some kind of change to
ComptimeInterpreter(I have not studied it yet)
Another observation: the reason why hover works most of the time is because the Analyser is instantiated for each request (with clean cache). So this bug can happen on hover as well, if the same Declaration needs to be evaluated multiple times within the single hover resolution.
fn arr(comptime T: anytype) []T {
return &[_]T{};
}
// The deeper `arr` is evaluated, the outer `arr` is from cache
// should be [][]u1, but both hint and hover is []u1
pub const hover = arr(@TypeOf(arr(u1)));