rust-lang / rust-analyzer

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

Auto Import structure breaks with `"rust-analyzer.imports.prefix": "plain"` #17320

Open homchom opened 2 months ago

homchom commented 2 months ago

I do not believe this is a regression, but it is exacerbated by #17277.


rust-analyzer version: 0.3.1975-standalone (71a816a90 2024-05-26)

rustc version: 1.78.0 (9b00956e5 2024-04-29)

editor or extension: VSCode

relevant settings: rust-analyzer.imports.prefix

to reproduce:

  1. Create a new project with serde (including feature derive) as a dependency; any external crate would work, but I chose serde for this report.
  2. Create the following src directory
    ├── lib.rs
    ├── foo.rs

    and the following files.

    
    // lib.rs
    use serde::Serialize;

mod foo;

[derive(Serialize)]

struct Example;

impl Example { fn a() { } }

```rs
// foo.rs
pub fn b() {
}

It is important that the module is named foo, so it is alphabetically before serde.

  1. Through UI or JSON, change the setting rust-analyzer.imports.prefix to self.
  2. In the body of Example::a(), type b and use auto-import. Observe that self::foo::b is correctly imported in a group below serde::Serialize. Remove the function call and import, so it once again resembles Step 2.
  3. Change rust-analyzer.imports.prefix to plain (the default).
  4. In the body of Example::a(), type b and use auto-import. Observe that foo::c is incorrectly imported. It should be below serde::Serialize, as it is a current module import, but it is instead above serde::Serialize in the same group, as if it was an external crate.
dfireBird commented 2 months ago

As per this: https://github.com/rust-lang/rust-analyzer/blob/58a8f1b18539e67e80870ef71c8e88ddd2a815ac/crates/ide-db/src/imports/insert_use.rs#L286-L298

If the PathSegmentKind of first segment is Name (which it is for the imports in example), it either tag the import group as Std or ExternalCrate.

Seems like we may need to have list of local modules as arguments for this function and tag local modules ThisCrate or ThisModule.