rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

Better diagnostics for unlinked projects

Open matklad opened this issue 4 years ago • 14 comments

Problem: when opening a project with unusual struture (Cargo.toml buried deep in the source tree) rust-analyzer doesn't work, without a clear error message.

At the moment, when opening the project, we to detect rust project structure we either use likedProjects config, or, if that is absent, look for Cargo.tomls in level one subdirs. So, we fail to discover deeply nested projects.

Soln1: travers all folders, and not only the top level. This is a bad idea, as this is an unbounded amount of work.

Soln2: lazily load Cargo.projects. That is, when a user opens an .rs file which does not belong to any known project, traverse the directory upwards looking for Cargo.toml. This seems like a best solution UX wise on the first glance. There's a big problem though -- non-determinism. If there are two projects, A and B, and A uses B, then opening B first and invoking find useages won't find usages in A, because we don't know about A yet!

Soln3, what we should do: start like soln2, but, instead of magically loading the file, show a popup "add this file to a list of linked projects?". That way, discovery results are persistent, and user always gets the same workspace.

matklad avatar Apr 22 '21 08:04 matklad

If there are two projects, A and B, and A uses B, then opening B first and invoking find useages won't find usages in A, because we don't know about A yet!

If A and B aren't in a common Cargo workspace and A just uses B through a path dependency, would we actually find the usages? My guess would be that we see them as completely separate crate graphs?

flodiebold avatar Apr 22 '21 08:04 flodiebold

If we have an entry for A in the linked projects, then yes, we'll find usages (or at least, will be able to find them in theory, depending on how our source2def picks B).

matklad avatar Apr 22 '21 09:04 matklad

Soln1: travers all folders, and not only the top level. This is a bad idea, as this is an unbounded amount of work.

It seems like this is a problem for big workspaces, but I've often used projects where just looking into every top-level directory would be enough to discover all Cargo.tomls needed. So perhaps just descending a single level would be another possible solution here.

It would also be interesting to look at how other IDEs do this.

jonas-schievink avatar Apr 22 '21 12:04 jonas-schievink

It seems like this is a problem for big workspaces, but I've often used projects where just looking into every top-level directory would be enough to discover all Cargo.tomls needed. So perhaps just descending a single level would be another possible solution here.

That's exactly what we are doing! ;)

It would also be interesting to look at how other IDEs do this.

IntelliJ Rust does 3, with a caveat that the list of liked projects is managed internally and is not exposed via user-editable config file. That is, instead of JSON, there's a GUI for the list of associated projects

image

matklad avatar Apr 22 '21 12:04 matklad

The problem with changing the configs currently is that it depends on the client, unless we finally introduce rust-analyzer.toml :grimacing:

flodiebold avatar Apr 22 '21 12:04 flodiebold

Yeah, that's true... I wonder if we should add a "change config" LSP extension?

matklad avatar Apr 22 '21 13:04 matklad

See #8631, we might want to lazily load non-toplevel Cargo projects in any case...

flodiebold avatar Apr 23 '21 08:04 flodiebold

This is also related to #6388, I think -- if we're able to load Cargo projects when you open a file from them, the next step would be to create a fake crate for free-standing files when you open them...

flodiebold avatar Apr 24 '21 09:04 flodiebold

Btw, we also have the "changing configs" use case for cargo features (toggling them on/off)...

flodiebold avatar Apr 26 '21 12:04 flodiebold

Uhh

matklad avatar Apr 26 '21 12:04 matklad

If linkedProject points to the workspace root Cargo.toml, but incorrectly through an inline rust-project.json, vscode may not think my source files are linked, but no indication is given that my config is incorrect: image

repro: https://github.com/bugadani/rust-esp32-example/commit/3c093a9af9ec1d93b76c2216aa559b6d31349a7c (edited to point at the incorrect config)

bugadani avatar Sep 22 '21 17:09 bugadani

@bugadani you need to configure linkedProjects like

{
    "rust-analyzer.linkedProjects": ["components/rustlib/Cargo.toml"]
}

, not with an inline rust-project.json.

flodiebold avatar Sep 22 '21 17:09 flodiebold

Ah, shoot. Thanks a lot and sorry for the noise. For whatever reason I found the "Non-Cargo Based Projects" section in the docs, but did not search back for "linkedProjects" and missed that, badly. This means I also misunderstood https://github.com/rust-analyzer/rust-analyzer/issues/7268#issuecomment-925118794 Oh well. Thanks again.

bugadani avatar Sep 22 '21 17:09 bugadani

We have a standard project structure that results in Rust packages two levels deep, and thus not working with Rust Analyzer. linkedProjects is a workaround but requires configuring each package individually. Would support for wildcards in linkedProjects be an option?

{
    "rust-analyzer.linkedProjects": [
        "extensions/*/Cargo.toml"
    ]
}

nickwesselman avatar Aug 02 '22 18:08 nickwesselman

We have a standard project structure that results in Rust packages two levels deep, and thus not working with Rust Analyzer. linkedProjects is a workaround but requires configuring each package individually. Would support for wildcards in linkedProjects be an option?

{
    "rust-analyzer.linkedProjects": [
        "extensions/*/Cargo.toml"
    ]
}

I was also hoping for something like this, or being able to define the depth of search like you can for git repos.

andar1an avatar Nov 14 '22 12:11 andar1an

Hello :), wondering if there are any updates on being able to use wildcards with linkedProjects? Or lazily loading projects?

andar1an avatar Jan 26 '23 17:01 andar1an