rust-lang / rust-analyzer

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

Unresolved import for platform specific modules #6038

Closed GrayJack closed 2 years ago

GrayJack commented 3 years ago

I tried to search if it was reported but didn't found anything.

When importing the platform specific modules in std::os rust-analyzer gives me the following error: unresolved import. Also those modules don't show up for auto-complete.

When the module is used outside use statement, there is no error, but the semantic token are of the type unresolvedReference.

RA version

Latest master branch

Example

use std::os::unix;
jonas-schievink commented 3 years ago

We seem to have trouble finding/expanding the cfg_if! invocation

jonas-schievink commented 3 years ago

Oh, it's because we don't load the sysroot correctly. We just add a bunch of hard-coded path dependencies to libstd without looking at its Cargo.toml.

jfcha commented 3 years ago

I'm also seeing this issue for

use std::os::windows::ffi::{OsStrExt, OsStringExt};

in the 2020-09-21 release.

ttzztztz commented 3 years ago

Same issue.

iulianR commented 3 years ago

Hello, it's a bit spammy in VSCode (using Code Lens extension) because it looks like a hard error, making you think the code won't compile: image image image

It is possible to change it somehow it so it shows in a similar way to an {unknown} error (when ra is unable to determine type for example)? I think that was the previous behaviour before the 21-09-2020 release. Thanks!

lnicola commented 3 years ago

@iulianR you can disable that warning in the preferences (the experimental diagnostics key).

EDIT: "rust-analyzer.diagnostics.disabled": ["unresolved-import"]

leshow commented 3 years ago

I am running into this too, if I use the above disable though, won't that disable all unresolved import errors?

That doesn't seem to be desirable. Is there any other options? I assume it happens because rust-analyzer is set to build for all targets, and the import isn't available on some targets

jonas-schievink commented 3 years ago

No, it happens because

we don't load the sysroot correctly. We just add a bunch of hard-coded path dependencies to libstd without looking at its Cargo.toml.

You can only disable the unresolved import diagnostic entirely (although check-on-save will still display rustc's unresolved import messages, regardless of how r-a diagnostics are configured)

thomcc commented 3 years ago

This is (unsurprisingly) also broken for {core,std}::arch::*. I'm certain this used to work too... :(

flodiebold commented 3 years ago

It "used to work" in the sense that this diagnostic didn't show up, because the diagnostic wasn't implemented yet. You can make it not show up again with the setting mentioned above; you'll still get unresolved import errors from rustc. But at least we're now aware that rust-analyzer can't actually resolve these imports.

jonas-schievink commented 3 years ago

The diagnostic is already marked as experimental fwiw, so unless you opt into the experimental ones this shouldn't show up.

thomcc commented 3 years ago

It "used to work" in the sense that this diagnostic didn't show up

I guess I'll take your word for it that it never worked, but I was pretty sure I had autocomplete for some parts of core::arch in the past. Huh.

The diagnostic is already marked as experimental fwiw, so unless you opt into the experimental ones this shouldn't show up.

Hrm, I don't remember opting into experimental diagnostics anywhere.

jonas-schievink commented 3 years ago

Oh, turns out the experimental ones are on by default

cameron-rowe commented 3 years ago

Oh, turns out the experimental ones are on by default

Disabling that caused the error to go away for me. This works as a temporary workaround. Thanks.

blinsay commented 3 years ago

Is there documentation on disabling diagnostics in editors that aren't VSCode? I can't tell from this thread if rust-analyzer.diagnostics.disabled is a VSCode option or a rust-analyzer option.

Thanks for rust-analyzer, it's wonderful.

lnicola commented 3 years ago

It's a rust-analyzer option, but configuring it is client-dependant. If you're using coc.vim, you can use the same setting, otherwise it might be called diagnostics/enabled, without the program name.

If you figure it out and have the time, we'll probably accept client-specific documentation pull requests.

matklad commented 3 years ago

Some discussion here: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Where.20are.20third.20party.20crates.20in.20rustc-src.3F

matklad commented 3 years ago

https://github.com/rust-analyzer/rust-analyzer/pull/6294 papers over this issue

jonas-schievink commented 3 years ago

This still seems to happen, despite the workaround. Or does that only work if something else pulls in a cfg_if dependency?

matklad commented 3 years ago

Yeah, cfg_if should be in dep tree somewhere

taikulawo commented 3 years ago

Still showing this problem when I use use std::os::unix::io::{AsRawFd, RawFd}; :( Please fix it, think you :)

taikulawo commented 3 years ago

Mio seems works in WSL2

image

But my project doesn't show docs and hint.

image

talk2drys commented 3 years ago

same issue. even though it works

image

danfo commented 3 years ago

In my projects I have unresolved imports reported on files deep in ~/.rustup/. Sounds like it could be this known issue?

![Screen Shot 2020-12-07 at 9 09 17 am](https://user-images.githubusercontent.com/99922/101295894-08313c80-386c-11eb-9864-22eee8c2adbc.png)
axonasif commented 3 years ago

Same issue when using std::os::unix::fs::symlink.

2deth commented 3 years ago

Resolved?! 😳

image

❯ rust-analyzer --version
rust-analyzer 5e2935e
bjorn3 commented 3 years ago

This was worked around in #6294.

lnicola commented 3 years ago

But I think we've had reports of it even after #6294 + one week.

GrayJack commented 3 years ago

I think it's because cfg_if crate must be in the dependency tree for it to work

2deth commented 3 years ago

This was worked around in #6294.

Hmm it didn’t work last week.. iirc

2deth commented 3 years ago

"unresolved import"s are back.. ​😢​

I suspect that "resolved" happened after I put %s to target-dir.. And yes cfg_if.. cargo build has failed on that today.

But I cannot reproduce "resolved". I use nightly and update everyday, and messed up many things recently.

Sorry for the wrong report.

mvforell commented 3 years ago

@jonas-schievink you wrote:

Oh, it's because we don't load the sysroot correctly. We just add a bunch of hard-coded path dependencies to libstd without looking at its Cargo.toml.

I'm not familiar with how rust_analyzer's works, but quickly skimming through the code I found these lines where this hardcoding seems to reside. Without exactly knowing what I'm doing I added cfg_if to both strings, but sadly that does not seem to fix the issue.

Maybe you/someone could explain why it's not so simple, to make it easier to look into this issue?

jonas-schievink commented 3 years ago

cfg_if is a crates.io dependency, so it isn't available in the sysroot. Those lists only determine how the dependency graph within sysroot crates looks.

One possible way to solve this problem would be to vendor all external dependencies in the rust-src component. Another would be to run cargo metadata on the sysroot, which will download all crates.io dependencies (though it might require some file system trickery to avoid polluting rustup-managed directories).

thomcc commented 3 years ago

What would be needed to improve this in rust-analyzer? Is it possible or is it a fundamental limitation?

I'd be willing to try and work on it if possible, even if it's not exactly beginner-level. It is a ever-present pain point for me.

flodiebold commented 3 years ago

Maybe we could just vendor the definition of cfg_if ourselves in rust-analyzer, to make the workaround at least work in all cases.

inflation commented 3 years ago

I guess this is a great point why std should really have this macro in itself.

thomcc commented 3 years ago

Maybe we could just vendor the definition of cfg_if ourselves in rust-analyzer, to make the workaround at least work in all cases.

It doesn't actually work for me even if I explicitly add cfg_if into my dep tree. Like,

The following errors

#[cfg(target_arch = "x86_64")]
use core::arch::x86_64; 

One thing that doesn't error, but I wouldn't phrase as rust-analyzer actually working (it has no semantic knowledge but also no red squiggles) is when I put that import inside a function. At function scope rust-analyzer seems to fail to resolve the module, but doesn't mark it as erroring, e.g.

// partially works — syntax highlighting 
// is slightly wrong inside the function
// and no semantic support is available,
// but at least it doesn't error
fn foo() {
    #[cfg(target_arch = "x86_64")]
    use core::arch::x86_64 as arch;
    #[cfg(target_arch = "x86")]
    use core::arch::x86 as arch;
}

(Example of "slightly wrong" syntax highlighting: https://user-images.githubusercontent.com/860665/107137781-b8e7a680-68c4-11eb-91d8-77ef140a2bc2.png — normally the parts after x wouldn't be white)

While this is way better than it giving an error, it's still unfortunate as r-a failing to understand the code seems to be (unsurprisingly) somewhat viral, and pretty soon a lot of your code isn't understood.

So yeah, the workaround with cfg_if either broke, never worked, never worked in this case, ...


Tangentially...

I guess this is a great point why std should really have this macro in itself.

I used to agree but I think it's kinda a wrong way to structure stuff now in a lot of cases. Now I mostly just write the #[cfg(...)], which works much better with r-a. (Well, maybe my opinion would be different if these options all worked with it though).

Also, just purely aesthetically I think something more like:

cfg_match! {
    #[cfg(blah)] => { ... }
    #[cfg(foo)] => { ... }
}

Is a cleaner API (no repetition for "if"), and more natural expression support (although AFAIK none of the crates that implement this have expression support that isn't a little janky). Anyway, regardless of whether or not you agree, stabilizing it would have to go through this bikeshed-color-picking process...

Also note that core::arch is a dep of libcore (well... it's complicated) so libcore exposing cfg_if! might not help anyway, I'm not really sure.

bjorn3 commented 3 years ago

core::arch not resolving is a different issue. This one is due to #[path = "..."] mod arch; not working when the path is not part of any directory assumed to be part of a crate in the crate graph based on the output of cargo metadata.

thomcc commented 3 years ago

core::arch not resolving is a different issue. This one is due to #[path = "..."] mod arch; not working when the path is not part of any directory assumed to be part of a crate in the crate graph based on the output of cargo metadata.

Oh. Well. Is there a separate bug for that? How tractable is it to fix in r-a?

If it's very hard to fix in r-a I could do a patch to change stdarch itself to not use #[path] in the name of simplifying things for tooling probably, since usually the alternative there is just a slightly more complex mod/use setup.

lnicola commented 3 years ago

@jonas-schievink this doesn't seem to work for me even after https://github.com/rust-lang/rust/pull/81969/:

image

image

lnicola commented 3 years ago

Oh, there's plenty more in lib/rustlib/src/rust/library/std/src/sys/mod.rs

jonas-schievink commented 3 years ago

Ugh, how annoying

elinorbgr commented 3 years ago

Has something happened? I was successfully using the "add cfg-if in your dependency tree" method, but since today it no longer works, I again get unresolved import errors in vscode for std::os::unix::*.

Version 0.2.513 of the vscode rust-analyzer extension, and rustc 1.52.0-nightly (acca81892 2021-03-13)

nico-abram commented 3 years ago

I'm encountering this issue when doing use std::os::windows::ffi::OsStrExt; (With no conditional compilation attributes, it's a toy project that will only run in my machine). I don't have cfg_if in my dep tree

CDirkx commented 3 years ago

rust-lang/rust#84200 just got merged, which also removed more cfg_if in publicly exported items. I believe this should make everything in std::os usable, without needing to add cfg-if to your dependency tree. Can anyone confirm if this is the case?

jonas-schievink commented 3 years ago

Looks like this block still causes problems with std::os::unix: https://github.com/rust-lang/rust/blob/bacf770f2983a52f31e3537db5f0fe1ef2eaa874/library/std/src/sys/mod.rs#L27-L50

However, std::os::linux seems to work fine now :tada:

noproto commented 2 years ago

I'm no longer seeing any errors! (latest toolchain Rust 1.53, nightly rust-analyzer) 🥳🥳🥳

Meister1593 commented 2 years ago

Works for me only with git rust-analyzer (pretty much current nightly) and nightly rust 1.55 (nightly-x86_64-unknown-linux-gnu, 1.53 stable didn't work) rustc 1.55.0-nightly (150fad30e 2021-06-19) rust-analyzer 3843bd02a 2021-06-20 dev

jonas-schievink commented 2 years ago

Cool, looks like we can close this then. The more general problem on the r-a side is tracked in https://github.com/rust-analyzer/rust-analyzer/issues/7637.

xanderio commented 2 years ago

I'm still having this issue on my FreeBSD box with std::os::unix::ffi::OsStringExt. rustc 1.54.0 (a178d0322 2021-07-26) rust-analyzer bc084a6ee 2021-08-08 dev