From 95cabfd7227d5dc70d1ec370da3173e92447a476 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 4 Jan 2022 01:48:08 +0000 Subject: [PATCH 1/3] Correctly pass through mutable references when extracting a function --- .../src/handlers/extract_function.rs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 63b0a91ce5a..8c7fb03f7af 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs @@ -878,7 +878,7 @@ impl FunctionBody { // We can move the value into the function call if it's not used after the call, // if the var is not used but defined outside a loop we are extracting from we can't move it either // as the function will reuse it in the next iteration. - let move_local = !has_usages && defined_outside_parent_loop; + let move_local = (!has_usages && defined_outside_parent_loop) || ty.is_reference(); Param { var, ty, move_local, requires_mut, is_copy } }) .collect() @@ -4332,6 +4332,43 @@ fn foo() { fn $0fun_name(a: _) -> _ { a } +"#, + ); + } + + #[test] + fn test_jeroen() { + check_assist( + extract_function, + r#" +pub struct Foo { + field: u32, +} + +pub fn testfn(arg: &mut Foo) { + $0arg.field = 8; // write access + println!("{}", arg.field); // read access$0 + // Simulating access after the extracted portion + arg.field = 16; // write access + println!("{}", arg.field); // read access +} +"#, + r#" +pub struct Foo { + field: u32, +} + +pub fn testfn(arg: &mut Foo) { + fun_name(arg); // read access + // Simulating access after the extracted portion + arg.field = 16; // write access + println!("{}", arg.field); // read access +} + +fn $0fun_name(arg: &mut Foo) { + arg.field = 8; + println!("{}", arg.field); +} "#, ); } From 5beddf93e75ab1d001fc2382830cea560b1473fd Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 4 Jan 2022 02:12:53 +0000 Subject: [PATCH 2/3] additional test without further usages --- .../src/handlers/extract_function.rs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 8c7fb03f7af..2821f6cde98 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs @@ -4337,7 +4337,7 @@ fn $0fun_name(a: _) -> _ { } #[test] - fn test_jeroen() { + fn reference_mutable_param_with_further_usages() { check_assist( extract_function, r#" @@ -4365,6 +4365,37 @@ pub fn testfn(arg: &mut Foo) { println!("{}", arg.field); // read access } +fn $0fun_name(arg: &mut Foo) { + arg.field = 8; + println!("{}", arg.field); +} +"#, + ); + } + + #[test] + fn reference_mutable_param_without_further_usages() { + check_assist( + extract_function, + r#" +pub struct Foo { + field: u32, +} + +pub fn testfn(arg: &mut Foo) { + $0arg.field = 8; // write access + println!("{}", arg.field); // read access$0 +} +"#, + r#" +pub struct Foo { + field: u32, +} + +pub fn testfn(arg: &mut Foo) { + fun_name(arg); // read access +} + fn $0fun_name(arg: &mut Foo) { arg.field = 8; println!("{}", arg.field); From ec61abbe930ae07b2a89813e37d595de1d47b288 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 4 Jan 2022 10:11:04 +0000 Subject: [PATCH 3/3] reduced the tests to their bare essence --- .../src/handlers/extract_function.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 2821f6cde98..59c52dcd04a 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs @@ -4346,11 +4346,9 @@ pub struct Foo { } pub fn testfn(arg: &mut Foo) { - $0arg.field = 8; // write access - println!("{}", arg.field); // read access$0 + $0arg.field = 8;$0 // Simulating access after the extracted portion - arg.field = 16; // write access - println!("{}", arg.field); // read access + arg.field = 16; } "#, r#" @@ -4359,15 +4357,13 @@ pub struct Foo { } pub fn testfn(arg: &mut Foo) { - fun_name(arg); // read access + fun_name(arg); // Simulating access after the extracted portion - arg.field = 16; // write access - println!("{}", arg.field); // read access + arg.field = 16; } fn $0fun_name(arg: &mut Foo) { arg.field = 8; - println!("{}", arg.field); } "#, ); @@ -4383,8 +4379,7 @@ pub struct Foo { } pub fn testfn(arg: &mut Foo) { - $0arg.field = 8; // write access - println!("{}", arg.field); // read access$0 + $0arg.field = 8;$0 } "#, r#" @@ -4393,12 +4388,11 @@ pub struct Foo { } pub fn testfn(arg: &mut Foo) { - fun_name(arg); // read access + fun_name(arg); } fn $0fun_name(arg: &mut Foo) { arg.field = 8; - println!("{}", arg.field); } "#, );