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
This commit is contained in:
Dorian Scheidt 2022-07-08 18:01:44 -05:00
parent 2836dd15f7
commit 21062f9201
2 changed files with 28 additions and 5 deletions

View File

@ -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);
}"#,
);
}

View File

@ -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",
);
}
}