Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocator usage causes zls inline types to get very confused #1841

Open
Beyley opened this issue Mar 28, 2024 · 2 comments
Open

Allocator usage causes zls inline types to get very confused #1841

Beyley opened this issue Mar 28, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@Beyley
Copy link
Contributor

Beyley commented Mar 28, 2024

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

@Beyley Beyley added the bug Something isn't working label Mar 28, 2024
@Sekky61
Copy link
Contributor

Sekky61 commented May 24, 2024

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`

Selection_117

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)

@Sekky61
Copy link
Contributor

Sekky61 commented May 25, 2024

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)));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants