about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorA4-Tacks <wdsjxhno1001@163.com>2025-09-05 15:34:49 +0800
committerA4-Tacks <wdsjxhno1001@163.com>2025-09-05 15:57:51 +0800
commitb9b235acb088aa88d96890c930e174ab56abbccd (patch)
treefefbeec6b871043cad53fff38f22f078a20fee8a /src/tools/rust-analyzer
parentab5113a316959f2558f03a7bf590e967602f02df (diff)
downloadrust-b9b235acb088aa88d96890c930e174ab56abbccd.tar.gz
rust-b9b235acb088aa88d96890c930e174ab56abbccd.zip
Fix indent for unresolved_field fixes
Examples
---
```rust
mod indent {
    struct Foo {}

    fn foo() {
        let foo = Foo{};
        foo.bar$0;
    }
}
```

**Before this PR**:

```rust
mod indent {
    struct Foo {        bar: ()
}

    fn foo() {
        let foo = Foo{};
        foo.bar;
    }
}
```

**After this PR**:

```rust
mod indent {
    struct Foo {
        bar: ()
    }

    fn foo() {
        let foo = Foo{};
        foo.bar;
    }
}
```

---
New field list add newline

```rust
mod indent {
    struct Foo;

    fn foo() {
        Foo.bar$0;
    }
}
```

**Before this PR**:

```rust
mod indent {
    struct Foo{ bar: () }

    fn foo() {
        Foo.bar;
    }
}
```

**After this PR**:

```rust
mod indent {
    struct Foo {
        bar: (),
    }

    fn foo() {
        Foo.bar;
    }
}
```
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs65
1 files changed, 52 insertions, 13 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs
index 69015898967..358e0c43c2a 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs
@@ -1,5 +1,3 @@
-use std::iter;
-
 use either::Either;
 use hir::{Adt, FileRange, HasSource, HirDisplay, InFile, Struct, Union, db::ExpandDatabase};
 use ide_db::text_edit::TextEdit;
@@ -194,17 +192,20 @@ fn add_field_to_struct_fix(
                 Some(make::visibility_pub_crate())
             };
             // FIXME: Allow for choosing a visibility modifier see https://github.com/rust-lang/rust-analyzer/issues/11563
-            let indent = IndentLevel::from_node(struct_syntax.value) + 1;
+            let indent = IndentLevel::from_node(struct_syntax.value);
 
-            let field = make::record_field(visibility, field_name, suggested_type).indent(indent);
-            let record_field_list = make::record_field_list(iter::once(field));
+            let field =
+                make::record_field(visibility, field_name, suggested_type).indent(indent + 1);
             // A Unit Struct with no `;` is invalid syntax. We should not suggest this fix.
             let semi_colon =
                 algo::skip_trivia_token(struct_syntax.value.last_token()?, Direction::Prev)?;
             if semi_colon.kind() != SyntaxKind::SEMICOLON {
                 return None;
             }
-            src_change_builder.replace(semi_colon.text_range(), record_field_list.to_string());
+            src_change_builder.replace(
+                semi_colon.text_range(),
+                format!(" {{\n{}{field},\n{indent}}}", indent + 1),
+            );
 
             Some(Assist {
                 id: AssistId::quick_fix("convert-unit-struct-to-record-struct"),
@@ -230,7 +231,7 @@ fn record_field_layout(
     field_list: ast::RecordFieldList,
     struct_syntax: &SyntaxNode,
 ) -> Option<(TextSize, String)> {
-    let (offset, needs_comma, trailing_new_line, indent) = match field_list.fields().last() {
+    let (offset, needs_comma, indent) = match field_list.fields().last() {
         Some(record_field) => {
             let syntax = algo::skip_trivia_token(field_list.r_curly_token()?, Direction::Prev)?;
 
@@ -239,19 +240,22 @@ fn record_field_layout(
             (
                 last_field_syntax.text_range().end(),
                 syntax.kind() != SyntaxKind::COMMA,
-                false,
                 last_field_indent,
             )
         }
         // Empty Struct. Add a field right before the closing brace
         None => {
             let indent = IndentLevel::from_node(struct_syntax) + 1;
-            let offset = field_list.r_curly_token()?.text_range().start();
-            (offset, false, true, indent)
+            let offset = field_list.l_curly_token()?.text_range().end();
+            (offset, false, indent)
         }
     };
-    let comma = if needs_comma { ",\n" } else { "" };
-    let trailing_new_line = if trailing_new_line { "\n" } else { "" };
+    let trailing_new_line = if !field_list.syntax().text().contains_char('\n') {
+        format!("\n{}", field_list.indent_level())
+    } else {
+        String::new()
+    };
+    let comma = if needs_comma { ",\n" } else { "\n" };
     let record_field = make::record_field(visibility, name, suggested_type);
 
     Some((offset, format!("{comma}{indent}{record_field}{trailing_new_line}")))
@@ -377,18 +381,24 @@ fn foo() {
     fn unresolved_field_fix_on_unit() {
         check_fix(
             r#"
+            mod indent {
                 struct Foo;
 
                 fn foo() {
                     Foo.bar$0;
                 }
+            }
             "#,
             r#"
-                struct Foo{ bar: () }
+            mod indent {
+                struct Foo {
+                    bar: (),
+                }
 
                 fn foo() {
                     Foo.bar;
                 }
+            }
             "#,
         );
     }
@@ -396,6 +406,7 @@ fn foo() {
     fn unresolved_field_fix_on_empty() {
         check_fix(
             r#"
+            mod indent {
                 struct Foo{
                 }
 
@@ -403,8 +414,10 @@ fn foo() {
                     let foo = Foo{};
                     foo.bar$0;
                 }
+            }
             "#,
             r#"
+            mod indent {
                 struct Foo{
                     bar: ()
                 }
@@ -413,6 +426,32 @@ fn foo() {
                     let foo = Foo{};
                     foo.bar;
                 }
+            }
+            "#,
+        );
+
+        check_fix(
+            r#"
+            mod indent {
+                struct Foo {}
+
+                fn foo() {
+                    let foo = Foo{};
+                    foo.bar$0;
+                }
+            }
+            "#,
+            r#"
+            mod indent {
+                struct Foo {
+                    bar: ()
+                }
+
+                fn foo() {
+                    let foo = Foo{};
+                    foo.bar;
+                }
+            }
             "#,
         );
     }