Description
I'm using Emacs with Eglot as its LSP client. My project structure is fairly complex:
+ project/
+ src/
+ include/
+ plugins/
+ rust/
+ Cargo.toml workspace
+ crate1/
+ crate2/
+ ...
I set rust-analyzer.linkedProjects
through .dir-locals.el
((nil . ((eglot-workspace-configuration . (:rust-analyzer (:linkedProjects ["$PROJECT/plugins/rust/Cargo.toml"]))))))
This works well: I have perfectly working completion and inlay hints and others. But the problem is: whenever I start the lsp client, there will be a false warning:
[eglot] Server reports (type=1): Failed to load workspaces.`rust-analyzer.linkedProjects` have been specified, which may be incorrect. Specified project paths:
$PROJECT/plugins/rust/Cargo.toml
This is quite annoying and misleading if it actually works. And I'm baffled why rust-analyzer complains this when it actually knows the path.
VSCode does not report this warning, so I reported this to Eglot first, and one of the Eglot contributors suggested that Eglot is unlikely to be incorrect here, so I forwarded the issue here.
Eglot debug logs (until the error message):
[jsonrpc] D[12:06:54.935] Running language server: rust-analyzer
[jsonrpc] e[12:06:54.935] --> initialize[1] {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":1596439,"clientInfo":{"name":"Eglot","version":"1.17.30"},"rootPath":"$PROJECT/","rootUri":"file://$PROJECT","initializationOptions":{},"capabilities":{"workspace":{"applyEdit":true,"executeCommand":{"dynamicRegistration":false},"workspaceEdit":{"documentChanges":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":false},"configuration":true,"workspaceFolders":true},"textDocument":{"synchronization":{"dynamicRegistration":false,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":false,"completionItem":{"snippetSupport":true,"deprecatedSupport":true,"resolveSupport":{"properties":["documentation","details","additionalTextEdits"]},"tagSupport":{"valueSet":[1]}},"contextSupport":true},"hover":{"dynamicRegistration":false,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":false,"signatureInformation":{"parameterInformation":{"labelOffsetSupport":true},"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true}},"references":{"dynamicRegistration":false},"definition":{"dynamicRegistration":false,"linkSupport":true},"declaration":{"dynamicRegistration":false,"linkSupport":true},"implementation":{"dynamicRegistration":false,"linkSupport":true},"typeDefinition":{"dynamicRegistration":false,"linkSupport":true},"documentSymbol":{"dynamicRegistration":false,"hierarchicalDocumentSymbolSupport":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"documentHighlight":{"dynamicRegistration":false},"codeAction":{"dynamicRegistration":false,"resolveSupport":{"properties":["edit","command"]},"dataSupport":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"isPreferredSupport":true},"formatting":{"dynamicRegistration":false},"rangeFormatting":{"dynamicRegistration":false},"rename":{"dynamicRegistration":false},"inlayHint":{"dynamicRegistration":false},"publishDiagnostics":{"relatedInformation":false,"codeDescriptionSupport":false,"tagSupport":{"valueSet":[1,2]}}},"window":{"showDocument":{"support":true},"workDoneProgress":true},"general":{"positionEncodings":["utf-32","utf-8","utf-16"]},"experimental":{}},"workspaceFolders":[{"uri":"file://$PROJECT","name":"$PROJECT/"}]}}
[jsonrpc] e[12:06:54.972] <-- initialize[1] {"jsonrpc":"2.0","id":1,"result":{"capabilities":{"positionEncoding":"utf-32","textDocumentSync":{"openClose":true,"change":2,"save":{}},"selectionRangeProvider":true,"hoverProvider":true,"completionProvider":{"resolveProvider":true,"triggerCharacters":[":",".","'","("],"completionItem":{"labelDetailsSupport":false}},"signatureHelpProvider":{"triggerCharacters":["(",",","<"]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"workspaceSymbolProvider":true,"codeActionProvider":{"codeActionKinds":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite"],"resolveProvider":true},"codeLensProvider":{"resolveProvider":true},"documentFormattingProvider":true,"documentRangeFormattingProvider":false,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":"=","moreTriggerCharacter":[".",">","{","("]},"renameProvider":{"prepareProvider":true},"foldingRangeProvider":true,"declarationProvider":true,"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":true},"fileOperations":{"willRename":{"filters":[{"scheme":"file","pattern":{"glob":"**/*.rs","matches":"file"}},{"scheme":"file","pattern":{"glob":"**","matches":"folder"}}]}}},"callHierarchyProvider":true,"semanticTokensProvider":{"legend":{"tokenTypes":["comment","decorator","enumMember","enum","function","interface","keyword","macro","method","namespace","number","operator","parameter","property","string","struct","typeParameter","variable","angle","arithmetic","attributeBracket","attribute","bitwise","boolean","brace","bracket","builtinAttribute","builtinType","character","colon","comma","comparison","constParameter","const","deriveHelper","derive","dot","escapeSequence","formatSpecifier","generic","invalidEscapeSequence","label","lifetime","logical","macroBang","parenthesis","procMacro","punctuation","selfKeyword","selfTypeKeyword","semicolon","static","toolModule","typeAlias","union","unresolvedReference"],"tokenModifiers":["async","documentation","declaration","static","defaultLibrary","associated","attribute","callable","constant","consuming","controlFlow","crateRoot","injected","intraDocLink","library","macro","mutable","procMacro","public","reference","trait","unsafe"]},"range":true,"full":{"delta":true}},"inlayHintProvider":{"resolveProvider":true},"diagnosticProvider":{"interFileDependencies":true,"workspaceDiagnostics":false},"experimental":{"externalDocs":true,"hoverRange":true,"joinLines":true,"matchingBrace":true,"moveItem":true,"onEnter":true,"openCargoToml":true,"parentModule":true,"runnables":{"kinds":["cargo"]},"ssr":true,"workspaceSymbolScopeKindFiltering":true}},"serverInfo":{"name":"rust-analyzer","version":"1.84.0 (9fc6b43 2025-01-07)"}}}
[jsonrpc] e[12:06:54.972] --> initialized {"jsonrpc":"2.0","method":"initialized","params":{}}
[jsonrpc] e[12:06:54.973] --> textDocument/didOpen {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file://$PROJECT/plugins/rust/lib/rinflex/src/rec_inflex.rs","version":0,"languageId":"rust","text":"$SKIPPED"}}}
[jsonrpc] e[12:06:54.974] --> workspace/didChangeConfiguration {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"rust-analyzer":{"linkedProjects":["$PROJECT/plugins/rust/Cargo.toml"]}}}}
[stderr] 2025-04-10T12:06:54.973365031+02:00 ERROR failed to find any projects in [AbsPathBuf("$PROJECT")]
[stderr] 2025-04-10T12:06:54.976596661+02:00 ERROR FetchWorkspaceError: rust-analyzer failed to fetch workspace
[stderr] 2025-04-10T12:06:54.97695733+02:00 ERROR FetchWorkspaceError: rust-analyzer failed to fetch workspace
[jsonrpc] e[12:06:54.984] <-- window/showMessage {"jsonrpc":"2.0","method":"window/showMessage","params":{"type":2,"message":"Failed to discover workspace.\nConsider adding the `Cargo.toml` of the workspace to the [`linkedProjects`](https://rust-analyzer.github.io/manual.html#rust-analyzer.linkedProjects) setting."}}
The problem can be reproduced with the latest nightly version rust-analyzer 1.88.0-nightly (934880f 2025-04-09) as well.
edit: $PROJECT
are not really envvars here. I used them to make the paths more clear.