Skip to content

Commit e2eaa99

Browse files
committed
Auto merge of rust-lang#12788 - hasali19:extract-var-mut, r=jonas-schievink
Fix extract variable assist for subexpression in mutable borrow This checks if the expression is in a mutable borrow and if so makes the extracted variable `mut`. Closes rust-lang#12786
2 parents ee2d5fe + ea19e70 commit e2eaa99

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

crates/ide-assists/src/handlers/extract_variable.rs

+31-5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
5858
_ => "",
5959
};
6060

61+
let parent_ref_expr = to_extract.syntax().parent().and_then(ast::RefExpr::cast);
62+
let var_modifier = match parent_ref_expr {
63+
Some(expr) if expr.mut_token().is_some() => "mut ",
64+
_ => "",
65+
};
66+
6167
let anchor = Anchor::from(&to_extract)?;
6268
let indent = anchor.syntax().prev_sibling_or_token()?.as_token()?.clone();
6369
let target = to_extract.syntax().text_range();
@@ -85,7 +91,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
8591

8692
match anchor {
8793
Anchor::Before(_) | Anchor::Replace(_) => {
88-
format_to!(buf, "let {} = {}", var_name, reference_modifier)
94+
format_to!(buf, "let {}{} = {}", var_modifier, var_name, reference_modifier)
8995
}
9096
Anchor::WrapInBlock(_) => {
9197
format_to!(buf, "{{ let {} = {}", var_name, reference_modifier)
@@ -100,8 +106,10 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
100106
}
101107
match ctx.config.snippet_cap {
102108
Some(cap) => {
103-
let snip = buf
104-
.replace(&format!("let {}", var_name), &format!("let $0{}", var_name));
109+
let snip = buf.replace(
110+
&format!("let {}{}", var_modifier, var_name),
111+
&format!("let {}$0{}", var_modifier, var_name),
112+
);
105113
edit.replace_snippet(cap, expr_range, snip)
106114
}
107115
None => edit.replace(expr_range, buf),
@@ -126,8 +134,10 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
126134
let offset = anchor.syntax().text_range().start();
127135
match ctx.config.snippet_cap {
128136
Some(cap) => {
129-
let snip =
130-
buf.replace(&format!("let {}", var_name), &format!("let $0{}", var_name));
137+
let snip = buf.replace(
138+
&format!("let {}{}", var_modifier, var_name),
139+
&format!("let {}$0{}", var_modifier, var_name),
140+
);
131141
edit.insert_snippet(cap, offset, snip)
132142
}
133143
None => edit.insert(offset, buf),
@@ -1247,6 +1257,22 @@ fn foo() {
12471257
let local = &S::new();
12481258
let $0x = &local.sub;
12491259
x.do_thing();
1260+
}"#,
1261+
);
1262+
}
1263+
1264+
#[test]
1265+
fn test_extract_var_for_mutable_borrow() {
1266+
check_assist(
1267+
extract_variable,
1268+
r#"
1269+
fn foo() {
1270+
let v = &mut $00$0;
1271+
}"#,
1272+
r#"
1273+
fn foo() {
1274+
let mut $0var_name = 0;
1275+
let v = &mut var_name;
12501276
}"#,
12511277
);
12521278
}

0 commit comments

Comments
 (0)