@@ -191,6 +191,22 @@ impl Completions {
191191 func : hir:: Function ,
192192 local_name : Option < String > ,
193193 ) {
194+ fn add_arg ( arg : & str , ty : & Type , ctx : & CompletionContext ) -> String {
195+ let mut prefix = "" ;
196+ if let Some ( derefed_ty) = ty. remove_ref ( ) {
197+ ctx. scope . process_all_names ( & mut |name, scope| {
198+ if prefix != "" {
199+ return ;
200+ }
201+ if let ScopeDef :: Local ( local) = scope {
202+ if name. to_string ( ) == arg && local. can_unify ( derefed_ty. clone ( ) , ctx. db ) {
203+ prefix = if ty. is_mutable_reference ( ) { "&mut " } else { "&" } ;
204+ }
205+ }
206+ } ) ;
207+ }
208+ prefix. to_string ( ) + arg
209+ } ;
194210 let name = local_name. unwrap_or_else ( || func. name ( ctx. db ) . to_string ( ) ) ;
195211 let ast_node = func. source ( ctx. db ) . value ;
196212
@@ -205,12 +221,20 @@ impl Completions {
205221 . set_deprecated ( is_deprecated ( func, ctx. db ) )
206222 . detail ( function_declaration ( & ast_node) ) ;
207223
224+ let params_ty = func. params ( ctx. db ) ;
208225 let params = ast_node
209226 . param_list ( )
210227 . into_iter ( )
211228 . flat_map ( |it| it. params ( ) )
212- . flat_map ( |it| it. pat ( ) )
213- . map ( |pat| pat. to_string ( ) . trim_start_matches ( '_' ) . into ( ) )
229+ . zip ( params_ty)
230+ . flat_map ( |( it, param_ty) | {
231+ if let Some ( pat) = it. pat ( ) {
232+ let name = pat. to_string ( ) ;
233+ let arg = name. trim_start_matches ( '_' ) ;
234+ return Some ( add_arg ( arg, & param_ty, ctx) ) ;
235+ }
236+ None
237+ } )
214238 . collect ( ) ;
215239
216240 builder = builder. add_call_parens ( ctx, name, Params :: Named ( params) ) ;
@@ -863,6 +887,85 @@ fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 }
863887 ) ;
864888 }
865889
890+ #[ test]
891+ fn insert_ref_when_matching_local_in_scope ( ) {
892+ check_edit (
893+ "ref_arg" ,
894+ r#"
895+ struct Foo {}
896+ fn ref_arg(x: &Foo) {}
897+ fn main() {
898+ let x = Foo {};
899+ ref_ar<|>
900+ }
901+ "# ,
902+ r#"
903+ struct Foo {}
904+ fn ref_arg(x: &Foo) {}
905+ fn main() {
906+ let x = Foo {};
907+ ref_arg(${1:&x})$0
908+ }
909+ "# ,
910+ ) ;
911+ }
912+
913+ #[ test]
914+ fn insert_mut_ref_when_matching_local_in_scope ( ) {
915+ check_edit (
916+ "ref_arg" ,
917+ r#"
918+ struct Foo {}
919+ fn ref_arg(x: &mut Foo) {}
920+ fn main() {
921+ let x = Foo {};
922+ ref_ar<|>
923+ }
924+ "# ,
925+ r#"
926+ struct Foo {}
927+ fn ref_arg(x: &mut Foo) {}
928+ fn main() {
929+ let x = Foo {};
930+ ref_arg(${1:&mut x})$0
931+ }
932+ "# ,
933+ ) ;
934+ }
935+
936+ #[ test]
937+ fn insert_ref_when_matching_local_in_scope_for_method ( ) {
938+ check_edit (
939+ "apply_foo" ,
940+ r#"
941+ struct Foo {}
942+ struct Bar {}
943+ impl Bar {
944+ fn apply_foo(&self, x: &Foo) {}
945+ }
946+
947+ fn main() {
948+ let x = Foo {};
949+ let y = Bar {};
950+ y.<|>
951+ }
952+ "# ,
953+ r#"
954+ struct Foo {}
955+ struct Bar {}
956+ impl Bar {
957+ fn apply_foo(&self, x: &Foo) {}
958+ }
959+
960+ fn main() {
961+ let x = Foo {};
962+ let y = Bar {};
963+ y.apply_foo(${1:&x})$0
964+ }
965+ "# ,
966+ ) ;
967+ }
968+
866969 #[ test]
867970 fn inserts_parens_for_tuple_enums ( ) {
868971 mark:: check!( inserts_parens_for_tuple_enums) ;
0 commit comments