Skip to content

Commit 1cc43ab

Browse files
committed
Add documentation on how whether a generated return type should be focused or not
1 parent a5c46e5 commit 1cc43ab

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

crates/ide_assists/src/handlers/generate_function.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ struct FunctionTemplate {
172172
leading_ws: String,
173173
fn_def: ast::Fn,
174174
ret_type: Option<ast::RetType>,
175-
should_focus_tail_expr: bool,
175+
should_focus_return_type: bool,
176176
trailing_ws: String,
177177
file: FileId,
178178
tail_expr: ast::Expr,
@@ -182,7 +182,8 @@ impl FunctionTemplate {
182182
fn to_string(&self, cap: Option<SnippetCap>) -> String {
183183
let f = match cap {
184184
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
186187
if let Some(ref ret_type) = self.ret_type {
187188
ret_type.syntax()
188189
} else {
@@ -206,7 +207,7 @@ struct FunctionBuilder {
206207
type_params: Option<ast::GenericParamList>,
207208
params: ast::ParamList,
208209
ret_type: Option<ast::RetType>,
209-
should_focus_tail_expr: bool,
210+
should_focus_return_type: bool,
210211
file: FileId,
211212
needs_pub: bool,
212213
is_async: bool,
@@ -239,7 +240,7 @@ impl FunctionBuilder {
239240
let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
240241
let is_async = await_expr.is_some();
241242

242-
let (ret_type, should_focus_tail_expr) =
243+
let (ret_type, should_focus_return_type) =
243244
make_return_type(ctx, &ast::Expr::CallExpr(call.clone()), target_module);
244245

245246
Some(Self {
@@ -248,7 +249,7 @@ impl FunctionBuilder {
248249
type_params,
249250
params,
250251
ret_type,
251-
should_focus_tail_expr,
252+
should_focus_return_type,
252253
file,
253254
needs_pub,
254255
is_async,
@@ -284,7 +285,7 @@ impl FunctionBuilder {
284285
let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
285286
let is_async = await_expr.is_some();
286287

287-
let (ret_type, should_focus_tail_expr) =
288+
let (ret_type, should_focus_return_type) =
288289
make_return_type(ctx, &ast::Expr::MethodCallExpr(call.clone()), target_module);
289290

290291
Some(Self {
@@ -293,7 +294,7 @@ impl FunctionBuilder {
293294
type_params,
294295
params,
295296
ret_type,
296-
should_focus_tail_expr,
297+
should_focus_return_type,
297298
file,
298299
needs_pub,
299300
is_async,
@@ -336,28 +337,36 @@ impl FunctionBuilder {
336337
FunctionTemplate {
337338
insert_offset,
338339
leading_ws,
339-
// PANIC: we guarantee we always create a function with a return type
340340
ret_type: fn_def.ret_type(),
341341
// PANIC: we guarantee we always create a function body with a tail expr
342342
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,
344344
fn_def,
345345
trailing_ws,
346346
file: self.file,
347347
}
348348
}
349349
}
350350

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.
351360
fn make_return_type(
352361
ctx: &AssistContext,
353362
call: &ast::Expr,
354363
target_module: Module,
355364
) -> (Option<ast::RetType>, bool) {
356-
let (ret_ty, should_focus_tail_expr) = {
365+
let (ret_ty, should_focus_return_type) = {
357366
match ctx.sema.type_of_expr(call).map(TypeInfo::original) {
358-
Some(ty) if ty.is_unit() => (None, false),
359367
Some(ty) if ty.is_unknown() => (Some(make::ty_unit()), true),
360368
None => (Some(make::ty_unit()), true),
369+
Some(ty) if ty.is_unit() => (None, false),
361370
Some(ty) => {
362371
let rendered = ty.display_source_code(ctx.db(), target_module.into());
363372
match rendered {
@@ -368,7 +377,7 @@ fn make_return_type(
368377
}
369378
};
370379
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)
372381
}
373382

374383
enum GeneratedFunctionTarget {

0 commit comments

Comments
 (0)