about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-09 13:08:57 +0000
committerbors <bors@rust-lang.org>2022-07-09 13:08:57 +0000
commit666343b759e4949415ce7ad786b3cede1263b0ae (patch)
tree9d9773aa9feb4cd70ef52657d1b0823fa2ffd9cf
parent2836dd15f753a490ea5b89e02c6cfcecd2f32984 (diff)
parent21062f9201ca05929a11c87a51850d45c8d8ef00 (diff)
downloadrust-666343b759e4949415ce7ad786b3cede1263b0ae.tar.gz
rust-666343b759e4949415ce7ad786b3cede1263b0ae.zip
Auto merge of #12727 - DorianListens:dscheidt/extract-var-field-name, r=jonas-schievink
fix: Improve suggested names for extracted variables

When extracting a field expression, if RA was unable to resolve the type of the
field, we would previously fall back to using "var_name" as the variable name.

Now, when the `Expr` being extracted matches a `FieldExpr`, we can use the
`NameRef`'s ident token as a fallback option.

fixes #10035
-rw-r--r--crates/ide-assists/src/handlers/extract_variable.rs8
-rw-r--r--crates/ide-assists/src/utils/suggest_name.rs25
2 files changed, 28 insertions, 5 deletions
diff --git a/crates/ide-assists/src/handlers/extract_variable.rs b/crates/ide-assists/src/handlers/extract_variable.rs
index ecf9feb0e55..71fa3ac3349 100644
--- a/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/crates/ide-assists/src/handlers/extract_variable.rs
@@ -943,8 +943,8 @@ struct S {
 }
 
 fn foo(s: &mut S) {
-    let $0var_name = &mut s.vec;
-    var_name.push(0);
+    let $0vec = &mut s.vec;
+    vec.push(0);
 }"#,
         );
     }
@@ -979,8 +979,8 @@ struct S {
 }
 
 fn foo(f: &mut Y) {
-    let $0var_name = &mut f.field.field.vec;
-    var_name.push(0);
+    let $0vec = &mut f.field.field.vec;
+    vec.push(0);
 }"#,
         );
     }
diff --git a/crates/ide-assists/src/utils/suggest_name.rs b/crates/ide-assists/src/utils/suggest_name.rs
index 5b79a7495f7..411e5b25b73 100644
--- a/crates/ide-assists/src/utils/suggest_name.rs
+++ b/crates/ide-assists/src/utils/suggest_name.rs
@@ -94,7 +94,8 @@ pub(crate) fn for_variable(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>)
 
     let mut next_expr = Some(expr.clone());
     while let Some(expr) = next_expr {
-        let name = from_call(&expr).or_else(|| from_type(&expr, sema));
+        let name =
+            from_call(&expr).or_else(|| from_type(&expr, sema)).or_else(|| from_field_name(&expr));
         if let Some(name) = name {
             return name;
         }
@@ -263,6 +264,15 @@ fn trait_name(trait_: &hir::Trait, db: &RootDatabase) -> Option<String> {
     Some(name)
 }
 
+fn from_field_name(expr: &ast::Expr) -> Option<String> {
+    let field = match expr {
+        ast::Expr::FieldExpr(field) => field,
+        _ => return None,
+    };
+    let ident = field.name_ref()?.ident_token()?;
+    normalize(ident.text())
+}
+
 #[cfg(test)]
 mod tests {
     use ide_db::base_db::{fixture::WithFixture, FileRange};
@@ -734,4 +744,17 @@ fn foo() { $0function.name().as_ref().unwrap().to_string()$0 }
             "name",
         );
     }
+
+    #[test]
+    fn struct_field_name() {
+        check(
+            r#"
+struct S<T> {
+    some_field: T;
+}
+fn foo<T>(some_struct: S<T>) { $0some_struct.some_field$0 }
+"#,
+            "some_field",
+        );
+    }
 }