No compile-time errors in VSCode workspace projects with rust-analyzer plugin

Hi,

The problem:

  • For some reason rust-analyzer extension has stopped showing compile-time errors in VSCode workspace projects.
  • Everything works fine if I don't use VSCode workspace, but open the projects separately.
  • The following VSCode outputs have no errors: Rust Analyzer Client, Rust Analyzer Language Server
  • In the past, the extension has shown errors while developing, but this has broken some time ago.

Has anyone else had a similar problem and been able to resolve it? How?

Kind regards,

Harri

Use the rust-analyzer.linkedProjects setting to tell rust-analyzer which parts of your VS Code workspace contain Cargo packages/workspaces.

@kpreid, thanks for helping! I've tried that also but it doesn't work.

Can you try this sample project?

When I opened that workspace, rust-analyzer displayed an error: red status bar item, and this in the Output:

[ERROR rust_analyzer::main_loop] FetchWorkspaceError: rust-analyzer failed to load workspace: Failed to load the project at /.../rust_vscode_workspace_example/lib1/lib1/Cargo.toml: Failed to query rust toolchain version at /.../rust_vscode_workspace_example/lib1/lib1, is your toolchain setup correctly?: cd "/.../rust_vscode_workspace_example/lib1/lib1" && "cargo" "--version" failed: No such file or directory (os error 2)
rust-analyzer failed to load workspace: Failed to load the project at /.../rust_vscode_workspace_example/lib1/lib2/Cargo.toml: Failed to query rust toolchain version at /.../rust_vscode_workspace_example/lib1/lib2, is your toolchain setup correctly?: cd "/.../rust_vscode_workspace_example/lib1/lib2" && "cargo" "--version" failed: No such file or directory (os error 2)

Note the incorrect paths lib1/lib1 and lib1/lib2. So it seems that there is indeed a bug. I suggest reporting it.

I want to point out that, although rust-analyzer indeed didn't handle this case correctly, OP has misconfigured the vscode workspace anyway.

the TLDR is: multi-root workspace is poorly supported by extensions, just use a single workspace with subdirectories, e.g.:

{
	"folders": [{ "path": "." }],
	"settings": {
		"rust-analyzer.linkedProjects": [
			"lib1/Cargo.toml",
			"lib2/Cargo.toml"
		]
	}
}

explanation

the following is how the workspace SHOULD be configured, but rust-analyzer does NOT handle it correctly as of now.

your workspace is configured as a multiroot workspace, and the linkedProjects should not use relative path, as it's ambiguous to which root they are relative. the "proper" way should use variables socped per-workspace root. for example:

{
	"folders": [
		{ "path": "lib1" },
		{ "path": "lib2" }
	],
	"settings": {
		"rust-analyzer.linkedProjects": [
			"${workspaceFolder:lib1}/Cargo.toml",
			"${workspaceFolder:lib2}/Cargo.toml"
		]
	}
}

interestingly, when I search workspaceFolders in rust-analyzer repository, I found it is being handled in debug.ts, namely:

you can check the linked issue in the comment for context.

however, it is not handled in the lsp configuration marshalling code:

rust-analyzer will only expand selectively a subset of variables listed in supportedVariables. they only support the form ${workspaceFolder} (not ${workspaceFolder:foobar}), and it gets expanded to the first workspace root folder:

that's the reason the error log says:

t's a shame there's many useful variables in vscode but there's no API for extension authors to access them easily (as far as I know, I might be wrong).

1 Like

OP has misconfigured the vscode workspace anyway

Initially the workspace had

{
    "folders": [
        {
            "path": "lib1"
        },
        {
            "path": "lib2"
        }
    ],
    "settings": {
        "rust-analyzer.linkedProjects": [
            "./Cargo.toml"
        ]
    }
}

and it used to work fine... but it does not work anymore.

I added

"lib1/Cargo.toml",
"lib2/Cargo.toml"

to provide @kpreid with a workspace to test his proposal.

as I explained, rust-analyzer will use lib1 as the root of workspace in such cases, so it can work totally fine, it's just lib2 will not be recognized by rust-analyzer as a top level workspace, for example, if your lib1 has something like:

[dependencies]
lib2 = { path = "../lib2" }

it'll work just fine. but if it's the other way around, that is, lib2 depends on lib1, rust-analyzer will only find lib1.

you should be aware that a multiroot workspace contains multiple root folders, i.e. there's no single ${workspaceFolder} variable for a multi-root workspace setting. as far as I know, most vscode extensions don't handle this very well, including rust-analyzer.

the simplest is just treat lib1 and lib2 as subdirectories of a single root workspace, i.e.

{
    "folders": [
        {
            "path": "."
        },
    ],
    "settings": {
        "rust-analyzer.linkedProjects": [
            "./lib1/Cargo.toml",
            "./lib2/Cargo.toml"
        ]
    }}

Thank you @nerditation for the help and insight. I added this comment into the issue.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.