Skip to content
This repository was archived by the owner on Nov 18, 2022. It is now read-only.

Incorrectly reports missing Cargo.toml if it's not in the root #222

Closed
chriskrycho opened this issue Jan 1, 2018 · 11 comments · Fixed by #457
Closed

Incorrectly reports missing Cargo.toml if it's not in the root #222

chriskrycho opened this issue Jan 1, 2018 · 11 comments · Fixed by #457

Comments

@chriskrycho
Copy link

I'm working on a small multi-lang project where the Cargo.toml is in a child of the root directory:

root/
  README.md
  rust/
    cargo.toml
  # other stuff

It incorrectly reports that:

Cargo.toml must be in the workspace in order to support all features

Of course, Cargo.toml is in the workspace…

code-error

@jeffryang24
Copy link

Yes... It also happens to me...

@maelvls
Copy link
Contributor

maelvls commented May 18, 2018

I think the error message has been changed to

A Cargo.toml file must be at the root of the workspace in order to support all features

(cf. #207) meaning that rls-vscode expects cargo.toml to be at the root of your workspace. Sadly, this implies we have to find a workaround for multi-lang projects (for example, use the "Add folder to workspace" feature in vscode) 🤔
Update: apparently, the extension does not work with multiple workspaces opened at the same time. So I have no other workaround than opening multiple instances of vscode 😕 But I found a workaround in the atom extension's README:

Multi-crate projects

A root Cargo.toml is required in each atom project, however cargo workspaces can be used to support multiple crates in a single project. For example, a project with 'rust_foo' & 'rust_bar' directories/crates could have the following root Cargo.toml

# Cargo.toml
[workspace]
members = [
    "rust_foo",
    "rust_bar",
]

@enioluwas
Copy link

What about a feature instead that instead allows you to sepcify what folder the Cargo.toml is in? I have seen many other VS Code extensions do this. Perhaps add it to the context menu of a folder "Set as Cargo.toml location"?

@maelvls
Copy link
Contributor

maelvls commented Jun 6, 2018

I perused some of the extension's code but could not find how to hack it so that the 'root_path' for Cargo.toml is different from workspace.rootPath. That said, I found out that 3333323 removed the variable rls.root that allowed running the rust language server from a different directory.

The commit message says:

rls.path is a better option, we don't need two ways and I don't think anyone uses this one any more

Maybe we need it back? 😊

Update: I misunderstood the first intent of rls.root. It is not what we want. What we want is something like:

    } else if (rls_root) {
        const env = await makeRlsEnv();
        console.info('running `cargo run` in ' + rls_root);
        childProcessPromise = Promise.resolve(child_process.spawn(
            CONFIGURATION.rustupPath, ['run', CONFIGURATION.channel, 'cargo', 'run', '--release'],
            { cwd: rls_root, env })
        );
    }

Update: I think I went a bit fast; rls.root isn't actually what we want. But we can use that as a basis for a new parameter, e.g., rust-client.cargoSubdir and pass the correct cwd to the spawn of RLS (in the child_process call)

Update2: setting cwd at the child_process cannot work as the Language Server protocol uses the workspaceFolder information, thus changing cwd won't do anything.

@enioluwas
Copy link

Yup! Seems like that's it. Especially with neon/ffi-like modules I think people would like this customized instead of having two VS Code workspaces open at the same time to have rls functionality.

maelvls added a commit to maelvls/rls-vscode that referenced this issue Jun 7, 2018
Fixes rust-lang#222.

This patch is quite hacky and may reveal my lack of knowledge on the RLS or
LSP architectures. My idea was to give the user the opportunity using the
variable `rust-client.cargoSubdir` to select a subdirectory as the root for
the Cargo.toml file.

To do that, I hacked the vscode's workspaceFoldervariable; my hack won't
work with multi-workspaces.

Alternate solutions:
- (not so good idea) add a new setting to the initialize JSON-RPC (similar
  to the existing `omitInitBuild` in the rls server) that would set a
  different path that the one given by vscode's workspaceFolder.
- (better) we add support for multi-root workspaces in the RLS server;
  (mentionned in  <rust-lang/rls#608>)
  but this does not really help when we want to open a general project
  where one of the subfolders is a rust project.
- we tell people that in order to get RLS working in a subdirectory, they
  must use the 'Multi-crate projects' feature or the 'rlsCommandOverride'
  feature (see README at <https://github.com/mehcode/atom-ide-rust>).
@joseluisq
Copy link

Any progress on this feature?

@jannickj
Copy link
Contributor

This issue is really annoying when working with a rust, rarely is rust my sole project.
@maelvalais Solutions seems like a nice hack, but it doesn't fix the problem if you have multiple rust projects at the same time. What we actually need is for the extension to find the cargo.toml based on the file you have active and then either reuse or spin up a new language server.

@maelvls
Copy link
Contributor

maelvls commented Nov 14, 2018

You are right, my hack does not really help in these scenarios. Let us imagine we have open vscode in an hypothetical project/ folder that contains multiple rust projects (each one with a Cargo.toml and src/*.rs):

project/
├── lib1/
│  ├── Cargo.toml
│  └── src/
│     └── main1.rs
├── lib2/
│  ├── Cargo.toml
│  └── src/
│     └── main2.rs
└── lib3/
   ├── Cargo.toml
   └── src/
      └── main3.rs

Now, let's imagine a scenario:

  1. open the project/ in vscode
  2. open file main1.rs
  3. the rust-client extension fires up and looks for Cargo.toml in the parent folder and finds lib1/Cargo.toml
  4. because a Cargo.toml is found, the extension creates a new rls instance
  5. now, open file main2.rs
  6. the extension notices this file isn't related to the previous Cargo.toml from lib1/
  7. the extension looks for a Cargo.toml in the parent folder and finds lib2/Cargo.toml
  8. the extension creates a second rls instance (but the other one is still running)

@jannickj Does this scenario fit your expectation of how the extension should operate?

@jannickj
Copy link
Contributor

@maelvalais yes that's exactly how I would love it to operate :)

@jannickj
Copy link
Contributor

#457 implements what @maelvalais proposed

@jannickj
Copy link
Contributor

@nrc, I'm really looking forward to having this feature, do you know when you have time to look at it?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants