Skip to main content

ide_assists/handlers/
generate_function.rs

1use hir::{
2    Adt, AsAssocItem, HasSource, HirDisplay, Module, PathResolution, Semantics, StructKind, Type,
3    TypeInfo,
4};
5use ide_db::{
6    FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap,
7    defs::{Definition, NameRefClass},
8    famous_defs::FamousDefs,
9    helpers::is_editable_crate,
10    path_transform::PathTransform,
11    source_change::SourceChangeBuilder,
12};
13use itertools::Itertools;
14use stdx::to_lower_snake_case;
15use syntax::{
16    Edition, SyntaxKind, SyntaxNode, T, TextRange,
17    ast::{
18        self, AstNode, BlockExpr, CallExpr, HasArgList, HasGenericParams, HasModuleItem,
19        HasTypeBounds,
20        edit::{AstNodeEdit, IndentLevel},
21        syntax_factory::SyntaxFactory,
22    },
23    syntax_editor::{Position, SyntaxEditor},
24};
25
26use crate::{
27    AssistContext, AssistId, Assists,
28    utils::{convert_reference_type, expr_fill_default, find_struct_impl},
29};
30
31// Assist: generate_function
32//
33// Adds a stub function with a signature matching the function under the cursor.
34//
35// ```
36// struct Baz;
37// fn baz() -> Baz { Baz }
38// fn foo() {
39//     bar$0("", baz());
40// }
41//
42// ```
43// ->
44// ```
45// struct Baz;
46// fn baz() -> Baz { Baz }
47// fn foo() {
48//     bar("", baz());
49// }
50//
51// fn bar(arg: &'static str, baz: Baz) ${0:-> _} {
52//     todo!()
53// }
54//
55// ```
56pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
57    gen_fn(acc, ctx).or_else(|| gen_method(acc, ctx))
58}
59
60fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
61    let path_expr: ast::PathExpr = ctx.find_node_at_offset()?;
62    let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?;
63    let path = path_expr.path()?;
64    let name_ref = path.segment()?.name_ref()?;
65    if ctx.sema.resolve_path(&path).is_some() {
66        // The function call already resolves, no need to add a function
67        return None;
68    }
69
70    let fn_name = &*name_ref.text();
71    let TargetInfo { target_module, adt_info, target, file } =
72        fn_target_info(ctx, path, &call, fn_name)?;
73
74    if let Some(m) = target_module
75        && !is_editable_crate(m.krate(ctx.db()), ctx.db())
76    {
77        return None;
78    }
79    let make = SyntaxFactory::without_mappings();
80
81    let function_builder =
82        FunctionBuilder::from_call(&make, ctx, &call, fn_name, target_module, target, &adt_info)?;
83    let text_range = call.syntax().text_range();
84    let label = format!("Generate {} function", function_builder.fn_name);
85    add_func_to_accumulator(acc, ctx, text_range, function_builder, file, adt_info, label)
86}
87
88struct TargetInfo {
89    target_module: Option<Module>,
90    adt_info: Option<AdtInfo>,
91    target: GeneratedFunctionTarget,
92    file: FileId,
93}
94
95impl TargetInfo {
96    fn new(
97        target_module: Option<Module>,
98        adt_info: Option<AdtInfo>,
99        target: GeneratedFunctionTarget,
100        file: FileId,
101    ) -> Self {
102        Self { target_module, adt_info, target, file }
103    }
104}
105
106fn fn_target_info(
107    ctx: &AssistContext<'_, '_>,
108    path: ast::Path,
109    call: &CallExpr,
110    fn_name: &str,
111) -> Option<TargetInfo> {
112    match path.qualifier() {
113        Some(qualifier) => match ctx.sema.resolve_path(&qualifier) {
114            Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) => {
115                get_fn_target_info(ctx, Some(module), call.clone())
116            }
117            Some(hir::PathResolution::Def(hir::ModuleDef::Adt(adt))) => {
118                if let hir::Adt::Enum(_) = adt {
119                    // Don't suggest generating function if the name starts with an uppercase letter
120                    if fn_name.starts_with(char::is_uppercase) {
121                        return None;
122                    }
123                }
124
125                assoc_fn_target_info(ctx, call, adt, fn_name)
126            }
127            Some(hir::PathResolution::SelfType(impl_)) => {
128                let adt = impl_.self_ty(ctx.db()).as_adt()?;
129                assoc_fn_target_info(ctx, call, adt, fn_name)
130            }
131            _ => None,
132        },
133        _ => get_fn_target_info(ctx, None, call.clone()),
134    }
135}
136
137fn gen_method(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
138    let call: ast::MethodCallExpr = ctx.find_node_at_offset()?;
139    if ctx.sema.resolve_method_call(&call).is_some() {
140        return None;
141    }
142
143    let fn_name = call.name_ref()?;
144    let receiver_ty = ctx.sema.type_of_expr(&call.receiver()?)?.original().strip_references();
145    let adt = receiver_ty.as_adt()?;
146
147    let target_module = adt.module(ctx.sema.db);
148    if !is_editable_crate(target_module.krate(ctx.db()), ctx.db()) {
149        return None;
150    }
151
152    let enclosing_impl = ctx.find_node_at_offset::<ast::Impl>();
153    let cursor_impl = enclosing_impl.filter(|impl_| {
154        ctx.sema.to_def(impl_).is_some_and(|def| {
155            def.self_ty(ctx.sema.db).as_adt() == Some(adt) && def.trait_(ctx.sema.db).is_none()
156        })
157    });
158
159    let (impl_, file) = if let Some(impl_) = cursor_impl {
160        (Some(impl_), ctx.vfs_file_id())
161    } else {
162        get_adt_source(ctx, &adt, fn_name.text().as_str())?
163    };
164    let target = get_method_target(ctx, &impl_, &adt)?;
165
166    let make = SyntaxFactory::without_mappings();
167
168    let function_builder = FunctionBuilder::from_method_call(
169        &make,
170        ctx,
171        &call,
172        &fn_name,
173        receiver_ty,
174        target_module,
175        target,
176    )?;
177    let text_range = call.syntax().text_range();
178    let adt_info = AdtInfo::new(adt, impl_.is_some());
179    let label = format!("Generate {} method", function_builder.fn_name);
180    add_func_to_accumulator(acc, ctx, text_range, function_builder, file, Some(adt_info), label)
181}
182
183fn add_func_to_accumulator(
184    acc: &mut Assists,
185    ctx: &AssistContext<'_, '_>,
186    text_range: TextRange,
187    function_builder: FunctionBuilder,
188    file: FileId,
189    adt_info: Option<AdtInfo>,
190    label: String,
191) -> Option<()> {
192    acc.add(AssistId::generate("generate_function"), label, text_range, |edit| {
193        let target = function_builder.target.clone();
194        let snippet_cap = ctx.config.snippet_cap;
195
196        if let Some(adt) = adt_info
197            .and_then(|adt_info| if adt_info.impl_exists { None } else { Some(adt_info.adt) })
198        {
199            target.insert_impl_at(edit, file, ctx, &function_builder, adt, snippet_cap);
200        } else {
201            target.insert_fn_at(edit, file, &function_builder, snippet_cap);
202        }
203    })
204}
205
206fn get_adt_source(
207    ctx: &AssistContext<'_, '_>,
208    adt: &hir::Adt,
209    fn_name: &str,
210) -> Option<(Option<ast::Impl>, FileId)> {
211    let range = adt.source(ctx.sema.db)?.syntax().original_file_range_rooted(ctx.sema.db);
212
213    let file = ctx.sema.parse(range.file_id);
214    let adt_source =
215        ctx.sema.find_node_at_offset_with_macros(file.syntax(), range.range.start())?;
216    find_struct_impl(ctx, &adt_source, &[fn_name.to_owned()])
217        .map(|impl_| (impl_, range.file_id.file_id(ctx.db())))
218}
219
220struct FunctionBuilder {
221    target: GeneratedFunctionTarget,
222    fn_name: ast::Name,
223    generic_param_list: Option<ast::GenericParamList>,
224    where_clause: Option<ast::WhereClause>,
225    params: ast::ParamList,
226    fn_body: BlockExpr,
227    ret_type: Option<ast::RetType>,
228    should_focus_return_type: bool,
229    visibility: Visibility,
230    is_async: bool,
231    target_edition: Edition,
232}
233
234impl FunctionBuilder {
235    /// Prepares a generated function that matches `call`.
236    /// The function is generated in `target_module` or next to `call`
237    fn from_call(
238        make: &SyntaxFactory,
239        ctx: &AssistContext<'_, '_>,
240        call: &ast::CallExpr,
241        fn_name: &str,
242        target_module: Option<Module>,
243        target: GeneratedFunctionTarget,
244        adt_info: &Option<AdtInfo>,
245    ) -> Option<Self> {
246        let target_module =
247            target_module.or_else(|| ctx.sema.scope(target.syntax()).map(|it| it.module()))?;
248        let target_edition = target_module.krate(ctx.db()).edition(ctx.db());
249
250        let current_module = ctx.sema.scope(call.syntax())?.module();
251        let visibility = calculate_necessary_visibility(current_module, target_module, ctx);
252        let fn_name = make.name(fn_name);
253        let mut necessary_generic_params = FxHashSet::default();
254        let params = fn_args(
255            make,
256            ctx,
257            target_module,
258            ast::CallableExpr::Call(call.clone()),
259            &mut necessary_generic_params,
260        )?;
261
262        let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
263        let is_async = await_expr.is_some();
264
265        let ret_type;
266        let should_focus_return_type;
267        let fn_body;
268
269        // If generated function has the name "new" and is an associated function, we generate fn body
270        // as a constructor and assume a "Self" return type.
271        if let Some(body) =
272            make_fn_body_as_new_function(make, ctx, &fn_name.text(), adt_info, target_edition)
273        {
274            ret_type = Some(make.ret_type(make.ty_path(make.ident_path("Self")).into()));
275            should_focus_return_type = false;
276            fn_body = body;
277        } else {
278            let expr_for_ret_ty = await_expr.map_or_else(|| call.clone().into(), |it| it.into());
279            (ret_type, should_focus_return_type) = make_return_type(
280                make,
281                ctx,
282                &expr_for_ret_ty,
283                target_module,
284                &mut necessary_generic_params,
285            );
286            let placeholder_expr = expr_fill_default(ctx.config);
287            fn_body = make.block_expr(vec![], Some(placeholder_expr));
288        };
289
290        let (generic_param_list, where_clause) =
291            fn_generic_params(make, ctx, necessary_generic_params, &target)?;
292
293        Some(Self {
294            target,
295            fn_name,
296            generic_param_list,
297            where_clause,
298            params,
299            fn_body,
300            ret_type,
301            should_focus_return_type,
302            visibility,
303            is_async,
304            target_edition,
305        })
306    }
307
308    fn from_method_call(
309        make: &SyntaxFactory,
310        ctx: &AssistContext<'_, '_>,
311        call: &ast::MethodCallExpr,
312        name: &ast::NameRef,
313        receiver_ty: Type<'_>,
314        target_module: Module,
315        target: GeneratedFunctionTarget,
316    ) -> Option<Self> {
317        let target_edition = target_module.krate(ctx.db()).edition(ctx.db());
318
319        let current_module = ctx.sema.scope(call.syntax())?.module();
320        let visibility = calculate_necessary_visibility(current_module, target_module, ctx);
321
322        let fn_name = make.name(name.ident_token()?.text());
323        let mut necessary_generic_params = FxHashSet::default();
324        necessary_generic_params.extend(receiver_ty.generic_params(ctx.db()));
325        let params = fn_args(
326            make,
327            ctx,
328            target_module,
329            ast::CallableExpr::MethodCall(call.clone()),
330            &mut necessary_generic_params,
331        )?;
332
333        let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
334        let is_async = await_expr.is_some();
335
336        let expr_for_ret_ty = await_expr.map_or_else(|| call.clone().into(), |it| it.into());
337        let (ret_type, should_focus_return_type) = make_return_type(
338            make,
339            ctx,
340            &expr_for_ret_ty,
341            target_module,
342            &mut necessary_generic_params,
343        );
344
345        let (generic_param_list, where_clause) =
346            fn_generic_params(make, ctx, necessary_generic_params, &target)?;
347
348        let placeholder_expr = expr_fill_default(ctx.config);
349        let fn_body = make.block_expr(vec![], Some(placeholder_expr));
350
351        Some(Self {
352            target,
353            fn_name,
354            generic_param_list,
355            where_clause,
356            params,
357            fn_body,
358            ret_type,
359            should_focus_return_type,
360            visibility,
361            is_async,
362            target_edition,
363        })
364    }
365
366    fn render(&self, make: &SyntaxFactory) -> ast::Fn {
367        let visibility = match self.visibility {
368            Visibility::None => None,
369            Visibility::Crate => Some(make.visibility_pub_crate()),
370            Visibility::Pub => Some(make.visibility_pub()),
371        };
372        let type_params =
373            self.generic_param_list.clone().filter(|list| list.generic_params().next().is_some());
374        make.fn_(
375            None,
376            visibility,
377            self.fn_name.clone(),
378            type_params,
379            self.where_clause.clone(),
380            self.params.clone(),
381            self.fn_body.clone(),
382            self.ret_type.clone(),
383            self.is_async,
384            false, // FIXME : const and unsafe are not handled yet.
385            false,
386            false,
387        )
388    }
389}
390
391/// Makes an optional return type along with whether the return type should be focused by the cursor.
392/// If we cannot infer what the return type should be, we create a placeholder type.
393///
394/// The rule for whether we focus a return type or not (and thus focus the function body),
395/// is rather simple:
396/// * If we could *not* infer what the return type should be, focus it (so the user can fill-in
397///   the correct return type).
398/// * If we could infer the return type, don't focus it (and thus focus the function body) so the
399///   user can change the `todo!` function body.
400fn make_return_type(
401    make: &SyntaxFactory,
402    ctx: &AssistContext<'_, '_>,
403    expr: &ast::Expr,
404    target_module: Module,
405    necessary_generic_params: &mut FxHashSet<hir::GenericParam>,
406) -> (Option<ast::RetType>, bool) {
407    let (ret_ty, should_focus_return_type) =
408        match ctx.sema.type_of_expr(expr).map(TypeInfo::original) {
409            Some(ty) if ty.is_unknown() => (Some(make.ty_placeholder()), true),
410            None => (Some(make.ty_placeholder()), true),
411            Some(ty) if ty.is_unit() => (None, false),
412            Some(ty) => {
413                necessary_generic_params.extend(ty.generic_params(ctx.db()));
414                let rendered = ty.display_source_code(ctx.db(), target_module.into(), true);
415                match rendered {
416                    Ok(rendered) => (Some(make.ty(&rendered)), false),
417                    Err(_) => (Some(make.ty_placeholder()), true),
418                }
419            }
420        };
421    let ret_type = ret_ty.map(|ty| make.ret_type(ty));
422    (ret_type, should_focus_return_type)
423}
424
425fn make_fn_body_as_new_function(
426    make: &SyntaxFactory,
427    ctx: &AssistContext<'_, '_>,
428    fn_name: &str,
429    adt_info: &Option<AdtInfo>,
430    edition: Edition,
431) -> Option<ast::BlockExpr> {
432    if fn_name != "new" {
433        return None;
434    };
435    let adt_info = adt_info.as_ref()?;
436
437    let path_self = make.ident_path("Self");
438    let placeholder_expr = expr_fill_default(ctx.config);
439    let tail_expr = if let Some(strukt) = adt_info.adt.as_struct() {
440        match strukt.kind(ctx.db()) {
441            StructKind::Record => {
442                let fields = strukt
443                    .fields(ctx.db())
444                    .iter()
445                    .map(|field| {
446                        make.record_expr_field(
447                            make.name_ref(&format!(
448                                "{}",
449                                field.name(ctx.db()).display(ctx.db(), edition)
450                            )),
451                            Some(placeholder_expr.clone()),
452                        )
453                    })
454                    .collect::<Vec<_>>();
455
456                make.record_expr(path_self, make.record_expr_field_list(fields)).into()
457            }
458            StructKind::Tuple => {
459                let args = strukt
460                    .fields(ctx.db())
461                    .iter()
462                    .map(|_| placeholder_expr.clone())
463                    .collect::<Vec<_>>();
464
465                make.expr_call(make.expr_path(path_self), make.arg_list(args)).into()
466            }
467            StructKind::Unit => make.expr_path(path_self),
468        }
469    } else {
470        placeholder_expr
471    };
472
473    let fn_body = make.block_expr(vec![], Some(tail_expr));
474    Some(fn_body)
475}
476
477fn get_fn_target_info(
478    ctx: &AssistContext<'_, '_>,
479    target_module: Option<Module>,
480    call: CallExpr,
481) -> Option<TargetInfo> {
482    let (target, file) = get_fn_target(ctx, target_module, call)?;
483    Some(TargetInfo::new(target_module, None, target, file))
484}
485
486fn get_fn_target(
487    ctx: &AssistContext<'_, '_>,
488    target_module: Option<Module>,
489    call: CallExpr,
490) -> Option<(GeneratedFunctionTarget, FileId)> {
491    let mut file = ctx.vfs_file_id();
492    let target = match target_module {
493        Some(target_module) => {
494            let (in_file, target) = next_space_for_fn_in_module(ctx.db(), target_module);
495            file = in_file;
496            target
497        }
498        None => next_space_for_fn_after_call_site(ast::CallableExpr::Call(call))?,
499    };
500    Some((target, file))
501}
502
503fn get_method_target(
504    ctx: &AssistContext<'_, '_>,
505    impl_: &Option<ast::Impl>,
506    adt: &Adt,
507) -> Option<GeneratedFunctionTarget> {
508    let target = match impl_ {
509        Some(impl_) => GeneratedFunctionTarget::InImpl(impl_.clone()),
510        None => GeneratedFunctionTarget::AfterItem(adt.source(ctx.sema.db)?.syntax().value.clone()),
511    };
512    Some(target)
513}
514
515fn assoc_fn_target_info(
516    ctx: &AssistContext<'_, '_>,
517    call: &CallExpr,
518    adt: hir::Adt,
519    fn_name: &str,
520) -> Option<TargetInfo> {
521    let current_module = ctx.sema.scope(call.syntax())?.module();
522    let module = adt.module(ctx.sema.db);
523    let target_module = if current_module == module { None } else { Some(module) };
524    if current_module.krate(ctx.db()) != module.krate(ctx.db()) {
525        return None;
526    }
527    let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?;
528    let target = get_method_target(ctx, &impl_, &adt)?;
529    let adt_info = AdtInfo::new(adt, impl_.is_some());
530    Some(TargetInfo::new(target_module, Some(adt_info), target, file))
531}
532
533#[derive(Clone)]
534enum GeneratedFunctionTarget {
535    AfterItem(SyntaxNode),
536    InEmptyItemList(SyntaxNode),
537    InImpl(ast::Impl),
538}
539
540impl GeneratedFunctionTarget {
541    fn syntax(&self) -> &SyntaxNode {
542        match self {
543            GeneratedFunctionTarget::AfterItem(it) => it,
544            GeneratedFunctionTarget::InEmptyItemList(it) => it,
545            GeneratedFunctionTarget::InImpl(it) => it.syntax(),
546        }
547    }
548
549    fn parent(&self) -> SyntaxNode {
550        match self {
551            GeneratedFunctionTarget::AfterItem(it) => it.parent().expect("item without parent"),
552            GeneratedFunctionTarget::InEmptyItemList(it) => it.clone(),
553            GeneratedFunctionTarget::InImpl(it) => it.syntax().clone(),
554        }
555    }
556
557    fn insert_impl_at(
558        &self,
559        edit: &mut SourceChangeBuilder,
560        file: FileId,
561        ctx: &AssistContext<'_, '_>,
562        function_builder: &FunctionBuilder,
563        adt: Adt,
564        cap: Option<SnippetCap>,
565    ) {
566        let editor = edit.make_editor(self.syntax());
567
568        match self {
569            GeneratedFunctionTarget::AfterItem(item) => {
570                let position = if item.parent().is_some() {
571                    Position::after(item)
572                } else {
573                    Position::first_child_of(item)
574                };
575
576                let indent = IndentLevel::from_node(item);
577                insert_rendered_impl(
578                    &editor,
579                    edit,
580                    ctx,
581                    function_builder,
582                    adt,
583                    position,
584                    indent,
585                    indent,
586                    cap,
587                );
588            }
589            GeneratedFunctionTarget::InEmptyItemList(item_list) => {
590                let insert_after =
591                    item_list.children_with_tokens().find_or_first(|child| child.kind() == T!['{']);
592                let position = match insert_after {
593                    Some(child) => Position::after(child),
594                    None => Position::first_child_of(item_list),
595                };
596
597                let indent = IndentLevel::from_node(item_list);
598                let leading_indent = indent + 1;
599                insert_rendered_impl(
600                    &editor,
601                    edit,
602                    ctx,
603                    function_builder,
604                    adt,
605                    position,
606                    indent,
607                    leading_indent,
608                    cap,
609                );
610            }
611            GeneratedFunctionTarget::InImpl(_) => {
612                unreachable!("can't insert an impl inside an impl")
613            }
614        }
615        edit.add_file_edits(file, editor);
616    }
617
618    fn insert_fn_at(
619        &self,
620        edit: &mut SourceChangeBuilder,
621        file: FileId,
622        function_builder: &FunctionBuilder,
623        cap: Option<SnippetCap>,
624    ) {
625        let editor = edit.make_editor(self.syntax());
626        let make = editor.make();
627
628        match self {
629            GeneratedFunctionTarget::AfterItem(item) => {
630                let position = if item.parent().is_some() {
631                    Position::after(item)
632                } else {
633                    Position::first_child_of(item)
634                };
635
636                let indent = IndentLevel::from_node(item);
637                insert_rendered_fn(
638                    &editor,
639                    edit,
640                    function_builder,
641                    position,
642                    indent,
643                    format!("\n\n{indent}"),
644                    None,
645                    cap,
646                );
647            }
648            GeneratedFunctionTarget::InEmptyItemList(item_list) => {
649                let insert_after =
650                    item_list.children_with_tokens().find_or_first(|child| child.kind() == T!['{']);
651                let position = match insert_after {
652                    Some(child) => Position::after(child),
653                    None => Position::first_child_of(item_list),
654                };
655
656                let indent = IndentLevel::from_node(item_list);
657                let leading_indent = indent + 1;
658                insert_rendered_fn(
659                    &editor,
660                    edit,
661                    function_builder,
662                    position,
663                    leading_indent,
664                    format!("\n{leading_indent}"),
665                    Some(format!("\n{indent}")),
666                    cap,
667                );
668            }
669            GeneratedFunctionTarget::InImpl(impl_) => {
670                let leading_indent = impl_.indent_level() + 1;
671
672                if let Some(item_list) = impl_.assoc_item_list() {
673                    let insert_after_item = item_list.assoc_items().last();
674                    let insert_after = item_list
675                        .assoc_items()
676                        .last()
677                        .map(|it| it.syntax().clone().into())
678                        .or_else(|| {
679                            item_list
680                                .syntax()
681                                .children_with_tokens()
682                                .find_or_first(|child| child.kind() == T!['{'])
683                        });
684                    let position = match insert_after {
685                        Some(child) => Position::after(child),
686                        None => Position::first_child_of(item_list.syntax()),
687                    };
688                    let indent = impl_.indent_level();
689                    let leading_ws = if insert_after_item.is_some() {
690                        format!("\n\n{leading_indent}")
691                    } else {
692                        format!("\n{leading_indent}")
693                    };
694                    let trailing_ws = insert_after_item.is_none().then(|| format!("\n{indent}"));
695                    insert_rendered_fn(
696                        &editor,
697                        edit,
698                        function_builder,
699                        position,
700                        leading_indent,
701                        leading_ws,
702                        trailing_ws,
703                        cap,
704                    );
705                } else {
706                    let func = function_builder.render(make).indent(leading_indent);
707                    let item_list = make.assoc_item_list([func.into()]);
708                    if let Some(fn_) = item_list.syntax().descendants().find_map(ast::Fn::cast) {
709                        add_generated_fn_annotation(&editor, edit, function_builder, &fn_, cap);
710                    }
711                    editor.insert(Position::last_child_of(impl_.syntax()), item_list.syntax());
712                }
713            }
714        }
715        edit.add_file_edits(file, editor);
716    }
717}
718
719fn insert_rendered_impl(
720    editor: &SyntaxEditor,
721    edit: &mut SourceChangeBuilder,
722    ctx: &AssistContext<'_, '_>,
723    function_builder: &FunctionBuilder,
724    adt: Adt,
725    position: Position,
726    impl_indent: IndentLevel,
727    leading_ws_indent: IndentLevel,
728    cap: Option<SnippetCap>,
729) {
730    let make = editor.make();
731    let leading_ws = make.whitespace(&format!("\n{leading_ws_indent}"));
732    let name = make.ty_path(make.ident_path(&format!(
733        "{}",
734        adt.name(ctx.db()).display(ctx.db(), function_builder.target_edition)
735    )));
736
737    // FIXME: adt may have generic params.
738    let fn_ = function_builder.render(make).indent(IndentLevel(1));
739    let impl_ =
740        make.impl_(None, None, None, name.into(), None, Some(make.assoc_item_list([fn_.into()])));
741    let impl_ = impl_.indent(impl_indent);
742    if let Some(fn_) = impl_.syntax().descendants().find_map(ast::Fn::cast) {
743        add_generated_fn_annotation(editor, edit, function_builder, &fn_, cap);
744    }
745
746    editor.insert_all(position, vec![leading_ws.into(), impl_.syntax().clone().into()]);
747}
748
749fn insert_rendered_fn(
750    editor: &SyntaxEditor,
751    edit: &mut SourceChangeBuilder,
752    function_builder: &FunctionBuilder,
753    position: Position,
754    indent: IndentLevel,
755    leading_ws: String,
756    trailing_ws: Option<String>,
757    cap: Option<SnippetCap>,
758) {
759    let make = editor.make();
760    let leading_ws = make.whitespace(&leading_ws);
761    let func = function_builder.render(make).indent(indent);
762    add_generated_fn_annotation(editor, edit, function_builder, &func, cap);
763
764    let mut elements = vec![leading_ws.into(), func.syntax().clone().into()];
765    if let Some(trailing_ws) = trailing_ws {
766        elements.push(make.whitespace(&trailing_ws).into());
767    }
768    editor.insert_all(position, elements);
769}
770
771fn add_generated_fn_annotation(
772    editor: &SyntaxEditor,
773    edit: &mut SourceChangeBuilder,
774    function_builder: &FunctionBuilder,
775    fn_: &ast::Fn,
776    cap: Option<SnippetCap>,
777) {
778    let Some(cap) = cap else { return };
779
780    let annotation = edit.make_placeholder_snippet(cap);
781    if function_builder.should_focus_return_type
782        && let Some(ret_type) = fn_.ret_type()
783    {
784        editor.add_annotation(ret_type.syntax(), annotation);
785    } else if let Some(tail_expr) = fn_.body().and_then(|body| body.tail_expr()) {
786        editor.add_annotation(tail_expr.syntax(), annotation);
787    }
788}
789
790struct AdtInfo {
791    adt: hir::Adt,
792    impl_exists: bool,
793}
794
795impl AdtInfo {
796    fn new(adt: Adt, impl_exists: bool) -> Self {
797        Self { adt, impl_exists }
798    }
799}
800
801/// Computes parameter list for the generated function.
802fn fn_args(
803    make: &SyntaxFactory,
804    ctx: &AssistContext<'_, '_>,
805    target_module: Module,
806    call: ast::CallableExpr,
807    necessary_generic_params: &mut FxHashSet<hir::GenericParam>,
808) -> Option<ast::ParamList> {
809    let mut arg_names = Vec::new();
810    let mut arg_types = Vec::new();
811    for arg in call.arg_list()?.args() {
812        arg_names.push(fn_arg_name(&ctx.sema, &arg));
813        arg_types.push(fn_arg_type(ctx, target_module, &arg, necessary_generic_params));
814    }
815    deduplicate_arg_names(&mut arg_names);
816    let params = arg_names
817        .into_iter()
818        .zip(arg_types)
819        .map(|(name, ty)| make.param(make.simple_ident_pat(make.name(&name)).into(), make.ty(&ty)));
820
821    Some(make.param_list(
822        match call {
823            ast::CallableExpr::Call(_) => None,
824            ast::CallableExpr::MethodCall(_) => Some(make.self_param()),
825        },
826        params,
827    ))
828}
829
830/// Gets parameter bounds and where predicates in scope and filters out irrelevant ones. Returns
831/// `None` when it fails to get scope information.
832///
833/// See comment on `filter_unnecessary_bounds()` for what bounds we consider relevant.
834///
835/// NOTE: Generic parameters returned from this function may cause name clash at `target`. We don't
836/// currently do anything about it because it's actually easy to resolve it after the assist: just
837/// use the Rename functionality.
838fn fn_generic_params(
839    make: &SyntaxFactory,
840    ctx: &AssistContext<'_, '_>,
841    necessary_params: FxHashSet<hir::GenericParam>,
842    target: &GeneratedFunctionTarget,
843) -> Option<(Option<ast::GenericParamList>, Option<ast::WhereClause>)> {
844    if necessary_params.is_empty() {
845        // Not really needed but fast path.
846        return Some((None, None));
847    }
848
849    // 1. Get generic parameters (with bounds) and where predicates in scope.
850    let (generic_params, where_preds) = params_and_where_preds_in_scope(ctx);
851
852    // 2. Extract type parameters included in each bound.
853    let mut generic_params = generic_params
854        .into_iter()
855        .filter_map(|it| compute_contained_params_in_generic_param(ctx, it))
856        .collect();
857    let mut where_preds = where_preds
858        .into_iter()
859        .filter_map(|it| compute_contained_params_in_where_pred(ctx, it))
860        .collect();
861
862    // 3. Filter out unnecessary bounds.
863    filter_unnecessary_bounds(&mut generic_params, &mut where_preds, necessary_params);
864    filter_bounds_in_scope(&mut generic_params, &mut where_preds, ctx, target);
865
866    let source_scope = generic_params.first().and_then(|param| ctx.sema.scope(param.node.syntax()));
867    let target_scope = source_scope.as_ref().and_then(|_| ctx.sema.scope(&target.parent()));
868
869    let generic_params: Vec<ast::GenericParam> =
870        generic_params.into_iter().map(|it| it.node).collect();
871    let where_preds: Vec<ast::WherePred> = where_preds.into_iter().map(|it| it.node).collect();
872
873    let (generic_params, where_preds) = if let Some(source_scope) = source_scope
874        && let Some(target_scope) = target_scope
875        && source_scope.module() != target_scope.module()
876    {
877        // 4. Rewrite paths
878        let transform = PathTransform::generic_transformation(&target_scope, &source_scope);
879        let generic_params = generic_params.iter().map(|it| it.syntax());
880        let where_preds = where_preds.iter().map(|it| it.syntax());
881        transform
882            .apply_all(generic_params.chain(where_preds))
883            .into_iter()
884            .filter_map(|it| {
885                if let Some(it) = ast::GenericParam::cast(it.clone()) {
886                    Some(either::Either::Left(it))
887                } else {
888                    ast::WherePred::cast(it).map(either::Either::Right)
889                }
890            })
891            .partition_map(|it| it)
892    } else {
893        (generic_params, where_preds)
894    };
895
896    let generic_param_list = make.generic_param_list(generic_params);
897    let where_clause =
898        if where_preds.is_empty() { None } else { Some(make.where_clause(where_preds)) };
899
900    Some((Some(generic_param_list), where_clause))
901}
902
903fn params_and_where_preds_in_scope(
904    ctx: &AssistContext<'_, '_>,
905) -> (Vec<ast::GenericParam>, Vec<ast::WherePred>) {
906    let Some(body) = containing_body(ctx) else {
907        return Default::default();
908    };
909
910    let mut generic_params = Vec::new();
911    let mut where_clauses = Vec::new();
912
913    // There are two items where generic parameters currently in scope may be declared: the item
914    // the cursor is at, and its parent (if any).
915    //
916    // We handle parent first so that their generic parameters appear first in the generic
917    // parameter list of the function we're generating.
918    let db = ctx.db();
919    if let Some(parent) = body.as_assoc_item(db).map(|it| it.container(db)) {
920        match parent {
921            hir::AssocItemContainer::Impl(it) => {
922                let (params, clauses) = get_bounds_in_scope(ctx, it);
923                generic_params.extend(params);
924                where_clauses.extend(clauses);
925            }
926            hir::AssocItemContainer::Trait(it) => {
927                let (params, clauses) = get_bounds_in_scope(ctx, it);
928                generic_params.extend(params);
929                where_clauses.extend(clauses);
930            }
931        }
932    }
933
934    // Other defs with body may inherit generic parameters from its parent, but never have their
935    // own generic parameters.
936    if let hir::DefWithBody::Function(it) = body {
937        let (params, clauses) = get_bounds_in_scope(ctx, it);
938        generic_params.extend(params);
939        where_clauses.extend(clauses);
940    }
941
942    (generic_params, where_clauses)
943}
944
945fn containing_body(ctx: &AssistContext<'_, '_>) -> Option<hir::DefWithBody> {
946    let item: ast::Item = ctx.find_node_at_offset()?;
947    let def = match item {
948        ast::Item::Fn(it) => ctx.sema.to_def(&it)?.into(),
949        ast::Item::Const(it) => ctx.sema.to_def(&it)?.into(),
950        ast::Item::Static(it) => ctx.sema.to_def(&it)?.into(),
951        _ => return None,
952    };
953    Some(def)
954}
955
956fn get_bounds_in_scope<D>(
957    ctx: &AssistContext<'_, '_>,
958    def: D,
959) -> (impl Iterator<Item = ast::GenericParam>, impl Iterator<Item = ast::WherePred>)
960where
961    D: HasSource,
962    D::Ast: HasGenericParams,
963{
964    // This function should be only called with `Impl`, `Trait`, or `Function`, for which it's
965    // infallible to get source ast.
966    let node = ctx.sema.source(def).expect("definition's source couldn't be found").value;
967    let generic_params = node.generic_param_list().into_iter().flat_map(|it| it.generic_params());
968    let where_clauses = node.where_clause().into_iter().flat_map(|it| it.predicates());
969    (generic_params, where_clauses)
970}
971
972#[derive(Debug)]
973struct ParamBoundWithParams {
974    node: ast::GenericParam,
975    /// Generic parameter `node` introduces.
976    ///
977    /// ```text
978    /// impl<T> S<T> {
979    ///     fn f<U: Trait<T>>() {}
980    ///          ^ this
981    /// }
982    /// ```
983    ///
984    /// `U` in this example.
985    self_ty_param: hir::GenericParam,
986    /// Generic parameters contained in the trait reference of this bound.
987    ///
988    /// ```text
989    /// impl<T> S<T> {
990    ///     fn f<U: Trait<T>>() {}
991    ///             ^^^^^^^^ params in this part
992    /// }
993    /// ```
994    ///
995    /// `T` in this example.
996    other_params: FxHashSet<hir::GenericParam>,
997}
998
999#[derive(Debug)]
1000struct WherePredWithParams {
1001    node: ast::WherePred,
1002    /// Generic parameters contained in the "self type" of this where predicate.
1003    ///
1004    /// ```text
1005    /// Struct<T, U>: Trait<T, Assoc = V>,
1006    /// ^^^^^^^^^^^^ params in this part
1007    /// ```
1008    ///
1009    /// `T` and `U` in this example.
1010    self_ty_params: FxHashSet<hir::GenericParam>,
1011    /// Generic parameters contained in the trait reference of this where predicate.
1012    ///
1013    /// ```text
1014    /// Struct<T, U>: Trait<T, Assoc = V>,
1015    ///               ^^^^^^^^^^^^^^^^^^^ params in this part
1016    /// ```
1017    ///
1018    /// `T` and `V` in this example.
1019    other_params: FxHashSet<hir::GenericParam>,
1020}
1021
1022fn compute_contained_params_in_generic_param(
1023    ctx: &AssistContext<'_, '_>,
1024    node: ast::GenericParam,
1025) -> Option<ParamBoundWithParams> {
1026    match &node {
1027        ast::GenericParam::TypeParam(ty) => {
1028            let self_ty_param = ctx.sema.to_def(ty)?.into();
1029
1030            let other_params = ty
1031                .type_bound_list()
1032                .into_iter()
1033                .flat_map(|it| it.bounds())
1034                .flat_map(|bound| bound.syntax().descendants())
1035                .filter_map(|node| filter_generic_params(ctx, node))
1036                .collect();
1037
1038            Some(ParamBoundWithParams { node, self_ty_param, other_params })
1039        }
1040        ast::GenericParam::ConstParam(ct) => {
1041            let self_ty_param = ctx.sema.to_def(ct)?.into();
1042            Some(ParamBoundWithParams { node, self_ty_param, other_params: FxHashSet::default() })
1043        }
1044        ast::GenericParam::LifetimeParam(_) => {
1045            // FIXME: It might be a good idea to handle lifetime parameters too.
1046            None
1047        }
1048    }
1049}
1050
1051fn compute_contained_params_in_where_pred(
1052    ctx: &AssistContext<'_, '_>,
1053    node: ast::WherePred,
1054) -> Option<WherePredWithParams> {
1055    let self_ty = node.ty()?;
1056    let bound_list = node.type_bound_list()?;
1057
1058    let self_ty_params = self_ty
1059        .syntax()
1060        .descendants()
1061        .filter_map(|node| filter_generic_params(ctx, node))
1062        .collect();
1063
1064    let other_params = bound_list
1065        .bounds()
1066        .flat_map(|bound| bound.syntax().descendants())
1067        .filter_map(|node| filter_generic_params(ctx, node))
1068        .collect();
1069
1070    Some(WherePredWithParams { node, self_ty_params, other_params })
1071}
1072
1073fn filter_generic_params(
1074    ctx: &AssistContext<'_, '_>,
1075    node: SyntaxNode,
1076) -> Option<hir::GenericParam> {
1077    let path = ast::Path::cast(node)?;
1078    match ctx.sema.resolve_path(&path)? {
1079        PathResolution::TypeParam(it) => Some(it.into()),
1080        PathResolution::ConstParam(it) => Some(it.into()),
1081        _ => None,
1082    }
1083}
1084
1085/// Filters out irrelevant bounds from `generic_params` and `where_preds`.
1086///
1087/// Say we have a trait bound `Struct<T>: Trait<U>`. Given `necessary_params`, when is it relevant
1088/// and when not? Some observations:
1089/// - When `necessary_params` contains `T`, it's likely that we want this bound, but now we have
1090///   an extra param to consider: `U`.
1091/// - On the other hand, when `necessary_params` contains `U` (but not `T`), then it's unlikely
1092///   that we want this bound because it doesn't really constrain `U`.
1093///
1094/// (FIXME?: The latter clause might be overstating. We may want to include the bound if the self
1095/// type does *not* include generic params at all - like `Option<i32>: From<U>`)
1096///
1097/// Can we make this a bit more formal? Let's define "dependency" between generic parameters and
1098/// trait bounds:
1099/// - A generic parameter `T` depends on a trait bound if `T` appears in the self type (i.e. left
1100///   part) of the bound.
1101/// - A trait bound depends on a generic parameter `T` if `T` appears in the bound.
1102///
1103/// Using the notion, what we want is all the bounds that params in `necessary_params`
1104/// *transitively* depend on!
1105///
1106/// Now it's not hard to solve: we build a dependency graph and compute all reachable nodes from
1107/// nodes that represent params in `necessary_params` by usual and boring DFS.
1108///
1109/// The time complexity is O(|generic_params| + |where_preds| + |necessary_params|).
1110fn filter_unnecessary_bounds(
1111    generic_params: &mut Vec<ParamBoundWithParams>,
1112    where_preds: &mut Vec<WherePredWithParams>,
1113    necessary_params: FxHashSet<hir::GenericParam>,
1114) {
1115    // All `self_ty_param` should be unique as they were collected from `ast::GenericParamList`s.
1116    let param_map: FxHashMap<hir::GenericParam, usize> =
1117        generic_params.iter().map(|it| it.self_ty_param).zip(0..).collect();
1118    let param_count = param_map.len();
1119    let generic_params_upper_bound = param_count + generic_params.len();
1120    let node_count = generic_params_upper_bound + where_preds.len();
1121
1122    // | node index range                        | what the node represents |
1123    // |-----------------------------------------|--------------------------|
1124    // | 0..param_count                          | generic parameter        |
1125    // | param_count..generic_params_upper_bound | `ast::GenericParam`      |
1126    // | generic_params_upper_bound..node_count  | `ast::WherePred`         |
1127    let mut graph = Graph::new(node_count);
1128    for (pred, pred_idx) in generic_params.iter().zip(param_count..) {
1129        let param_idx = param_map[&pred.self_ty_param];
1130        graph.add_edge(param_idx, pred_idx);
1131        graph.add_edge(pred_idx, param_idx);
1132
1133        for param in &pred.other_params {
1134            let param_idx = param_map[param];
1135            graph.add_edge(pred_idx, param_idx);
1136        }
1137    }
1138    for (pred, pred_idx) in where_preds.iter().zip(generic_params_upper_bound..) {
1139        for param in &pred.self_ty_params {
1140            let param_idx = param_map[param];
1141            graph.add_edge(param_idx, pred_idx);
1142            graph.add_edge(pred_idx, param_idx);
1143        }
1144        for param in &pred.other_params {
1145            let param_idx = param_map[param];
1146            graph.add_edge(pred_idx, param_idx);
1147        }
1148    }
1149
1150    let starting_nodes = necessary_params.iter().flat_map(|param| param_map.get(param).copied());
1151    let reachable = graph.compute_reachable_nodes(starting_nodes);
1152
1153    // Not pretty, but effective. If only there were `Vec::retain_index()`...
1154    let mut idx = param_count;
1155    generic_params.retain(|_| {
1156        idx += 1;
1157        reachable[idx - 1]
1158    });
1159    stdx::always!(idx == generic_params_upper_bound, "inconsistent index");
1160    where_preds.retain(|_| {
1161        idx += 1;
1162        reachable[idx - 1]
1163    });
1164}
1165
1166/// Filters out bounds from impl if we're generating the function into the same impl we're
1167/// generating from.
1168fn filter_bounds_in_scope(
1169    generic_params: &mut Vec<ParamBoundWithParams>,
1170    where_preds: &mut Vec<WherePredWithParams>,
1171    ctx: &AssistContext<'_, '_>,
1172    target: &GeneratedFunctionTarget,
1173) -> Option<()> {
1174    let target_impl = target.parent().ancestors().find_map(ast::Impl::cast)?;
1175    let target_impl = ctx.sema.to_def(&target_impl)?;
1176    // It's sufficient to test only the first element of `generic_params` because of the order of
1177    // insertion (see `params_and_where_preds_in_scope()`).
1178    let def = generic_params.first()?.self_ty_param.parent();
1179    if def != hir::GenericDef::Impl(target_impl) {
1180        return None;
1181    }
1182
1183    // Now we know every element that belongs to an impl would be in scope at `target`, we can
1184    // filter them out just by looking at their parent.
1185    generic_params.retain(|it| !matches!(it.self_ty_param.parent(), hir::GenericDef::Impl(_)));
1186    where_preds.retain(|it| {
1187        it.node.syntax().parent().and_then(|it| it.parent()).and_then(ast::Impl::cast).is_none()
1188    });
1189
1190    Some(())
1191}
1192
1193/// Makes duplicate argument names unique by appending incrementing numbers.
1194///
1195/// ```ignore
1196/// let mut names: Vec<String> =
1197///     vec!["foo".into(), "foo".into(), "bar".into(), "baz".into(), "bar".into()];
1198/// deduplicate_arg_names(&mut names);
1199/// let expected: Vec<String> =
1200///     vec!["foo_1".into(), "foo_2".into(), "bar_1".into(), "baz".into(), "bar_2".into()];
1201/// assert_eq!(names, expected);
1202/// ```
1203fn deduplicate_arg_names(arg_names: &mut [String]) {
1204    let mut arg_name_counts = FxHashMap::default();
1205    for name in arg_names.iter() {
1206        *arg_name_counts.entry(name).or_insert(0) += 1;
1207    }
1208    let duplicate_arg_names: FxHashSet<String> = arg_name_counts
1209        .into_iter()
1210        .filter(|(_, count)| *count >= 2)
1211        .map(|(name, _)| name.clone())
1212        .collect();
1213
1214    let mut counter_per_name = FxHashMap::default();
1215    for arg_name in arg_names.iter_mut() {
1216        if duplicate_arg_names.contains(arg_name) {
1217            let counter = counter_per_name.entry(arg_name.clone()).or_insert(1);
1218            arg_name.push('_');
1219            arg_name.push_str(&counter.to_string());
1220            *counter += 1;
1221        }
1222    }
1223}
1224
1225fn fn_arg_name(sema: &Semantics<'_, RootDatabase>, arg_expr: &ast::Expr) -> String {
1226    let name = (|| match arg_expr {
1227        ast::Expr::CastExpr(cast_expr) => Some(fn_arg_name(sema, &cast_expr.expr()?)),
1228        expr => {
1229            let name_ref = expr
1230                .syntax()
1231                .descendants()
1232                .filter_map(ast::NameRef::cast)
1233                .filter(|name| name.ident_token().is_some())
1234                .last()?;
1235            if let Some(NameRefClass::Definition(Definition::Const(_) | Definition::Static(_), _)) =
1236                NameRefClass::classify(sema, &name_ref)
1237            {
1238                return Some(name_ref.to_string().to_lowercase());
1239            };
1240            Some(to_lower_snake_case(&name_ref.to_string()))
1241        }
1242    })();
1243    match name {
1244        Some(mut name) if name.starts_with(|c: char| c.is_ascii_digit()) => {
1245            name.insert_str(0, "arg");
1246            name
1247        }
1248        Some(name) => name,
1249        None => "arg".to_owned(),
1250    }
1251}
1252
1253fn fn_arg_type(
1254    ctx: &AssistContext<'_, '_>,
1255    target_module: Module,
1256    fn_arg: &ast::Expr,
1257    generic_params: &mut FxHashSet<hir::GenericParam>,
1258) -> String {
1259    fn maybe_displayed_type(
1260        ctx: &AssistContext<'_, '_>,
1261        target_module: Module,
1262        fn_arg: &ast::Expr,
1263        generic_params: &mut FxHashSet<hir::GenericParam>,
1264    ) -> Option<String> {
1265        let ty = ctx.sema.type_of_expr(fn_arg)?.adjusted();
1266        if ty.is_unknown() {
1267            return None;
1268        }
1269
1270        generic_params.extend(ty.generic_params(ctx.db()));
1271
1272        if ty.is_reference() || ty.is_mutable_reference() {
1273            let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(fn_arg.syntax())?.krate());
1274            convert_reference_type(ty.strip_references(), ctx.db(), famous_defs)
1275                .map(|conversion| conversion.convert_type(ctx.db(), target_module).to_string())
1276                .or_else(|| ty.display_source_code(ctx.db(), target_module.into(), true).ok())
1277        } else {
1278            ty.display_source_code(ctx.db(), target_module.into(), true).ok()
1279        }
1280    }
1281
1282    maybe_displayed_type(ctx, target_module, fn_arg, generic_params)
1283        .unwrap_or_else(|| String::from("_"))
1284}
1285
1286/// Returns the position inside the current mod or file
1287/// directly after the current block
1288/// We want to write the generated function directly after
1289/// fns, impls or macro calls, but inside mods
1290fn next_space_for_fn_after_call_site(expr: ast::CallableExpr) -> Option<GeneratedFunctionTarget> {
1291    let mut ancestors = expr.syntax().ancestors().peekable();
1292    let mut last_ancestor: Option<SyntaxNode> = None;
1293    while let Some(next_ancestor) = ancestors.next() {
1294        match next_ancestor.kind() {
1295            SyntaxKind::SOURCE_FILE => {
1296                break;
1297            }
1298            SyntaxKind::ITEM_LIST
1299                if ancestors.peek().map(|a| a.kind()) == Some(SyntaxKind::MODULE) =>
1300            {
1301                break;
1302            }
1303            _ => {}
1304        }
1305        last_ancestor = Some(next_ancestor);
1306    }
1307    last_ancestor.map(GeneratedFunctionTarget::AfterItem)
1308}
1309
1310fn next_space_for_fn_in_module(
1311    db: &dyn hir::db::HirDatabase,
1312    target_module: hir::Module,
1313) -> (FileId, GeneratedFunctionTarget) {
1314    let module_source = target_module.definition_source(db);
1315    let file = module_source.file_id.original_file(db);
1316    let assist_item = match &module_source.value {
1317        hir::ModuleSource::SourceFile(it) => match it.items().last() {
1318            Some(last_item) => GeneratedFunctionTarget::AfterItem(last_item.syntax().clone()),
1319            None => GeneratedFunctionTarget::AfterItem(it.syntax().clone()),
1320        },
1321        hir::ModuleSource::Module(it) => match it.item_list().and_then(|it| it.items().last()) {
1322            Some(last_item) => GeneratedFunctionTarget::AfterItem(last_item.syntax().clone()),
1323            None => {
1324                let item_list =
1325                    it.item_list().expect("module definition source should have an item list");
1326                GeneratedFunctionTarget::InEmptyItemList(item_list.syntax().clone())
1327            }
1328        },
1329        hir::ModuleSource::BlockExpr(it) => {
1330            if let Some(last_item) =
1331                it.statements().take_while(|stmt| matches!(stmt, ast::Stmt::Item(_))).last()
1332            {
1333                GeneratedFunctionTarget::AfterItem(last_item.syntax().clone())
1334            } else {
1335                GeneratedFunctionTarget::InEmptyItemList(it.syntax().clone())
1336            }
1337        }
1338    };
1339
1340    (file.file_id(db), assist_item)
1341}
1342
1343#[derive(Clone, Copy)]
1344enum Visibility {
1345    None,
1346    Crate,
1347    Pub,
1348}
1349
1350fn calculate_necessary_visibility(
1351    current_module: Module,
1352    target_module: Module,
1353    ctx: &AssistContext<'_, '_>,
1354) -> Visibility {
1355    let db = ctx.db();
1356    let current_module = current_module.nearest_non_block_module(db);
1357    let target_module = target_module.nearest_non_block_module(db);
1358
1359    if target_module.krate(ctx.db()) != current_module.krate(ctx.db()) {
1360        Visibility::Pub
1361    } else if current_module.path_to_root(db).contains(&target_module) {
1362        Visibility::None
1363    } else {
1364        Visibility::Crate
1365    }
1366}
1367
1368// This is never intended to be used as a generic graph structure. If there's ever another need of
1369// graph algorithm, consider adding a library for that (and replace the following).
1370/// Minimally implemented directed graph structure represented by adjacency list.
1371struct Graph {
1372    edges: Vec<Vec<usize>>,
1373}
1374
1375impl Graph {
1376    fn new(node_count: usize) -> Self {
1377        Self { edges: vec![Vec::new(); node_count] }
1378    }
1379
1380    fn add_edge(&mut self, from: usize, to: usize) {
1381        self.edges[from].push(to);
1382    }
1383
1384    fn edges_for(&self, node_idx: usize) -> &[usize] {
1385        &self.edges[node_idx]
1386    }
1387
1388    fn len(&self) -> usize {
1389        self.edges.len()
1390    }
1391
1392    fn compute_reachable_nodes(
1393        &self,
1394        starting_nodes: impl IntoIterator<Item = usize>,
1395    ) -> Vec<bool> {
1396        let mut visitor = Visitor::new(self);
1397        for idx in starting_nodes {
1398            visitor.mark_reachable(idx);
1399        }
1400        visitor.visited
1401    }
1402}
1403
1404struct Visitor<'g> {
1405    graph: &'g Graph,
1406    visited: Vec<bool>,
1407    // Stack is held in this struct so we can reuse its buffer.
1408    stack: Vec<usize>,
1409}
1410
1411impl<'g> Visitor<'g> {
1412    fn new(graph: &'g Graph) -> Self {
1413        let visited = vec![false; graph.len()];
1414        Self { graph, visited, stack: Vec::new() }
1415    }
1416
1417    fn mark_reachable(&mut self, start_idx: usize) {
1418        // non-recursive DFS
1419        stdx::always!(self.stack.is_empty());
1420
1421        self.stack.push(start_idx);
1422        while let Some(idx) = self.stack.pop() {
1423            if !self.visited[idx] {
1424                self.visited[idx] = true;
1425                for &neighbor in self.graph.edges_for(idx) {
1426                    if !self.visited[neighbor] {
1427                        self.stack.push(neighbor);
1428                    }
1429                }
1430            }
1431        }
1432    }
1433}
1434
1435#[cfg(test)]
1436mod tests {
1437    use crate::tests::{check_assist, check_assist_not_applicable};
1438
1439    use super::*;
1440
1441    #[test]
1442    fn add_function_with_no_args() {
1443        check_assist(
1444            generate_function,
1445            r"
1446fn foo() {
1447    bar$0();
1448}
1449",
1450            r"
1451fn foo() {
1452    bar();
1453}
1454
1455fn bar() ${0:-> _} {
1456    todo!()
1457}
1458",
1459        )
1460    }
1461
1462    #[test]
1463    fn add_function_from_method() {
1464        // This ensures that the function is correctly generated
1465        // in the next outer mod or file
1466        check_assist(
1467            generate_function,
1468            r"
1469impl Foo {
1470    fn foo() {
1471        bar$0();
1472    }
1473}
1474",
1475            r"
1476impl Foo {
1477    fn foo() {
1478        bar();
1479    }
1480}
1481
1482fn bar() ${0:-> _} {
1483    todo!()
1484}
1485",
1486        )
1487    }
1488
1489    #[test]
1490    fn add_function_directly_after_current_block() {
1491        // The new fn should not be created at the end of the file or module
1492        check_assist(
1493            generate_function,
1494            r"
1495fn foo1() {
1496    bar$0();
1497}
1498
1499fn foo2() {}
1500",
1501            r"
1502fn foo1() {
1503    bar();
1504}
1505
1506fn bar() ${0:-> _} {
1507    todo!()
1508}
1509
1510fn foo2() {}
1511",
1512        )
1513    }
1514
1515    #[test]
1516    fn add_function_with_no_args_in_same_module() {
1517        check_assist(
1518            generate_function,
1519            r"
1520mod baz {
1521    fn foo() {
1522        bar$0();
1523    }
1524}
1525",
1526            r"
1527mod baz {
1528    fn foo() {
1529        bar();
1530    }
1531
1532    fn bar() ${0:-> _} {
1533        todo!()
1534    }
1535}
1536",
1537        )
1538    }
1539
1540    #[test]
1541    fn add_function_with_upper_camel_case_arg() {
1542        check_assist(
1543            generate_function,
1544            r"
1545struct BazBaz;
1546fn foo() {
1547    bar$0(BazBaz);
1548}
1549",
1550            r"
1551struct BazBaz;
1552fn foo() {
1553    bar(BazBaz);
1554}
1555
1556fn bar(baz_baz: BazBaz) ${0:-> _} {
1557    todo!()
1558}
1559",
1560        );
1561    }
1562
1563    #[test]
1564    fn add_function_with_upper_camel_case_arg_as_cast() {
1565        check_assist(
1566            generate_function,
1567            r"
1568struct BazBaz;
1569fn foo() {
1570    bar$0(&BazBaz as *const BazBaz);
1571}
1572",
1573            r"
1574struct BazBaz;
1575fn foo() {
1576    bar(&BazBaz as *const BazBaz);
1577}
1578
1579fn bar(baz_baz: *const BazBaz) ${0:-> _} {
1580    todo!()
1581}
1582",
1583        );
1584    }
1585
1586    #[test]
1587    fn add_function_with_function_call_arg() {
1588        check_assist(
1589            generate_function,
1590            r"
1591struct Baz;
1592fn baz() -> Baz { todo!() }
1593fn foo() {
1594    bar$0(baz());
1595}
1596",
1597            r"
1598struct Baz;
1599fn baz() -> Baz { todo!() }
1600fn foo() {
1601    bar(baz());
1602}
1603
1604fn bar(baz: Baz) ${0:-> _} {
1605    todo!()
1606}
1607",
1608        );
1609    }
1610
1611    #[test]
1612    fn add_function_with_method_call_arg() {
1613        check_assist(
1614            generate_function,
1615            r"
1616struct Baz;
1617impl Baz {
1618    fn foo(&self) -> Baz {
1619        ba$0r(self.baz())
1620    }
1621    fn baz(&self) -> Baz {
1622        Baz
1623    }
1624}
1625",
1626            r"
1627struct Baz;
1628impl Baz {
1629    fn foo(&self) -> Baz {
1630        bar(self.baz())
1631    }
1632    fn baz(&self) -> Baz {
1633        Baz
1634    }
1635}
1636
1637fn bar(baz: Baz) -> Baz {
1638    ${0:todo!()}
1639}
1640",
1641        )
1642    }
1643
1644    #[test]
1645    fn add_function_with_string_literal_arg() {
1646        check_assist(
1647            generate_function,
1648            r#"
1649fn foo() {
1650    $0bar("bar")
1651}
1652"#,
1653            r#"
1654fn foo() {
1655    bar("bar")
1656}
1657
1658fn bar(arg: &'static str) {
1659    ${0:todo!()}
1660}
1661"#,
1662        )
1663    }
1664
1665    #[test]
1666    fn add_function_with_char_literal_arg() {
1667        check_assist(
1668            generate_function,
1669            r#"
1670fn foo() {
1671    $0bar('x')
1672}
1673"#,
1674            r#"
1675fn foo() {
1676    bar('x')
1677}
1678
1679fn bar(arg: char) {
1680    ${0:todo!()}
1681}
1682"#,
1683        )
1684    }
1685
1686    #[test]
1687    fn add_function_with_int_literal_arg() {
1688        check_assist(
1689            generate_function,
1690            r"
1691fn foo() {
1692    $0bar(42)
1693}
1694",
1695            r"
1696fn foo() {
1697    bar(42)
1698}
1699
1700fn bar(arg: i32) {
1701    ${0:todo!()}
1702}
1703",
1704        )
1705    }
1706
1707    #[test]
1708    fn add_function_with_cast_int_literal_arg() {
1709        check_assist(
1710            generate_function,
1711            r"
1712fn foo() {
1713    $0bar(42 as u8)
1714}
1715",
1716            r"
1717fn foo() {
1718    bar(42 as u8)
1719}
1720
1721fn bar(arg: u8) {
1722    ${0:todo!()}
1723}
1724",
1725        )
1726    }
1727
1728    #[test]
1729    fn name_of_cast_variable_is_used() {
1730        // Ensures that the name of the cast type isn't used
1731        // in the generated function signature.
1732        check_assist(
1733            generate_function,
1734            r"
1735fn foo() {
1736    let x = 42;
1737    bar$0(x as u8)
1738}
1739",
1740            r"
1741fn foo() {
1742    let x = 42;
1743    bar(x as u8)
1744}
1745
1746fn bar(x: u8) {
1747    ${0:todo!()}
1748}
1749",
1750        )
1751    }
1752
1753    #[test]
1754    fn add_function_with_variable_arg() {
1755        check_assist(
1756            generate_function,
1757            r"
1758fn foo() {
1759    let worble = ();
1760    $0bar(worble)
1761}
1762",
1763            r"
1764fn foo() {
1765    let worble = ();
1766    bar(worble)
1767}
1768
1769fn bar(worble: ()) {
1770    ${0:todo!()}
1771}
1772",
1773        )
1774    }
1775
1776    #[test]
1777    fn add_function_with_impl_trait_arg() {
1778        check_assist(
1779            generate_function,
1780            r#"
1781//- minicore: sized
1782trait Foo {}
1783fn foo() -> impl Foo {
1784    todo!()
1785}
1786fn baz() {
1787    $0bar(foo())
1788}
1789"#,
1790            r#"
1791trait Foo {}
1792fn foo() -> impl Foo {
1793    todo!()
1794}
1795fn baz() {
1796    bar(foo())
1797}
1798
1799fn bar(foo: impl Foo) {
1800    ${0:todo!()}
1801}
1802"#,
1803        )
1804    }
1805
1806    #[test]
1807    fn borrowed_arg() {
1808        check_assist(
1809            generate_function,
1810            r"
1811struct Baz;
1812fn baz() -> Baz { todo!() }
1813
1814fn foo() {
1815    bar$0(&baz())
1816}
1817",
1818            r"
1819struct Baz;
1820fn baz() -> Baz { todo!() }
1821
1822fn foo() {
1823    bar(&baz())
1824}
1825
1826fn bar(baz: &Baz) {
1827    ${0:todo!()}
1828}
1829",
1830        )
1831    }
1832
1833    #[test]
1834    fn add_function_with_qualified_path_arg() {
1835        check_assist(
1836            generate_function,
1837            r"
1838mod Baz {
1839    pub struct Bof;
1840    pub fn baz() -> Bof { Bof }
1841}
1842fn foo() {
1843    $0bar(Baz::baz())
1844}
1845",
1846            r"
1847mod Baz {
1848    pub struct Bof;
1849    pub fn baz() -> Bof { Bof }
1850}
1851fn foo() {
1852    bar(Baz::baz())
1853}
1854
1855fn bar(baz: Baz::Bof) {
1856    ${0:todo!()}
1857}
1858",
1859        )
1860    }
1861
1862    #[test]
1863    fn generate_function_with_generic_param() {
1864        check_assist(
1865            generate_function,
1866            r"
1867fn foo<T, const N: usize>(t: [T; N]) { $0bar(t) }
1868",
1869            r"
1870fn foo<T, const N: usize>(t: [T; N]) { bar(t) }
1871
1872fn bar<T, const N: usize>(t: [T; N]) {
1873    ${0:todo!()}
1874}
1875",
1876        )
1877    }
1878
1879    #[test]
1880    fn generate_function_with_parent_generic_param() {
1881        check_assist(
1882            generate_function,
1883            r"
1884struct S<T>(T);
1885impl<T> S<T> {
1886    fn foo<U>(t: T, u: U) { $0bar(t, u) }
1887}
1888",
1889            r"
1890struct S<T>(T);
1891impl<T> S<T> {
1892    fn foo<U>(t: T, u: U) { bar(t, u) }
1893}
1894
1895fn bar<T, U>(t: T, u: U) {
1896    ${0:todo!()}
1897}
1898",
1899        )
1900    }
1901
1902    #[test]
1903    fn generic_param_in_receiver_type() {
1904        // FIXME: Generic parameter `T` should be part of impl, not method.
1905        check_assist(
1906            generate_function,
1907            r"
1908struct S<T>(T);
1909fn foo<T, U>(s: S<T>, u: U) { s.$0foo(u) }
1910",
1911            r"
1912struct S<T>(T);
1913impl S {
1914    fn foo<T, U>(&self, u: U) {
1915        ${0:todo!()}
1916    }
1917}
1918fn foo<T, U>(s: S<T>, u: U) { s.foo(u) }
1919",
1920        )
1921    }
1922
1923    #[test]
1924    fn generic_param_in_return_type() {
1925        check_assist(
1926            generate_function,
1927            r"
1928fn foo<T, const N: usize>() -> [T; N] { $0bar() }
1929",
1930            r"
1931fn foo<T, const N: usize>() -> [T; N] { bar() }
1932
1933fn bar<T, const N: usize>() -> [T; N] {
1934    ${0:todo!()}
1935}
1936",
1937        )
1938    }
1939
1940    #[test]
1941    fn generate_fn_with_bounds() {
1942        // FIXME: where predicates should be on next lines.
1943        check_assist(
1944            generate_function,
1945            r"
1946trait A<T> {}
1947struct S<T>(T);
1948impl<T: A<i32>> S<T>
1949where
1950    T: A<i64>,
1951{
1952    fn foo<U>(t: T, u: U)
1953    where
1954        T: A<()>,
1955        U: A<i32> + A<i64>,
1956    {
1957        $0bar(t, u)
1958    }
1959}
1960",
1961            r"
1962trait A<T> {}
1963struct S<T>(T);
1964impl<T: A<i32>> S<T>
1965where
1966    T: A<i64>,
1967{
1968    fn foo<U>(t: T, u: U)
1969    where
1970        T: A<()>,
1971        U: A<i32> + A<i64>,
1972    {
1973        bar(t, u)
1974    }
1975}
1976
1977fn bar<T: A<i32>, U>(t: T, u: U) where T: A<i64>, T: A<()>, U: A<i32> + A<i64> {
1978    ${0:todo!()}
1979}
1980",
1981        )
1982    }
1983
1984    #[test]
1985    fn include_transitive_param_dependency() {
1986        // FIXME: where predicates should be on next lines.
1987        check_assist(
1988            generate_function,
1989            r"
1990trait A<T> { type Assoc; }
1991trait B { type Item; }
1992struct S<T>(T);
1993impl<T, U, V: B, W> S<(T, U, V, W)>
1994where
1995    T: A<U, Assoc = V>,
1996    S<V::Item>: A<U, Assoc = W>,
1997{
1998    fn foo<I>(t: T, u: U)
1999    where
2000        U: A<T, Assoc = I>,
2001    {
2002        $0bar(u)
2003    }
2004}
2005",
2006            r"
2007trait A<T> { type Assoc; }
2008trait B { type Item; }
2009struct S<T>(T);
2010impl<T, U, V: B, W> S<(T, U, V, W)>
2011where
2012    T: A<U, Assoc = V>,
2013    S<V::Item>: A<U, Assoc = W>,
2014{
2015    fn foo<I>(t: T, u: U)
2016    where
2017        U: A<T, Assoc = I>,
2018    {
2019        bar(u)
2020    }
2021}
2022
2023fn bar<T, U, V: B, W, I>(u: U) where T: A<U, Assoc = V>, S<V::Item>: A<U, Assoc = W>, U: A<T, Assoc = I> {
2024    ${0:todo!()}
2025}
2026",
2027        )
2028    }
2029
2030    #[test]
2031    fn irrelevant_bounds_are_filtered_out() {
2032        check_assist(
2033            generate_function,
2034            r"
2035trait A<T> {}
2036struct S<T>(T);
2037impl<T, U, V, W> S<(T, U, V, W)>
2038where
2039    T: A<U>,
2040    V: A<W>,
2041{
2042    fn foo<I>(t: T, u: U)
2043    where
2044        U: A<T> + A<I>,
2045    {
2046        $0bar(u)
2047    }
2048}
2049",
2050            r"
2051trait A<T> {}
2052struct S<T>(T);
2053impl<T, U, V, W> S<(T, U, V, W)>
2054where
2055    T: A<U>,
2056    V: A<W>,
2057{
2058    fn foo<I>(t: T, u: U)
2059    where
2060        U: A<T> + A<I>,
2061    {
2062        bar(u)
2063    }
2064}
2065
2066fn bar<T, U, I>(u: U) where T: A<U>, U: A<T> + A<I> {
2067    ${0:todo!()}
2068}
2069",
2070        )
2071    }
2072
2073    #[test]
2074    fn params_in_trait_arg_are_not_dependency() {
2075        // Even though `bar` depends on `U` and `I`, we don't have to copy these bounds:
2076        // `T: A<I>` and `T: A<U>`.
2077        check_assist(
2078            generate_function,
2079            r"
2080trait A<T> {}
2081struct S<T>(T);
2082impl<T, U> S<(T, U)>
2083where
2084    T: A<U>,
2085{
2086    fn foo<I>(t: T, u: U)
2087    where
2088        T: A<I>,
2089        U: A<I>,
2090    {
2091        $0bar(u)
2092    }
2093}
2094",
2095            r"
2096trait A<T> {}
2097struct S<T>(T);
2098impl<T, U> S<(T, U)>
2099where
2100    T: A<U>,
2101{
2102    fn foo<I>(t: T, u: U)
2103    where
2104        T: A<I>,
2105        U: A<I>,
2106    {
2107        bar(u)
2108    }
2109}
2110
2111fn bar<U, I>(u: U) where U: A<I> {
2112    ${0:todo!()}
2113}
2114",
2115        )
2116    }
2117
2118    #[test]
2119    fn dont_copy_bounds_already_in_scope() {
2120        check_assist(
2121            generate_function,
2122            r"
2123trait A<T> {}
2124struct S<T>(T);
2125impl<T: A<i32>> S<T>
2126where
2127    T: A<usize>,
2128{
2129    fn foo<U: A<()>>(t: T, u: U)
2130    where
2131        T: A<S<i32>>,
2132    {
2133        Self::$0bar(t, u);
2134    }
2135}
2136",
2137            r"
2138trait A<T> {}
2139struct S<T>(T);
2140impl<T: A<i32>> S<T>
2141where
2142    T: A<usize>,
2143{
2144    fn foo<U: A<()>>(t: T, u: U)
2145    where
2146        T: A<S<i32>>,
2147    {
2148        Self::bar(t, u);
2149    }
2150
2151    fn bar<U: A<()>>(t: T, u: U) ${0:-> _} where T: A<S<i32>> {
2152        todo!()
2153    }
2154}
2155",
2156        )
2157    }
2158
2159    #[test]
2160    fn add_function_with_fn_arg() {
2161        check_assist(
2162            generate_function,
2163            r"
2164struct Baz;
2165impl Baz {
2166    fn new() -> Self { Baz }
2167}
2168fn foo() {
2169    $0bar(Baz::new);
2170}
2171",
2172            r"
2173struct Baz;
2174impl Baz {
2175    fn new() -> Self { Baz }
2176}
2177fn foo() {
2178    bar(Baz::new);
2179}
2180
2181fn bar(new: fn() -> Baz) ${0:-> _} {
2182    todo!()
2183}
2184",
2185        )
2186    }
2187
2188    #[test]
2189    fn add_function_with_closure_arg() {
2190        check_assist(
2191            generate_function,
2192            r"
2193fn foo() {
2194    let closure = |x: i64| x - 1;
2195    $0bar(closure)
2196}
2197",
2198            r"
2199fn foo() {
2200    let closure = |x: i64| x - 1;
2201    bar(closure)
2202}
2203
2204fn bar(closure: impl Fn(i64) -> i64) {
2205    ${0:todo!()}
2206}
2207",
2208        )
2209    }
2210
2211    #[test]
2212    fn unresolvable_types_default_to_placeholder() {
2213        check_assist(
2214            generate_function,
2215            r"
2216fn foo() {
2217    $0bar(baz)
2218}
2219",
2220            r"
2221fn foo() {
2222    bar(baz)
2223}
2224
2225fn bar(baz: _) {
2226    ${0:todo!()}
2227}
2228",
2229        )
2230    }
2231
2232    #[test]
2233    fn arg_names_dont_overlap() {
2234        check_assist(
2235            generate_function,
2236            r"
2237struct Baz;
2238fn baz() -> Baz { Baz }
2239fn foo() {
2240    $0bar(baz(), baz())
2241}
2242",
2243            r"
2244struct Baz;
2245fn baz() -> Baz { Baz }
2246fn foo() {
2247    bar(baz(), baz())
2248}
2249
2250fn bar(baz_1: Baz, baz_2: Baz) {
2251    ${0:todo!()}
2252}
2253",
2254        )
2255    }
2256
2257    #[test]
2258    fn arg_name_counters_start_at_1_per_name() {
2259        check_assist(
2260            generate_function,
2261            r#"
2262struct Baz;
2263fn baz() -> Baz { Baz }
2264fn foo() {
2265    $0bar(baz(), baz(), "foo", "bar")
2266}
2267"#,
2268            r#"
2269struct Baz;
2270fn baz() -> Baz { Baz }
2271fn foo() {
2272    bar(baz(), baz(), "foo", "bar")
2273}
2274
2275fn bar(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) {
2276    ${0:todo!()}
2277}
2278"#,
2279        )
2280    }
2281
2282    #[test]
2283    fn add_function_in_module() {
2284        check_assist(
2285            generate_function,
2286            r"
2287mod bar {}
2288
2289fn foo() {
2290    bar::my_fn$0()
2291}
2292",
2293            r"
2294mod bar {
2295    pub(crate) fn my_fn() {
2296        ${0:todo!()}
2297    }
2298}
2299
2300fn foo() {
2301    bar::my_fn()
2302}
2303",
2304        )
2305    }
2306
2307    #[test]
2308    fn qualified_path_uses_correct_scope() {
2309        check_assist(
2310            generate_function,
2311            r#"
2312mod foo {
2313    pub struct Foo;
2314}
2315fn bar() {
2316    use foo::Foo;
2317    let foo = Foo;
2318    baz$0(foo)
2319}
2320"#,
2321            r#"
2322mod foo {
2323    pub struct Foo;
2324}
2325fn bar() {
2326    use foo::Foo;
2327    let foo = Foo;
2328    baz(foo)
2329}
2330
2331fn baz(foo: foo::Foo) {
2332    ${0:todo!()}
2333}
2334"#,
2335        )
2336    }
2337
2338    #[test]
2339    fn qualified_path_in_generic_bounds_uses_correct_scope() {
2340        check_assist(
2341            generate_function,
2342            r"
2343mod a {
2344    pub trait A {};
2345}
2346pub mod b {
2347    pub struct S<T>(T);
2348}
2349struct S<T>(T);
2350impl<T> S<T>
2351where
2352    T: a::A,
2353{
2354    fn foo<U: a::A>(t: b::S<T>, u: S<U>) {
2355        a::$0bar(t, u);
2356    }
2357}
2358",
2359            r"
2360mod a {
2361    pub trait A {}
2362
2363    pub(crate) fn bar<T, U: self::A>(t: crate::b::S<T>, u: crate::S<U>) ${0:-> _} where T: self::A {
2364        todo!()
2365    };
2366}
2367pub mod b {
2368    pub struct S<T>(T);
2369}
2370struct S<T>(T);
2371impl<T> S<T>
2372where
2373    T: a::A,
2374{
2375    fn foo<U: a::A>(t: b::S<T>, u: S<U>) {
2376        a::bar(t, u);
2377    }
2378}
2379",
2380        )
2381    }
2382    #[test]
2383    fn add_function_in_module_containing_other_items() {
2384        check_assist(
2385            generate_function,
2386            r"
2387mod bar {
2388    fn something_else() {}
2389}
2390
2391fn foo() {
2392    bar::my_fn$0()
2393}
2394",
2395            r"
2396mod bar {
2397    fn something_else() {}
2398
2399    pub(crate) fn my_fn() {
2400        ${0:todo!()}
2401    }
2402}
2403
2404fn foo() {
2405    bar::my_fn()
2406}
2407",
2408        )
2409    }
2410
2411    #[test]
2412    fn add_function_in_nested_module() {
2413        check_assist(
2414            generate_function,
2415            r"
2416mod bar {
2417    pub mod baz {}
2418}
2419
2420fn foo() {
2421    bar::baz::my_fn$0()
2422}
2423",
2424            r"
2425mod bar {
2426    pub mod baz {
2427        pub(crate) fn my_fn() {
2428            ${0:todo!()}
2429        }
2430    }
2431}
2432
2433fn foo() {
2434    bar::baz::my_fn()
2435}
2436",
2437        )
2438    }
2439
2440    #[test]
2441    fn add_function_in_another_file() {
2442        check_assist(
2443            generate_function,
2444            r"
2445//- /main.rs
2446mod foo;
2447
2448fn main() {
2449    foo::bar$0()
2450}
2451//- /foo.rs
2452",
2453            r"
2454
2455
2456pub(crate) fn bar() {
2457    ${0:todo!()}
2458}",
2459        )
2460    }
2461
2462    #[test]
2463    fn add_function_with_return_type() {
2464        check_assist(
2465            generate_function,
2466            r"
2467fn main() {
2468    let x: u32 = foo$0();
2469}
2470",
2471            r"
2472fn main() {
2473    let x: u32 = foo();
2474}
2475
2476fn foo() -> u32 {
2477    ${0:todo!()}
2478}
2479",
2480        )
2481    }
2482
2483    #[test]
2484    fn add_function_not_applicable_if_function_already_exists() {
2485        check_assist_not_applicable(
2486            generate_function,
2487            r"
2488fn foo() {
2489    bar$0();
2490}
2491
2492fn bar() {}
2493",
2494        )
2495    }
2496
2497    #[test]
2498    fn add_function_not_applicable_if_unresolved_variable_in_call_is_selected() {
2499        check_assist_not_applicable(
2500            // bar is resolved, but baz isn't.
2501            // The assist is only active if the cursor is on an unresolved path,
2502            // but the assist should only be offered if the path is a function call.
2503            generate_function,
2504            r#"
2505fn foo() {
2506    bar(b$0az);
2507}
2508
2509fn bar(baz: ()) {}
2510"#,
2511        )
2512    }
2513
2514    #[test]
2515    fn create_method_with_no_args() {
2516        check_assist(
2517            generate_function,
2518            r#"
2519struct Foo;
2520impl Foo {
2521    fn foo(&self) {
2522        self.bar()$0;
2523    }
2524}
2525"#,
2526            r#"
2527struct Foo;
2528impl Foo {
2529    fn foo(&self) {
2530        self.bar();
2531    }
2532
2533    fn bar(&self) ${0:-> _} {
2534        todo!()
2535    }
2536}
2537"#,
2538        )
2539    }
2540
2541    #[test]
2542    fn create_method_with_unused_generics() {
2543        check_assist(
2544            generate_function,
2545            r#"
2546struct Foo<S>(S);
2547impl<S> Foo<S> {
2548    fn foo(&self) {
2549        self.bar()$0;
2550    }
2551}
2552"#,
2553            r#"
2554struct Foo<S>(S);
2555impl<S> Foo<S> {
2556    fn foo(&self) {
2557        self.bar();
2558    }
2559
2560    fn bar(&self) ${0:-> _} {
2561        todo!()
2562    }
2563}
2564"#,
2565        )
2566    }
2567
2568    #[test]
2569    fn create_function_with_async() {
2570        check_assist(
2571            generate_function,
2572            r"
2573async fn foo() {
2574    $0bar(42).await;
2575}
2576",
2577            r"
2578async fn foo() {
2579    bar(42).await;
2580}
2581
2582async fn bar(arg: i32) ${0:-> _} {
2583    todo!()
2584}
2585",
2586        )
2587    }
2588
2589    #[test]
2590    fn return_type_for_async_fn() {
2591        check_assist(
2592            generate_function,
2593            r"
2594//- minicore: result
2595async fn foo() {
2596    if Err(()) = $0bar(42).await {}
2597}
2598",
2599            r"
2600async fn foo() {
2601    if Err(()) = bar(42).await {}
2602}
2603
2604async fn bar(arg: i32) -> Result<_, ()> {
2605    ${0:todo!()}
2606}
2607",
2608        );
2609    }
2610
2611    #[test]
2612    fn create_method() {
2613        check_assist(
2614            generate_function,
2615            r"
2616struct S;
2617fn foo() {S.bar$0();}
2618",
2619            r"
2620struct S;
2621impl S {
2622    fn bar(&self) ${0:-> _} {
2623        todo!()
2624    }
2625}
2626fn foo() {S.bar();}
2627",
2628        )
2629    }
2630
2631    #[test]
2632    fn create_method_within_an_impl() {
2633        check_assist(
2634            generate_function,
2635            r"
2636struct S;
2637fn foo() {S.bar$0();}
2638impl S {}
2639
2640",
2641            r"
2642struct S;
2643fn foo() {S.bar();}
2644impl S {
2645    fn bar(&self) ${0:-> _} {
2646        todo!()
2647    }
2648}
2649
2650",
2651        )
2652    }
2653
2654    #[test]
2655    fn create_method_from_different_module() {
2656        check_assist(
2657            generate_function,
2658            r"
2659mod s {
2660    pub struct S;
2661}
2662fn foo() {s::S.bar$0();}
2663",
2664            r"
2665mod s {
2666    pub struct S;
2667    impl S {
2668        pub(crate) fn bar(&self) ${0:-> _} {
2669            todo!()
2670        }
2671    }
2672}
2673fn foo() {s::S.bar();}
2674",
2675        )
2676    }
2677
2678    #[test]
2679    fn create_method_from_descendant_module() {
2680        check_assist(
2681            generate_function,
2682            r"
2683struct S;
2684mod s {
2685    fn foo() {
2686        super::S.bar$0();
2687    }
2688}
2689
2690",
2691            r"
2692struct S;
2693impl S {
2694    fn bar(&self) ${0:-> _} {
2695        todo!()
2696    }
2697}
2698mod s {
2699    fn foo() {
2700        super::S.bar();
2701    }
2702}
2703
2704",
2705        )
2706    }
2707
2708    #[test]
2709    fn create_method_with_cursor_anywhere_on_call_expression() {
2710        check_assist(
2711            generate_function,
2712            r"
2713struct S;
2714fn foo() {$0S.bar();}
2715",
2716            r"
2717struct S;
2718impl S {
2719    fn bar(&self) ${0:-> _} {
2720        todo!()
2721    }
2722}
2723fn foo() {S.bar();}
2724",
2725        )
2726    }
2727
2728    #[test]
2729    fn create_async_method() {
2730        check_assist(
2731            generate_function,
2732            r"
2733//- minicore: result
2734struct S;
2735async fn foo() {
2736    if let Err(()) = S.$0bar(42).await {}
2737}
2738",
2739            r"
2740struct S;
2741impl S {
2742    async fn bar(&self, arg: i32) -> Result<_, ()> {
2743        ${0:todo!()}
2744    }
2745}
2746async fn foo() {
2747    if let Err(()) = S.bar(42).await {}
2748}
2749",
2750        )
2751    }
2752
2753    #[test]
2754    fn create_static_method() {
2755        check_assist(
2756            generate_function,
2757            r"
2758struct S;
2759fn foo() {S::bar$0();}
2760",
2761            r"
2762struct S;
2763impl S {
2764    fn bar() ${0:-> _} {
2765        todo!()
2766    }
2767}
2768fn foo() {S::bar();}
2769",
2770        )
2771    }
2772
2773    #[test]
2774    fn create_async_static_method() {
2775        check_assist(
2776            generate_function,
2777            r"
2778//- minicore: result
2779struct S;
2780async fn foo() {
2781    if let Err(()) = S::$0bar(42).await {}
2782}
2783",
2784            r"
2785struct S;
2786impl S {
2787    async fn bar(arg: i32) -> Result<_, ()> {
2788        ${0:todo!()}
2789    }
2790}
2791async fn foo() {
2792    if let Err(()) = S::bar(42).await {}
2793}
2794",
2795        )
2796    }
2797
2798    #[test]
2799    fn create_generic_static_method() {
2800        check_assist(
2801            generate_function,
2802            r"
2803struct S;
2804fn foo<T, const N: usize>(t: [T; N]) { S::bar$0(t); }
2805",
2806            r"
2807struct S;
2808impl S {
2809    fn bar<T, const N: usize>(t: [T; N]) ${0:-> _} {
2810        todo!()
2811    }
2812}
2813fn foo<T, const N: usize>(t: [T; N]) { S::bar(t); }
2814",
2815        )
2816    }
2817
2818    #[test]
2819    fn create_static_method_within_an_impl() {
2820        check_assist(
2821            generate_function,
2822            r"
2823struct S;
2824fn foo() {S::bar$0();}
2825impl S {}
2826
2827",
2828            r"
2829struct S;
2830fn foo() {S::bar();}
2831impl S {
2832    fn bar() ${0:-> _} {
2833        todo!()
2834    }
2835}
2836
2837",
2838        )
2839    }
2840
2841    #[test]
2842    fn create_static_method_from_different_module() {
2843        check_assist(
2844            generate_function,
2845            r"
2846mod s {
2847    pub struct S;
2848}
2849fn foo() {s::S::bar$0();}
2850",
2851            r"
2852mod s {
2853    pub struct S;
2854    impl S {
2855        pub(crate) fn bar() ${0:-> _} {
2856            todo!()
2857        }
2858    }
2859}
2860fn foo() {s::S::bar();}
2861",
2862        )
2863    }
2864
2865    #[test]
2866    fn create_static_method_with_cursor_anywhere_on_call_expression() {
2867        check_assist(
2868            generate_function,
2869            r"
2870struct S;
2871fn foo() {$0S::bar();}
2872",
2873            r"
2874struct S;
2875impl S {
2876    fn bar() ${0:-> _} {
2877        todo!()
2878    }
2879}
2880fn foo() {S::bar();}
2881",
2882        )
2883    }
2884
2885    #[test]
2886    fn create_static_method_within_an_impl_with_self_syntax() {
2887        check_assist(
2888            generate_function,
2889            r"
2890struct S;
2891impl S {
2892    fn foo(&self) {
2893        Self::bar$0();
2894    }
2895}
2896",
2897            r"
2898struct S;
2899impl S {
2900    fn foo(&self) {
2901        Self::bar();
2902    }
2903
2904    fn bar() ${0:-> _} {
2905        todo!()
2906    }
2907}
2908",
2909        )
2910    }
2911
2912    #[test]
2913    fn no_panic_on_invalid_global_path() {
2914        check_assist(
2915            generate_function,
2916            r"
2917fn main() {
2918    ::foo$0();
2919}
2920",
2921            r"
2922fn main() {
2923    ::foo();
2924}
2925
2926fn foo() ${0:-> _} {
2927    todo!()
2928}
2929",
2930        )
2931    }
2932
2933    #[test]
2934    fn handle_tuple_indexing() {
2935        check_assist(
2936            generate_function,
2937            r"
2938fn main() {
2939    let a = ((),);
2940    foo$0(a.0);
2941}
2942",
2943            r"
2944fn main() {
2945    let a = ((),);
2946    foo(a.0);
2947}
2948
2949fn foo(a: ()) ${0:-> _} {
2950    todo!()
2951}
2952",
2953        )
2954    }
2955
2956    #[test]
2957    fn add_function_with_const_arg() {
2958        check_assist(
2959            generate_function,
2960            r"
2961const VALUE: usize = 0;
2962fn main() {
2963    foo$0(VALUE);
2964}
2965",
2966            r"
2967const VALUE: usize = 0;
2968fn main() {
2969    foo(VALUE);
2970}
2971
2972fn foo(value: usize) ${0:-> _} {
2973    todo!()
2974}
2975",
2976        )
2977    }
2978
2979    #[test]
2980    fn add_function_with_static_arg() {
2981        check_assist(
2982            generate_function,
2983            r"
2984static VALUE: usize = 0;
2985fn main() {
2986    foo$0(VALUE);
2987}
2988",
2989            r"
2990static VALUE: usize = 0;
2991fn main() {
2992    foo(VALUE);
2993}
2994
2995fn foo(value: usize) ${0:-> _} {
2996    todo!()
2997}
2998",
2999        )
3000    }
3001
3002    #[test]
3003    fn add_function_with_static_mut_arg() {
3004        check_assist(
3005            generate_function,
3006            r"
3007static mut VALUE: usize = 0;
3008fn main() {
3009    foo$0(VALUE);
3010}
3011",
3012            r"
3013static mut VALUE: usize = 0;
3014fn main() {
3015    foo(VALUE);
3016}
3017
3018fn foo(value: usize) ${0:-> _} {
3019    todo!()
3020}
3021",
3022        )
3023    }
3024
3025    #[test]
3026    fn not_applicable_for_enum_variant() {
3027        check_assist_not_applicable(
3028            generate_function,
3029            r"
3030enum Foo {}
3031fn main() {
3032    Foo::Bar$0(true)
3033}
3034",
3035        );
3036    }
3037
3038    #[test]
3039    fn applicable_for_enum_method() {
3040        check_assist(
3041            generate_function,
3042            r"
3043enum Foo {}
3044fn main() {
3045    Foo::bar$0();
3046}
3047",
3048            r"
3049enum Foo {}
3050impl Foo {
3051    fn bar() ${0:-> _} {
3052        todo!()
3053    }
3054}
3055fn main() {
3056    Foo::bar();
3057}
3058",
3059        )
3060    }
3061
3062    #[test]
3063    fn applicable_in_different_local_crate() {
3064        check_assist(
3065            generate_function,
3066            r"
3067//- /lib.rs crate:lib new_source_root:local
3068fn dummy() {}
3069//- /main.rs crate:main deps:lib new_source_root:local
3070fn main() {
3071    lib::foo$0();
3072}
3073",
3074            r"
3075fn dummy() {}
3076
3077pub fn foo() ${0:-> _} {
3078    todo!()
3079}
3080",
3081        );
3082    }
3083
3084    #[test]
3085    fn applicable_in_different_local_crate_method() {
3086        check_assist(
3087            generate_function,
3088            r"
3089//- /lib.rs crate:lib new_source_root:local
3090pub struct S;
3091//- /main.rs crate:main deps:lib new_source_root:local
3092fn main() {
3093    lib::S.foo$0();
3094}
3095",
3096            r"
3097pub struct S;
3098impl S {
3099    pub fn foo(&self) ${0:-> _} {
3100        todo!()
3101    }
3102}
3103",
3104        );
3105    }
3106
3107    #[test]
3108    fn not_applicable_in_different_library_crate() {
3109        check_assist_not_applicable(
3110            generate_function,
3111            r"
3112//- /lib.rs crate:lib new_source_root:library
3113fn dummy() {}
3114//- /main.rs crate:main deps:lib new_source_root:local
3115fn main() {
3116    lib::foo$0();
3117}
3118",
3119        );
3120    }
3121
3122    #[test]
3123    fn not_applicable_in_different_library_crate_method() {
3124        check_assist_not_applicable(
3125            generate_function,
3126            r"
3127//- /lib.rs crate:lib new_source_root:library
3128pub struct S;
3129//- /main.rs crate:main deps:lib new_source_root:local
3130fn main() {
3131    lib::S.foo$0();
3132}
3133",
3134        );
3135    }
3136
3137    #[test]
3138    fn new_function_assume_self_type() {
3139        check_assist(
3140            generate_function,
3141            r"
3142pub struct Foo {
3143    field_1: usize,
3144    field_2: String,
3145}
3146
3147fn main() {
3148    let foo = Foo::new$0();
3149}
3150        ",
3151            r"
3152pub struct Foo {
3153    field_1: usize,
3154    field_2: String,
3155}
3156impl Foo {
3157    fn new() -> Self {
3158        ${0:Self { field_1: todo!(), field_2: todo!() }}
3159    }
3160}
3161
3162fn main() {
3163    let foo = Foo::new();
3164}
3165        ",
3166        )
3167    }
3168
3169    #[test]
3170    fn new_function_assume_self_type_for_tuple_struct() {
3171        check_assist(
3172            generate_function,
3173            r"
3174pub struct Foo (usize, String);
3175
3176fn main() {
3177    let foo = Foo::new$0();
3178}
3179        ",
3180            r"
3181pub struct Foo (usize, String);
3182impl Foo {
3183    fn new() -> Self {
3184        ${0:Self(todo!(), todo!())}
3185    }
3186}
3187
3188fn main() {
3189    let foo = Foo::new();
3190}
3191        ",
3192        )
3193    }
3194
3195    #[test]
3196    fn new_function_assume_self_type_for_unit_struct() {
3197        check_assist(
3198            generate_function,
3199            r"
3200pub struct Foo;
3201
3202fn main() {
3203    let foo = Foo::new$0();
3204}
3205        ",
3206            r"
3207pub struct Foo;
3208impl Foo {
3209    fn new() -> Self {
3210        ${0:Self}
3211    }
3212}
3213
3214fn main() {
3215    let foo = Foo::new();
3216}
3217        ",
3218        )
3219    }
3220
3221    #[test]
3222    fn new_function_assume_self_type_for_enum() {
3223        check_assist(
3224            generate_function,
3225            r"
3226pub enum Foo {}
3227
3228fn main() {
3229    let foo = Foo::new$0();
3230}
3231        ",
3232            r"
3233pub enum Foo {}
3234impl Foo {
3235    fn new() -> Self {
3236        ${0:todo!()}
3237    }
3238}
3239
3240fn main() {
3241    let foo = Foo::new();
3242}
3243        ",
3244        )
3245    }
3246
3247    #[test]
3248    fn new_function_assume_self_type_with_args() {
3249        check_assist(
3250            generate_function,
3251            r#"
3252pub struct Foo {
3253    field_1: usize,
3254    field_2: String,
3255}
3256
3257struct Baz;
3258fn baz() -> Baz { Baz }
3259
3260fn main() {
3261    let foo = Foo::new$0(baz(), baz(), "foo", "bar");
3262}
3263        "#,
3264            r#"
3265pub struct Foo {
3266    field_1: usize,
3267    field_2: String,
3268}
3269impl Foo {
3270    fn new(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) -> Self {
3271        ${0:Self { field_1: todo!(), field_2: todo!() }}
3272    }
3273}
3274
3275struct Baz;
3276fn baz() -> Baz { Baz }
3277
3278fn main() {
3279    let foo = Foo::new(baz(), baz(), "foo", "bar");
3280}
3281        "#,
3282        )
3283    }
3284
3285    #[test]
3286    fn no_generate_method_by_keyword() {
3287        check_assist_not_applicable(
3288            generate_function,
3289            r#"
3290fn main() {
3291    s.super$0();
3292}
3293        "#,
3294        );
3295        check_assist_not_applicable(
3296            generate_function,
3297            r#"
3298fn main() {
3299    s.Self$0();
3300}
3301        "#,
3302        );
3303        check_assist_not_applicable(
3304            generate_function,
3305            r#"
3306fn main() {
3307    s.self$0();
3308}
3309        "#,
3310        );
3311    }
3312
3313    #[test]
3314    fn regression_21288() {
3315        check_assist(
3316            generate_function,
3317            r#"
3318//- minicore: copy
3319fn foo() {
3320    $0bar(&|x| true)
3321}
3322        "#,
3323            r#"
3324fn foo() {
3325    bar(&|x| true)
3326}
3327
3328fn bar(arg: impl Fn(_) -> bool) {
3329    ${0:todo!()}
3330}
3331        "#,
3332        );
3333    }
3334    #[test]
3335    fn generate_method_uses_current_impl_block() {
3336        check_assist(
3337            generate_function,
3338            r"
3339struct Foo;
3340
3341impl Foo {
3342    fn new() -> Self {
3343        Foo
3344    }
3345}
3346
3347impl Foo {
3348    fn method1(&self) {
3349        self.method2$0(42)
3350    }
3351}
3352",
3353            r"
3354struct Foo;
3355
3356impl Foo {
3357    fn new() -> Self {
3358        Foo
3359    }
3360}
3361
3362impl Foo {
3363    fn method1(&self) {
3364        self.method2(42)
3365    }
3366
3367    fn method2(&self, arg: i32) {
3368        ${0:todo!()}
3369    }
3370}
3371",
3372        )
3373    }
3374
3375    #[test]
3376    fn generate_method_skips_trait_impl_for_inherent() {
3377        // regression: rust-lang/rust-analyzer#22123
3378        check_assist(
3379            generate_function,
3380            r"
3381struct Bar;
3382
3383impl Bar {
3384    fn func1() {}
3385}
3386
3387trait Foo { fn foo(&self); }
3388
3389impl Foo for Bar {
3390    fn foo(&self) {
3391        self.func2$0();
3392    }
3393}
3394",
3395            r"
3396struct Bar;
3397
3398impl Bar {
3399    fn func1() {}
3400
3401    fn func2(&self) ${0:-> _} {
3402        todo!()
3403    }
3404}
3405
3406trait Foo { fn foo(&self); }
3407
3408impl Foo for Bar {
3409    fn foo(&self) {
3410        self.func2();
3411    }
3412}
3413",
3414        )
3415    }
3416
3417    #[test]
3418    fn generate_method_from_trait_impl_creates_new_inherent_impl() {
3419        // #22123: no inherent impl exists, so the assist must synthesize one
3420        // instead of inserting into the trait impl.
3421        check_assist(
3422            generate_function,
3423            r"
3424struct Bar;
3425
3426trait Foo { fn foo(&self); }
3427
3428impl Foo for Bar {
3429    fn foo(&self) {
3430        self.func2$0();
3431    }
3432}
3433",
3434            r"
3435struct Bar;
3436impl Bar {
3437    fn func2(&self) ${0:-> _} {
3438        todo!()
3439    }
3440}
3441
3442trait Foo { fn foo(&self); }
3443
3444impl Foo for Bar {
3445    fn foo(&self) {
3446        self.func2();
3447    }
3448}
3449",
3450        )
3451    }
3452}