@@ -14,7 +14,9 @@ use syntax::{
14
14
ast:: {
15
15
self ,
16
16
edit:: { AstNodeEdit , IndentLevel } ,
17
- make, HasArgList , HasGenericParams , HasName ,
17
+ make,
18
+ syntax_factory:: SyntaxFactory ,
19
+ HasArgList , HasGenericParams , HasName ,
18
20
} ,
19
21
hacks:: parse_expr_from_str,
20
22
ted, AstNode , Direction , SyntaxKind , SyntaxNode , TextSize , ToSmolStr , T ,
@@ -75,32 +77,32 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
75
77
let mut ret_ty = callable. return_type ( ) ;
76
78
let mut closure_mentioned_generic_params = ret_ty. generic_params ( ctx. db ( ) ) ;
77
79
78
- let mut params = callable
79
- . params ( )
80
- . into_iter ( )
81
- . map ( |param| {
82
- let node = ctx. sema . source ( param. clone ( ) ) ?. value . right ( ) ?;
83
- let param_ty = param. ty ( ) ;
84
- closure_mentioned_generic_params. extend ( param_ty. generic_params ( ctx. db ( ) ) ) ;
85
- match node. ty ( ) {
86
- Some ( _) => Some ( node) ,
87
- None => {
88
- let ty = param_ty
89
- . display_source_code ( ctx. db ( ) , module. into ( ) , true )
90
- . unwrap_or_else ( |_| "_" . to_owned ( ) ) ;
91
- Some ( make:: param ( node. pat ( ) ?, make:: ty ( & ty) ) )
92
- }
80
+ let make = SyntaxFactory :: new ( ) ;
81
+
82
+ let mut params = Vec :: new ( ) ;
83
+ for param in callable. params ( ) . into_iter ( ) {
84
+ let node = ctx. sema . source ( param. clone ( ) ) ?. value . right ( ) ?;
85
+ let param_ty = param. ty ( ) ;
86
+ closure_mentioned_generic_params. extend ( param_ty. generic_params ( ctx. db ( ) ) ) ;
87
+ let param = match node. ty ( ) {
88
+ Some ( _) => node. clone_subtree ( ) . clone_for_update ( ) ,
89
+ None => {
90
+ let ty = param_ty
91
+ . display_source_code ( ctx. db ( ) , module. into ( ) , true )
92
+ . unwrap_or_else ( |_| "_" . to_owned ( ) ) ;
93
+ make. param ( node. pat ( ) ?, make. ty ( & ty) )
93
94
}
94
- } )
95
- . collect :: < Option < Vec < _ > > > ( ) ?;
95
+ } ;
96
+ params. push ( param) ;
97
+ }
96
98
97
99
let mut body = closure. body ( ) ?. clone_for_update ( ) ;
98
100
let mut is_gen = false ;
99
101
let mut is_async = closure. async_token ( ) . is_some ( ) ;
100
102
if is_async {
101
103
ret_ty = ret_ty. future_output ( ctx. db ( ) ) ?;
102
104
}
103
- // We defer the wrapping of the body in the block, because `make:: block()` will generate a new node,
105
+ // We defer the wrapping of the body in the block, because `make. block()` will generate a new node,
104
106
// but we need to locate `AstPtr`s inside the body.
105
107
let mut wrap_body_in_block = true ;
106
108
if let ast:: Expr :: BlockExpr ( block) = & body {
@@ -150,10 +152,12 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
150
152
"Convert closure to fn" ,
151
153
closure. param_list ( ) ?. syntax ( ) . text_range ( ) ,
152
154
|builder| {
153
- let closure_name_or_default = closure_name
154
- . as_ref ( )
155
- . map ( |( _, _, it) | it. clone ( ) )
156
- . unwrap_or_else ( || make:: name ( "fun_name" ) ) ;
155
+ let closure_name_or_default =
156
+ if let Some ( name) = closure_name. as_ref ( ) . map ( |( _, _, it) | it. clone ( ) ) {
157
+ name. clone_subtree ( ) . clone_for_update ( )
158
+ } else {
159
+ make. name ( "fun_name" )
160
+ } ;
157
161
let captures = closure_ty. captured_items ( ctx. db ( ) ) ;
158
162
let capture_tys = closure_ty. capture_types ( ctx. db ( ) ) ;
159
163
@@ -168,19 +172,19 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
168
172
// FIXME: Allow configuring the replacement of `self`.
169
173
let capture_name =
170
174
if capture. local ( ) . is_self ( ctx. db ( ) ) && !capture. has_field_projections ( ) {
171
- make:: name ( "this" )
175
+ make. name ( "this" )
172
176
} else {
173
- make:: name ( & capture. place_to_name ( ctx. db ( ) ) )
177
+ make. name ( & capture. place_to_name ( ctx. db ( ) ) )
174
178
} ;
175
179
176
180
closure_mentioned_generic_params. extend ( capture_ty. generic_params ( ctx. db ( ) ) ) ;
177
181
178
182
let capture_ty = capture_ty
179
183
. display_source_code ( ctx. db ( ) , module. into ( ) , true )
180
184
. unwrap_or_else ( |_| "_" . to_owned ( ) ) ;
181
- params. push ( make:: param (
182
- ast:: Pat :: IdentPat ( make:: ident_pat ( false , false , capture_name. clone_subtree ( ) ) ) ,
183
- make:: ty ( & capture_ty) ,
185
+ params. push ( make. param (
186
+ ast:: Pat :: IdentPat ( make. ident_pat ( false , false , capture_name. clone_subtree ( ) ) ) ,
187
+ make. ty ( & capture_ty) ,
184
188
) ) ;
185
189
186
190
for capture_usage in capture. usages ( ) . sources ( ctx. db ( ) ) {
@@ -199,16 +203,16 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
199
203
}
200
204
} ;
201
205
let replacement = wrap_capture_in_deref_if_needed (
206
+ & make,
202
207
& expr,
203
208
& capture_name,
204
209
capture. kind ( ) ,
205
210
capture_usage. is_ref ( ) ,
206
- )
207
- . clone_for_update ( ) ;
211
+ ) ;
208
212
capture_usages_replacement_map. push ( ( expr, replacement) ) ;
209
213
}
210
214
211
- captures_as_args. push ( capture_as_arg ( ctx, capture) ) ;
215
+ captures_as_args. push ( capture_as_arg ( ctx, & make , capture) ) ;
212
216
}
213
217
214
218
let ( closure_type_params, closure_where_clause) =
@@ -223,7 +227,7 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
223
227
}
224
228
225
229
let body = if wrap_body_in_block {
226
- make:: block_expr ( [ ] , Some ( body) )
230
+ make. block_expr ( [ ] , Some ( body) )
227
231
} else {
228
232
ast:: BlockExpr :: cast ( body. syntax ( ) . clone ( ) ) . unwrap ( )
229
233
} ;
@@ -237,7 +241,7 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>)
237
241
. unwrap_or_else ( |_| "_" . to_owned ( ) ) ;
238
242
Some ( make:: ret_type ( make:: ty ( & ret_ty) ) )
239
243
} ;
240
- let mut fn_ = make:: fn_ (
244
+ let mut fn_ = make. fn_ (
241
245
None ,
242
246
closure_name_or_default. clone ( ) ,
243
247
closure_type_params,
@@ -466,6 +470,7 @@ fn compute_closure_type_params(
466
470
}
467
471
468
472
fn wrap_capture_in_deref_if_needed (
473
+ make : & SyntaxFactory ,
469
474
expr : & ast:: Expr ,
470
475
capture_name : & ast:: Name ,
471
476
capture_kind : CaptureKind ,
@@ -483,7 +488,7 @@ fn wrap_capture_in_deref_if_needed(
483
488
expr
484
489
}
485
490
486
- let capture_name = make:: expr_path ( make:: path_from_text ( & capture_name. text ( ) ) ) ;
491
+ let capture_name = make. expr_path ( make:: path_from_text ( & capture_name. text ( ) ) ) ;
487
492
if capture_kind == CaptureKind :: Move || is_ref {
488
493
return capture_name;
489
494
}
@@ -505,13 +510,18 @@ fn wrap_capture_in_deref_if_needed(
505
510
if does_autoderef {
506
511
return capture_name;
507
512
}
508
- make:: expr_prefix ( T ! [ * ] , capture_name) . into ( )
513
+ make. expr_prefix ( T ! [ * ] , capture_name) . into ( )
509
514
}
510
515
511
- fn capture_as_arg ( ctx : & AssistContext < ' _ > , capture : & ClosureCapture ) -> ast:: Expr {
516
+ fn capture_as_arg (
517
+ ctx : & AssistContext < ' _ > ,
518
+ make : & SyntaxFactory ,
519
+ capture : & ClosureCapture ,
520
+ ) -> ast:: Expr {
512
521
let place =
513
522
parse_expr_from_str ( & capture. display_place_source_code ( ctx. db ( ) ) , ctx. file_id ( ) . edition ( ) )
514
- . expect ( "`display_place_source_code()` produced an invalid expr" ) ;
523
+ . expect ( "`display_place_source_code()` produced an invalid expr" )
524
+ . clone_subtree ( ) ;
515
525
let needs_mut = match capture. kind ( ) {
516
526
CaptureKind :: SharedRef => false ,
517
527
CaptureKind :: MutableRef | CaptureKind :: UniqueSharedRef => true ,
@@ -522,7 +532,7 @@ fn capture_as_arg(ctx: &AssistContext<'_>, capture: &ClosureCapture) -> ast::Exp
522
532
return expr. expr ( ) . expect ( "`display_place_source_code()` produced an invalid expr" ) ;
523
533
}
524
534
}
525
- make:: expr_ref ( place, needs_mut)
535
+ make. expr_ref ( place, needs_mut)
526
536
}
527
537
528
538
fn handle_calls (
0 commit comments