@@ -172,7 +172,7 @@ struct FunctionTemplate {
172
172
leading_ws : String ,
173
173
fn_def : ast:: Fn ,
174
174
ret_type : Option < ast:: RetType > ,
175
- should_focus_tail_expr : bool ,
175
+ should_focus_return_type : bool ,
176
176
trailing_ws : String ,
177
177
file : FileId ,
178
178
tail_expr : ast:: Expr ,
@@ -182,7 +182,8 @@ impl FunctionTemplate {
182
182
fn to_string ( & self , cap : Option < SnippetCap > ) -> String {
183
183
let f = match cap {
184
184
Some ( cap) => {
185
- let cursor = if self . should_focus_tail_expr {
185
+ let cursor = if self . should_focus_return_type {
186
+ // Focus the return type if there is one
186
187
if let Some ( ref ret_type) = self . ret_type {
187
188
ret_type. syntax ( )
188
189
} else {
@@ -206,7 +207,7 @@ struct FunctionBuilder {
206
207
type_params : Option < ast:: GenericParamList > ,
207
208
params : ast:: ParamList ,
208
209
ret_type : Option < ast:: RetType > ,
209
- should_focus_tail_expr : bool ,
210
+ should_focus_return_type : bool ,
210
211
file : FileId ,
211
212
needs_pub : bool ,
212
213
is_async : bool ,
@@ -239,7 +240,7 @@ impl FunctionBuilder {
239
240
let await_expr = call. syntax ( ) . parent ( ) . and_then ( ast:: AwaitExpr :: cast) ;
240
241
let is_async = await_expr. is_some ( ) ;
241
242
242
- let ( ret_type, should_focus_tail_expr ) =
243
+ let ( ret_type, should_focus_return_type ) =
243
244
make_return_type ( ctx, & ast:: Expr :: CallExpr ( call. clone ( ) ) , target_module) ;
244
245
245
246
Some ( Self {
@@ -248,7 +249,7 @@ impl FunctionBuilder {
248
249
type_params,
249
250
params,
250
251
ret_type,
251
- should_focus_tail_expr ,
252
+ should_focus_return_type ,
252
253
file,
253
254
needs_pub,
254
255
is_async,
@@ -284,7 +285,7 @@ impl FunctionBuilder {
284
285
let await_expr = call. syntax ( ) . parent ( ) . and_then ( ast:: AwaitExpr :: cast) ;
285
286
let is_async = await_expr. is_some ( ) ;
286
287
287
- let ( ret_type, should_focus_tail_expr ) =
288
+ let ( ret_type, should_focus_return_type ) =
288
289
make_return_type ( ctx, & ast:: Expr :: MethodCallExpr ( call. clone ( ) ) , target_module) ;
289
290
290
291
Some ( Self {
@@ -293,7 +294,7 @@ impl FunctionBuilder {
293
294
type_params,
294
295
params,
295
296
ret_type,
296
- should_focus_tail_expr ,
297
+ should_focus_return_type ,
297
298
file,
298
299
needs_pub,
299
300
is_async,
@@ -336,28 +337,36 @@ impl FunctionBuilder {
336
337
FunctionTemplate {
337
338
insert_offset,
338
339
leading_ws,
339
- // PANIC: we guarantee we always create a function with a return type
340
340
ret_type : fn_def. ret_type ( ) ,
341
341
// PANIC: we guarantee we always create a function body with a tail expr
342
342
tail_expr : fn_def. body ( ) . unwrap ( ) . tail_expr ( ) . unwrap ( ) ,
343
- should_focus_tail_expr : self . should_focus_tail_expr ,
343
+ should_focus_return_type : self . should_focus_return_type ,
344
344
fn_def,
345
345
trailing_ws,
346
346
file : self . file ,
347
347
}
348
348
}
349
349
}
350
350
351
+ /// Makes an optional return type along with whether the return type should be focused by the cursor.
352
+ /// If we cannot infer what the return type should be, we create unit as a placeholder.
353
+ ///
354
+ /// The rule for whether we focus a return type or not (and thus focus the function body),
355
+ /// is rather simple:
356
+ /// * If we could *not* infer what the return type should be, focus it (so the user can fill-in
357
+ /// the correct return type).
358
+ /// * If we could infer the return type, don't focus it (and thus focus the function body) so the
359
+ /// user can change the `todo!` function body.
351
360
fn make_return_type (
352
361
ctx : & AssistContext ,
353
362
call : & ast:: Expr ,
354
363
target_module : Module ,
355
364
) -> ( Option < ast:: RetType > , bool ) {
356
- let ( ret_ty, should_focus_tail_expr ) = {
365
+ let ( ret_ty, should_focus_return_type ) = {
357
366
match ctx. sema . type_of_expr ( call) . map ( TypeInfo :: original) {
358
- Some ( ty) if ty. is_unit ( ) => ( None , false ) ,
359
367
Some ( ty) if ty. is_unknown ( ) => ( Some ( make:: ty_unit ( ) ) , true ) ,
360
368
None => ( Some ( make:: ty_unit ( ) ) , true ) ,
369
+ Some ( ty) if ty. is_unit ( ) => ( None , false ) ,
361
370
Some ( ty) => {
362
371
let rendered = ty. display_source_code ( ctx. db ( ) , target_module. into ( ) ) ;
363
372
match rendered {
@@ -368,7 +377,7 @@ fn make_return_type(
368
377
}
369
378
} ;
370
379
let ret_type = ret_ty. map ( |rt| make:: ret_type ( rt) ) ;
371
- ( ret_type, should_focus_tail_expr )
380
+ ( ret_type, should_focus_return_type )
372
381
}
373
382
374
383
enum GeneratedFunctionTarget {
0 commit comments