rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.69k stars 12.64k forks source link

Automatically `s/use core::/use std::/` where applicable #101008

Open mqudsi opened 2 years ago

mqudsi commented 2 years ago

Where a developer incorrectly uses core:: to import a type/trait/module not available in core:: but available in std::, the default (and only) diagnostic should be "Foo not found in core::path::to, did you mean std::path::to::Foo?"

Example:

use core::sync::RwLock;

fn main() {}

Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=610c8c7d885be88995c49a1b9a36fa91

The current output is:

error[[E0432]](https://doc.rust-lang.org/stable/error-index.html#E0432): unresolved import `core::sync::RwLock`
 --> src/main.rs:1:5
  |
1 | [use core::sync::RwLock;](https://play.rust-lang.org/#)
  |     ^^^^^^^^^^^^^^^^^^ no `RwLock` in `sync`

Ideally the output should look like:

error[[E0432]](https://doc.rust-lang.org/stable/error-index.html#E0432): unresolved import `core::sync::RwLock`
 --> src/main.rs:1:5
  |
1 | [use core::sync::RwLock;](https://play.rust-lang.org/#)
  |     ^^^^^^^^^^^^^^^^^^ no `RwLock` in `sync`
  |                        Did you mean `std::sync::RwLock`?

If compiling under #![no_std], then perhaps the message can be adjusted (although this might need a separate issue) accordingly, for example:

error[[E0432]](https://doc.rust-lang.org/stable/error-index.html#E0432): unresolved import `core::sync::RwLock`
 --> src/main.rs:1:5
  |
1 | [use core::sync::RwLock;](https://play.rust-lang.org/#)
  |     ^^^^^^^^^^^^^^^^^^ `std::sync::RwLock` is not available under `#![no_std]`
gimbling-away commented 2 years ago

I'm going to be honest, this feels slightly unnecessary. While I'm sure it's coming from good intentions, "accidentally used an std type from the core crate" just seems like a situation that'd very rarely occur

compiler-errors commented 2 years ago

It would be neat to generalize this, for any crate1::a::b::C to search {all other crates}::a::b::C.

mqudsi commented 2 years ago

I'm going to be honest, this feels slightly unnecessary. While I'm sure it's coming from good intentions, "accidentally used an std type from the core crate" just seems like a situation that'd very rarely occur

I don't think it occurs as a rarely as you think, but the real reason it's not that big of a deal is because no_std developers tend to know what they're doing and can don't need a hand-holding explanation for what went wrong. I have a preference for not plugging in std when core will do so that I'm always aware of just how much no_std-friendly my code is; I don't know how prevalent of an approach that is with others.

Looking back, I think RwLock was a stupid example - it's obviously not bare no_std compatible. But something like core::error::Error isn't an unreasonable thing to try and use. I'm all for whatever changes we can make that would make writing incidentally no_std code easier for devs in the rust ecosystem.

veera-sivarajan commented 2 weeks ago

Output from rustc 1.81.0:

error[E0432]: unresolved import `core::sync::RwLock`
 --> <source>:1:5
  |
1 | use core::sync::RwLock;
  |     ^^^^^^^^^^^^^^^^^^ no `RwLock` in `sync`
  |
help: consider importing this struct instead
  |
1 | use std::sync::RwLock;
  |     ~~~~~~~~~~~~~~~~~

error: aborting due to 1 previous error