Skip to content

Commit a5c46e5

Browse files
committed
Factor out return type handling for both function and method
1 parent 0834e05 commit a5c46e5

File tree

1 file changed

+75
-101
lines changed

1 file changed

+75
-101
lines changed

crates/ide_assists/src/handlers/generate_function.rs

Lines changed: 75 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ struct FunctionTemplate {
171171
insert_offset: TextSize,
172172
leading_ws: String,
173173
fn_def: ast::Fn,
174-
ret_type: ast::RetType,
174+
ret_type: Option<ast::RetType>,
175175
should_focus_tail_expr: bool,
176176
trailing_ws: String,
177177
file: FileId,
@@ -183,7 +183,11 @@ impl FunctionTemplate {
183183
let f = match cap {
184184
Some(cap) => {
185185
let cursor = if self.should_focus_tail_expr {
186-
self.ret_type.syntax()
186+
if let Some(ref ret_type) = self.ret_type {
187+
ret_type.syntax()
188+
} else {
189+
self.tail_expr.syntax()
190+
}
187191
} else {
188192
self.tail_expr.syntax()
189193
};
@@ -201,7 +205,7 @@ struct FunctionBuilder {
201205
fn_name: ast::Name,
202206
type_params: Option<ast::GenericParamList>,
203207
params: ast::ParamList,
204-
ret_type: ast::RetType,
208+
ret_type: Option<ast::RetType>,
205209
should_focus_tail_expr: bool,
206210
file: FileId,
207211
needs_pub: bool,
@@ -235,33 +239,8 @@ impl FunctionBuilder {
235239
let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
236240
let is_async = await_expr.is_some();
237241

238-
// should_focus_tail_expr intends to express a rough level of confidence about
239-
// the correctness of the return type.
240-
//
241-
// If we are able to infer some return type, and that return type is not unit, we
242-
// don't want to render the snippet. The assumption here is in this situation the
243-
// return type is just as likely to be correct as any other part of the generated
244-
// function.
245-
//
246-
// In the case where the return type is inferred as unit it is likely that the
247-
// user does in fact intend for this generated function to return some non unit
248-
// type, but that the current state of their code doesn't allow that return type
249-
// to be accurately inferred.
250-
let (ret_ty, should_focus_tail_expr) = {
251-
match ctx.sema.type_of_expr(&ast::Expr::CallExpr(call.clone())).map(TypeInfo::original)
252-
{
253-
Some(ty) if ty.is_unknown() || ty.is_unit() => (make::ty_unit(), true),
254-
Some(ty) => {
255-
let rendered = ty.display_source_code(ctx.db(), target_module.into());
256-
match rendered {
257-
Ok(rendered) => (make::ty(&rendered), false),
258-
Err(_) => (make::ty_unit(), true),
259-
}
260-
}
261-
None => (make::ty_unit(), true),
262-
}
263-
};
264-
let ret_type = make::ret_type(ret_ty);
242+
let (ret_type, should_focus_tail_expr) =
243+
make_return_type(ctx, &ast::Expr::CallExpr(call.clone()), target_module);
265244

266245
Some(Self {
267246
target,
@@ -305,44 +284,16 @@ impl FunctionBuilder {
305284
let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
306285
let is_async = await_expr.is_some();
307286

308-
// should_render_snippet intends to express a rough level of confidence about
309-
// the correctness of the return type.
310-
//
311-
// If we are able to infer some return type, and that return type is not unit, we
312-
// don't want to render the snippet. The assumption here is in this situation the
313-
// return type is just as likely to be correct as any other part of the generated
314-
// function.
315-
//
316-
// In the case where the return type is inferred as unit it is likely that the
317-
// user does in fact intend for this generated function to return some non unit
318-
// type, but that the current state of their code doesn't allow that return type
319-
// to be accurately inferred.
320-
let (ret_ty, should_render_snippet) = {
321-
match ctx
322-
.sema
323-
.type_of_expr(&ast::Expr::MethodCallExpr(call.clone()))
324-
.map(TypeInfo::original)
325-
{
326-
Some(ty) if ty.is_unknown() || ty.is_unit() => (make::ty_unit(), true),
327-
Some(ty) => {
328-
let rendered = ty.display_source_code(ctx.db(), target_module.into());
329-
match rendered {
330-
Ok(rendered) => (make::ty(&rendered), false),
331-
Err(_) => (make::ty_unit(), true),
332-
}
333-
}
334-
None => (make::ty_unit(), true),
335-
}
336-
};
337-
let ret_type = make::ret_type(ret_ty);
287+
let (ret_type, should_focus_tail_expr) =
288+
make_return_type(ctx, &ast::Expr::MethodCallExpr(call.clone()), target_module);
338289

339290
Some(Self {
340291
target,
341292
fn_name,
342293
type_params,
343294
params,
344295
ret_type,
345-
should_focus_tail_expr: should_render_snippet,
296+
should_focus_tail_expr,
346297
file,
347298
needs_pub,
348299
is_async,
@@ -359,7 +310,7 @@ impl FunctionBuilder {
359310
self.type_params,
360311
self.params,
361312
fn_body,
362-
Some(self.ret_type),
313+
self.ret_type,
363314
self.is_async,
364315
);
365316
let leading_ws;
@@ -386,7 +337,7 @@ impl FunctionBuilder {
386337
insert_offset,
387338
leading_ws,
388339
// PANIC: we guarantee we always create a function with a return type
389-
ret_type: fn_def.ret_type().unwrap(),
340+
ret_type: fn_def.ret_type(),
390341
// PANIC: we guarantee we always create a function body with a tail expr
391342
tail_expr: fn_def.body().unwrap().tail_expr().unwrap(),
392343
should_focus_tail_expr: self.should_focus_tail_expr,
@@ -397,6 +348,29 @@ impl FunctionBuilder {
397348
}
398349
}
399350

351+
fn make_return_type(
352+
ctx: &AssistContext,
353+
call: &ast::Expr,
354+
target_module: Module,
355+
) -> (Option<ast::RetType>, bool) {
356+
let (ret_ty, should_focus_tail_expr) = {
357+
match ctx.sema.type_of_expr(call).map(TypeInfo::original) {
358+
Some(ty) if ty.is_unit() => (None, false),
359+
Some(ty) if ty.is_unknown() => (Some(make::ty_unit()), true),
360+
None => (Some(make::ty_unit()), true),
361+
Some(ty) => {
362+
let rendered = ty.display_source_code(ctx.db(), target_module.into());
363+
match rendered {
364+
Ok(rendered) => (Some(make::ty(&rendered)), false),
365+
Err(_) => (Some(make::ty_unit()), true),
366+
}
367+
}
368+
}
369+
};
370+
let ret_type = ret_ty.map(|rt| make::ret_type(rt));
371+
(ret_type, should_focus_tail_expr)
372+
}
373+
400374
enum GeneratedFunctionTarget {
401375
BehindItem(SyntaxNode),
402376
InEmptyItemList(SyntaxNode),
@@ -825,8 +799,8 @@ fn foo() {
825799
bar("bar")
826800
}
827801
828-
fn bar(arg: &str) ${0:-> ()} {
829-
todo!()
802+
fn bar(arg: &str) {
803+
${0:todo!()}
830804
}
831805
"#,
832806
)
@@ -846,8 +820,8 @@ fn foo() {
846820
bar('x')
847821
}
848822
849-
fn bar(arg: char) ${0:-> ()} {
850-
todo!()
823+
fn bar(arg: char) {
824+
${0:todo!()}
851825
}
852826
"#,
853827
)
@@ -867,8 +841,8 @@ fn foo() {
867841
bar(42)
868842
}
869843
870-
fn bar(arg: i32) ${0:-> ()} {
871-
todo!()
844+
fn bar(arg: i32) {
845+
${0:todo!()}
872846
}
873847
",
874848
)
@@ -888,8 +862,8 @@ fn foo() {
888862
bar(42 as u8)
889863
}
890864
891-
fn bar(arg: u8) ${0:-> ()} {
892-
todo!()
865+
fn bar(arg: u8) {
866+
${0:todo!()}
893867
}
894868
",
895869
)
@@ -913,8 +887,8 @@ fn foo() {
913887
bar(x as u8)
914888
}
915889
916-
fn bar(x: u8) ${0:-> ()} {
917-
todo!()
890+
fn bar(x: u8) {
891+
${0:todo!()}
918892
}
919893
",
920894
)
@@ -936,8 +910,8 @@ fn foo() {
936910
bar(worble)
937911
}
938912
939-
fn bar(worble: ()) ${0:-> ()} {
940-
todo!()
913+
fn bar(worble: ()) {
914+
${0:todo!()}
941915
}
942916
",
943917
)
@@ -965,8 +939,8 @@ fn baz() {
965939
bar(foo())
966940
}
967941
968-
fn bar(foo: impl Foo) ${0:-> ()} {
969-
todo!()
942+
fn bar(foo: impl Foo) {
943+
${0:todo!()}
970944
}
971945
",
972946
)
@@ -992,8 +966,8 @@ fn foo() {
992966
bar(&baz())
993967
}
994968
995-
fn bar(baz: &Baz) ${0:-> ()} {
996-
todo!()
969+
fn bar(baz: &Baz) {
970+
${0:todo!()}
997971
}
998972
",
999973
)
@@ -1021,8 +995,8 @@ fn foo() {
1021995
bar(Baz::baz())
1022996
}
1023997
1024-
fn bar(baz: Baz::Bof) ${0:-> ()} {
1025-
todo!()
998+
fn bar(baz: Baz::Bof) {
999+
${0:todo!()}
10261000
}
10271001
",
10281002
)
@@ -1043,8 +1017,8 @@ fn foo<T>(t: T) {
10431017
bar(t)
10441018
}
10451019
1046-
fn bar(t: T) ${0:-> ()} {
1047-
todo!()
1020+
fn bar(t: T) {
1021+
${0:todo!()}
10481022
}
10491023
",
10501024
)
@@ -1097,8 +1071,8 @@ fn foo() {
10971071
bar(closure)
10981072
}
10991073
1100-
fn bar(closure: ()) ${0:-> ()} {
1101-
todo!()
1074+
fn bar(closure: ()) {
1075+
${0:todo!()}
11021076
}
11031077
",
11041078
)
@@ -1118,8 +1092,8 @@ fn foo() {
11181092
bar(baz)
11191093
}
11201094
1121-
fn bar(baz: ()) ${0:-> ()} {
1122-
todo!()
1095+
fn bar(baz: ()) {
1096+
${0:todo!()}
11231097
}
11241098
",
11251099
)
@@ -1143,8 +1117,8 @@ fn foo() {
11431117
bar(baz(), baz())
11441118
}
11451119
1146-
fn bar(baz_1: Baz, baz_2: Baz) ${0:-> ()} {
1147-
todo!()
1120+
fn bar(baz_1: Baz, baz_2: Baz) {
1121+
${0:todo!()}
11481122
}
11491123
",
11501124
)
@@ -1168,8 +1142,8 @@ fn foo() {
11681142
bar(baz(), baz(), "foo", "bar")
11691143
}
11701144
1171-
fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) ${0:-> ()} {
1172-
todo!()
1145+
fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) {
1146+
${0:todo!()}
11731147
}
11741148
"#,
11751149
)
@@ -1188,8 +1162,8 @@ fn foo() {
11881162
",
11891163
r"
11901164
mod bar {
1191-
pub(crate) fn my_fn() ${0:-> ()} {
1192-
todo!()
1165+
pub(crate) fn my_fn() {
1166+
${0:todo!()}
11931167
}
11941168
}
11951169
@@ -1224,8 +1198,8 @@ fn bar() {
12241198
baz(foo)
12251199
}
12261200
1227-
fn baz(foo: foo::Foo) ${0:-> ()} {
1228-
todo!()
1201+
fn baz(foo: foo::Foo) {
1202+
${0:todo!()}
12291203
}
12301204
"#,
12311205
)
@@ -1248,8 +1222,8 @@ fn foo() {
12481222
mod bar {
12491223
fn something_else() {}
12501224
1251-
pub(crate) fn my_fn() ${0:-> ()} {
1252-
todo!()
1225+
pub(crate) fn my_fn() {
1226+
${0:todo!()}
12531227
}
12541228
}
12551229
@@ -1276,8 +1250,8 @@ fn foo() {
12761250
r"
12771251
mod bar {
12781252
mod baz {
1279-
pub(crate) fn my_fn() ${0:-> ()} {
1280-
todo!()
1253+
pub(crate) fn my_fn() {
1254+
${0:todo!()}
12811255
}
12821256
}
12831257
}
@@ -1305,8 +1279,8 @@ fn main() {
13051279
r"
13061280
13071281
1308-
pub(crate) fn bar() ${0:-> ()} {
1309-
todo!()
1282+
pub(crate) fn bar() {
1283+
${0:todo!()}
13101284
}",
13111285
)
13121286
}

0 commit comments

Comments
 (0)