rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.28k stars 1.61k forks source link

`unresolved import` for some `#[path = ".."] #3898

Open qryxip opened 4 years ago

qryxip commented 4 years ago

unresolved import errors show up for:

  1. File paths whose extensions are not rs
  2. Absolute file paths
  3. Outside of the workspace (or simply workspace_root or somewhere?)

rust-analzyer

These files do exist.

$ tree -I target "$PWD"
/home/ryo/src/local/a
├── Cargo.lock
├── Cargo.toml
├── empty-file
├── empty-file.rs
└── src
    └── main.rs

1 directory, 7 files
$ touch ./src/main.rs && cargo clippy
    Checking a v0.1.0 (/home/ryo/src/local/a)
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s
$ # OK
flodiebold commented 4 years ago

It seems unlikely that we'll ever support these. The set of files we look at has to be limited by design, and ".rs files in the workspace or dependencies" is a pretty reasonable set, I think. The only solution I could maybe imagine is having a setting for extra files.

hhamana commented 4 years ago

I ran into a similar issue. I'll post it here.

Defining local dependencies outside of the workspace in cargo.toml as such also has weird behaviour.

mydep = { path = "../mydep/" }

In this case, it does not output any error or warning, but also does not compute types/suggestions/tree/docs. Function definition can be linked to similarly-named function in the impl of unrelated structs. (ie, mydep::MyDepStruct::new() is linking to crate::CrateStruct::new()

jonas-schievink commented 4 years ago

The problem here is that we aren't just limiting ourselves to looking at files in the workspace, but in the package. That means that no files in parents of lib.rs can be included, which breaks core::arch (https://github.com/rust-analyzer/rust-analyzer/issues/5982).

mitinarseny commented 3 years ago

I run into same issue. Is there any progress?

ilyvion commented 4 months ago

It seems unlikely that we'll ever support these. The set of files we look at has to be limited by design, and ".rs files in the workspace or dependencies" is a pretty reasonable set, I think. The only solution I could maybe imagine is having a setting for extra files.

Couldn't rust-analyzer be "automagically" informed of said extra files by what these #[path] attributes have been set to? It's not like you need to load "every file outside the workspace/package" but the ones brought in by #[path] kind of seem like obvious "extra" files to bring in. It's not a particularly pleasant dev experience to have this and the lack of code-completion that it comes with: image

Especially given that this is probably 99% of use-cases for #[path] to begin with. In my case, I'm including files that are normally individual examples binary files into a bigger "combined bin" project for what I think is a very good reason (a combined WASM build of all the examples for publication on the project's github.io page) and I can't really think of another clean way to achieve this without any code/file duplication or hassle.

bmulder-innoseis commented 2 months ago

Basically this. In my particular project, it basically makes rust-analyzer as well as VSCode useless for working with Rust. My project structure looks as follows:

Now, since my submodule folder is used in both my binary crates and my library crate, it needs to be above them in the directory hierarchy. But my workspace members' cargo.toml are one directory below. Rust-analyzer does not allow this project structure, either forcing me to include this submodule three times as a subdirectory of all 3 crates, or copying my shared source files over many times. At this point it forces me to either buy Rust Rover or just code in vim or emacs, since VSCode does not add much besides annoying error squiggles.

bmulder-innoseis commented 1 week ago

Currently I worked around it by adding a symlink to the submodule inside each crate that depends on it. In general, symlinks can be used as a workaround here from the directory that contains the lib.rs to the external directory to achieve the same thing as the #[path = "../../foo"] statement.