]> git.lizzy.rs Git - rust.git/blob - crates/ide-assists/src/handlers/extract_function.rs
Avoid cloning IMPL node if we don't have to
[rust.git] / crates / ide-assists / src / handlers / extract_function.rs
1 use std::iter;
2
3 use ast::make;
4 use either::Either;
5 use hir::{
6     HasSource, HirDisplay, InFile, Local, ModuleDef, PathResolution, Semantics, TypeInfo, TypeParam,
7 };
8 use ide_db::{
9     defs::{Definition, NameRefClass},
10     famous_defs::FamousDefs,
11     helpers::mod_path_to_ast,
12     imports::insert_use::{insert_use, ImportScope},
13     search::{FileReference, ReferenceCategory, SearchScope},
14     syntax_helpers::node_ext::{preorder_expr, walk_expr, walk_pat, walk_patterns_in_expr},
15     FxIndexSet, RootDatabase,
16 };
17 use itertools::Itertools;
18 use stdx::format_to;
19 use syntax::{
20     ast::{
21         self,
22         edit::{AstNodeEdit, IndentLevel},
23         AstNode, HasGenericParams,
24     },
25     match_ast, ted, SyntaxElement,
26     SyntaxKind::{self, COMMENT},
27     SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T,
28 };
29
30 use crate::{
31     assist_context::{AssistContext, Assists, TreeMutator},
32     utils::generate_impl_text,
33     AssistId,
34 };
35
36 // Assist: extract_function
37 //
38 // Extracts selected statements and comments into new function.
39 //
40 // ```
41 // fn main() {
42 //     let n = 1;
43 //     $0let m = n + 2;
44 //     // calculate
45 //     let k = m + n;$0
46 //     let g = 3;
47 // }
48 // ```
49 // ->
50 // ```
51 // fn main() {
52 //     let n = 1;
53 //     fun_name(n);
54 //     let g = 3;
55 // }
56 //
57 // fn $0fun_name(n: i32) {
58 //     let m = n + 2;
59 //     // calculate
60 //     let k = m + n;
61 // }
62 // ```
63 pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
64     let range = ctx.selection_trimmed();
65     if range.is_empty() {
66         return None;
67     }
68
69     let node = ctx.covering_element();
70     if node.kind() == COMMENT {
71         cov_mark::hit!(extract_function_in_comment_is_not_applicable);
72         return None;
73     }
74
75     let node = match node {
76         syntax::NodeOrToken::Node(n) => n,
77         syntax::NodeOrToken::Token(t) => t.parent()?,
78     };
79
80     let body = extraction_target(&node, range)?;
81     let container_info = body.analyze_container(&ctx.sema)?;
82
83     let (locals_used, self_param) = body.analyze(&ctx.sema);
84
85     let anchor = if self_param.is_some() { Anchor::Method } else { Anchor::Freestanding };
86     let insert_after = node_to_insert_after(&body, anchor)?;
87     let semantics_scope = ctx.sema.scope(&insert_after)?;
88     let module = semantics_scope.module();
89
90     let ret_ty = body.return_ty(ctx)?;
91     let control_flow = body.external_control_flow(ctx, &container_info)?;
92     let ret_values = body.ret_values(ctx, node.parent().as_ref().unwrap_or(&node));
93
94     let target_range = body.text_range();
95
96     let scope = ImportScope::find_insert_use_container(&node, &ctx.sema)?;
97
98     acc.add(
99         AssistId("extract_function", crate::AssistKind::RefactorExtract),
100         "Extract into function",
101         target_range,
102         move |builder| {
103             let outliving_locals: Vec<_> = ret_values.collect();
104             if stdx::never!(!outliving_locals.is_empty() && !ret_ty.is_unit()) {
105                 // We should not have variables that outlive body if we have expression block
106                 return;
107             }
108
109             let params =
110                 body.extracted_function_params(ctx, &container_info, locals_used.iter().copied());
111
112             let name = make_function_name(&semantics_scope);
113
114             let fun = Function {
115                 name,
116                 self_param,
117                 params,
118                 control_flow,
119                 ret_ty,
120                 body,
121                 outliving_locals,
122                 mods: container_info,
123             };
124
125             let new_indent = IndentLevel::from_node(&insert_after);
126             let old_indent = fun.body.indent_level();
127
128             builder.replace(target_range, make_call(ctx, &fun, old_indent));
129
130             let has_impl_wrapper = insert_after
131                 .ancestors()
132                 .find(|a| a.kind() == SyntaxKind::IMPL && a != &insert_after)
133                 .is_some();
134
135             let fn_def = match fun.self_param_adt(ctx) {
136                 Some(adt) if anchor == Anchor::Method && !has_impl_wrapper => {
137                     let fn_def = format_function(ctx, module, &fun, old_indent, new_indent + 1);
138                     generate_impl_text(&adt, &fn_def).replace("{\n\n", "{")
139                 }
140                 _ => format_function(ctx, module, &fun, old_indent, new_indent),
141             };
142
143             if fn_def.contains("ControlFlow") {
144                 let scope = match scope {
145                     ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
146                     ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
147                     ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
148                 };
149
150                 let control_flow_enum =
151                     FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow();
152
153                 if let Some(control_flow_enum) = control_flow_enum {
154                     let mod_path = module.find_use_path_prefixed(
155                         ctx.sema.db,
156                         ModuleDef::from(control_flow_enum),
157                         ctx.config.insert_use.prefix_kind,
158                     );
159
160                     if let Some(mod_path) = mod_path {
161                         insert_use(&scope, mod_path_to_ast(&mod_path), &ctx.config.insert_use);
162                     }
163                 }
164             }
165
166             let insert_offset = insert_after.text_range().end();
167
168             match ctx.config.snippet_cap {
169                 Some(cap) => builder.insert_snippet(cap, insert_offset, fn_def),
170                 None => builder.insert(insert_offset, fn_def),
171             };
172         },
173     )
174 }
175
176 fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef {
177     let mut names_in_scope = vec![];
178     semantics_scope.process_all_names(&mut |name, _| names_in_scope.push(name.to_string()));
179
180     let default_name = "fun_name";
181
182     let mut name = default_name.to_string();
183     let mut counter = 0;
184     while names_in_scope.contains(&name) {
185         counter += 1;
186         name = format!("{}{}", &default_name, counter)
187     }
188     make::name_ref(&name)
189 }
190
191 /// Try to guess what user wants to extract
192 ///
193 /// We have basically have two cases:
194 /// * We want whole node, like `loop {}`, `2 + 2`, `{ let n = 1; }` exprs.
195 ///   Then we can use `ast::Expr`
196 /// * We want a few statements for a block. E.g.
197 ///   ```rust,no_run
198 ///   fn foo() -> i32 {
199 ///     let m = 1;
200 ///     $0
201 ///     let n = 2;
202 ///     let k = 3;
203 ///     k + n
204 ///     $0
205 ///   }
206 ///   ```
207 ///
208 fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<FunctionBody> {
209     if let Some(stmt) = ast::Stmt::cast(node.clone()) {
210         return match stmt {
211             ast::Stmt::Item(_) => None,
212             ast::Stmt::ExprStmt(_) | ast::Stmt::LetStmt(_) => Some(FunctionBody::from_range(
213                 node.parent().and_then(ast::StmtList::cast)?,
214                 node.text_range(),
215             )),
216         };
217     }
218
219     // Covering element returned the parent block of one or multiple statements that have been selected
220     if let Some(stmt_list) = ast::StmtList::cast(node.clone()) {
221         if let Some(block_expr) = stmt_list.syntax().parent().and_then(ast::BlockExpr::cast) {
222             if block_expr.syntax().text_range() == selection_range {
223                 return FunctionBody::from_expr(block_expr.into());
224             }
225         }
226
227         // Extract the full statements.
228         return Some(FunctionBody::from_range(stmt_list, selection_range));
229     }
230
231     let expr = ast::Expr::cast(node.clone())?;
232     // A node got selected fully
233     if node.text_range() == selection_range {
234         return FunctionBody::from_expr(expr);
235     }
236
237     node.ancestors().find_map(ast::Expr::cast).and_then(FunctionBody::from_expr)
238 }
239
240 #[derive(Debug)]
241 struct Function {
242     name: ast::NameRef,
243     self_param: Option<ast::SelfParam>,
244     params: Vec<Param>,
245     control_flow: ControlFlow,
246     ret_ty: RetType,
247     body: FunctionBody,
248     outliving_locals: Vec<OutlivedLocal>,
249     mods: ContainerInfo,
250 }
251
252 #[derive(Debug)]
253 struct Param {
254     var: Local,
255     ty: hir::Type,
256     move_local: bool,
257     requires_mut: bool,
258     is_copy: bool,
259 }
260
261 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
262 enum ParamKind {
263     Value,
264     MutValue,
265     SharedRef,
266     MutRef,
267 }
268
269 #[derive(Debug, Eq, PartialEq)]
270 enum FunType {
271     Unit,
272     Single(hir::Type),
273     Tuple(Vec<hir::Type>),
274 }
275
276 /// Where to put extracted function definition
277 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
278 enum Anchor {
279     /// Extract free function and put right after current top-level function
280     Freestanding,
281     /// Extract method and put right after current function in the impl-block
282     Method,
283 }
284
285 // FIXME: ControlFlow and ContainerInfo both track some function modifiers, feels like these two should
286 // probably be merged somehow.
287 #[derive(Debug)]
288 struct ControlFlow {
289     kind: Option<FlowKind>,
290     is_async: bool,
291     is_unsafe: bool,
292 }
293
294 /// The thing whose expression we are extracting from. Can be a function, const, static, const arg, ...
295 #[derive(Clone, Debug)]
296 struct ContainerInfo {
297     is_const: bool,
298     is_in_tail: bool,
299     parent_loop: Option<SyntaxNode>,
300     /// The function's return type, const's type etc.
301     ret_type: Option<hir::Type>,
302     generic_param_lists: Vec<ast::GenericParamList>,
303     where_clauses: Vec<ast::WhereClause>,
304 }
305
306 /// Control flow that is exported from extracted function
307 ///
308 /// E.g.:
309 /// ```rust,no_run
310 /// loop {
311 ///     $0
312 ///     if 42 == 42 {
313 ///         break;
314 ///     }
315 ///     $0
316 /// }
317 /// ```
318 #[derive(Debug, Clone)]
319 enum FlowKind {
320     /// Return with value (`return $expr;`)
321     Return(Option<ast::Expr>),
322     Try {
323         kind: TryKind,
324     },
325     /// Break with label and value (`break 'label $expr;`)
326     Break(Option<ast::Lifetime>, Option<ast::Expr>),
327     /// Continue with label (`continue 'label;`)
328     Continue(Option<ast::Lifetime>),
329 }
330
331 #[derive(Debug, Clone)]
332 enum TryKind {
333     Option,
334     Result { ty: hir::Type },
335 }
336
337 #[derive(Debug)]
338 enum RetType {
339     Expr(hir::Type),
340     Stmt,
341 }
342
343 impl RetType {
344     fn is_unit(&self) -> bool {
345         match self {
346             RetType::Expr(ty) => ty.is_unit(),
347             RetType::Stmt => true,
348         }
349     }
350 }
351
352 /// Semantically same as `ast::Expr`, but preserves identity when using only part of the Block
353 /// This is the future function body, the part that is being extracted.
354 #[derive(Debug)]
355 enum FunctionBody {
356     Expr(ast::Expr),
357     Span { parent: ast::StmtList, text_range: TextRange },
358 }
359
360 #[derive(Debug)]
361 struct OutlivedLocal {
362     local: Local,
363     mut_usage_outside_body: bool,
364 }
365
366 /// Container of local variable usages
367 ///
368 /// Semanticall same as `UsageSearchResult`, but provides more convenient interface
369 struct LocalUsages(ide_db::search::UsageSearchResult);
370
371 impl LocalUsages {
372     fn find_local_usages(ctx: &AssistContext<'_>, var: Local) -> Self {
373         Self(
374             Definition::Local(var)
375                 .usages(&ctx.sema)
376                 .in_scope(SearchScope::single_file(ctx.file_id()))
377                 .all(),
378         )
379     }
380
381     fn iter(&self) -> impl Iterator<Item = &FileReference> + '_ {
382         self.0.iter().flat_map(|(_, rs)| rs)
383     }
384 }
385
386 impl Function {
387     fn return_type(&self, ctx: &AssistContext<'_>) -> FunType {
388         match &self.ret_ty {
389             RetType::Expr(ty) if ty.is_unit() => FunType::Unit,
390             RetType::Expr(ty) => FunType::Single(ty.clone()),
391             RetType::Stmt => match self.outliving_locals.as_slice() {
392                 [] => FunType::Unit,
393                 [var] => FunType::Single(var.local.ty(ctx.db())),
394                 vars => {
395                     let types = vars.iter().map(|v| v.local.ty(ctx.db())).collect();
396                     FunType::Tuple(types)
397                 }
398             },
399         }
400     }
401
402     fn self_param_adt(&self, ctx: &AssistContext<'_>) -> Option<ast::Adt> {
403         let self_param = self.self_param.as_ref()?;
404         let def = ctx.sema.to_def(self_param)?;
405         let adt = def.ty(ctx.db()).strip_references().as_adt()?;
406         let InFile { file_id: _, value } = adt.source(ctx.db())?;
407         Some(value)
408     }
409 }
410
411 impl ParamKind {
412     fn is_ref(&self) -> bool {
413         matches!(self, ParamKind::SharedRef | ParamKind::MutRef)
414     }
415 }
416
417 impl Param {
418     fn kind(&self) -> ParamKind {
419         match (self.move_local, self.requires_mut, self.is_copy) {
420             (false, true, _) => ParamKind::MutRef,
421             (false, false, false) => ParamKind::SharedRef,
422             (true, true, _) => ParamKind::MutValue,
423             (_, false, _) => ParamKind::Value,
424         }
425     }
426
427     fn to_arg(&self, ctx: &AssistContext<'_>) -> ast::Expr {
428         let var = path_expr_from_local(ctx, self.var);
429         match self.kind() {
430             ParamKind::Value | ParamKind::MutValue => var,
431             ParamKind::SharedRef => make::expr_ref(var, false),
432             ParamKind::MutRef => make::expr_ref(var, true),
433         }
434     }
435
436     fn to_param(&self, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Param {
437         let var = self.var.name(ctx.db()).to_string();
438         let var_name = make::name(&var);
439         let pat = match self.kind() {
440             ParamKind::MutValue => make::ident_pat(false, true, var_name),
441             ParamKind::Value | ParamKind::SharedRef | ParamKind::MutRef => {
442                 make::ext::simple_ident_pat(var_name)
443             }
444         };
445
446         let ty = make_ty(&self.ty, ctx, module);
447         let ty = match self.kind() {
448             ParamKind::Value | ParamKind::MutValue => ty,
449             ParamKind::SharedRef => make::ty_ref(ty, false),
450             ParamKind::MutRef => make::ty_ref(ty, true),
451         };
452
453         make::param(pat.into(), ty)
454     }
455 }
456
457 impl TryKind {
458     fn of_ty(ty: hir::Type, ctx: &AssistContext<'_>) -> Option<TryKind> {
459         if ty.is_unknown() {
460             // We favour Result for `expr?`
461             return Some(TryKind::Result { ty });
462         }
463         let adt = ty.as_adt()?;
464         let name = adt.name(ctx.db());
465         // FIXME: use lang items to determine if it is std type or user defined
466         //        E.g. if user happens to define type named `Option`, we would have false positive
467         match name.to_string().as_str() {
468             "Option" => Some(TryKind::Option),
469             "Result" => Some(TryKind::Result { ty }),
470             _ => None,
471         }
472     }
473 }
474
475 impl FlowKind {
476     fn make_result_handler(&self, expr: Option<ast::Expr>) -> ast::Expr {
477         match self {
478             FlowKind::Return(_) => make::expr_return(expr),
479             FlowKind::Break(label, _) => make::expr_break(label.clone(), expr),
480             FlowKind::Try { .. } => {
481                 stdx::never!("cannot have result handler with try");
482                 expr.unwrap_or_else(|| make::expr_return(None))
483             }
484             FlowKind::Continue(label) => {
485                 stdx::always!(expr.is_none(), "continue with value is not possible");
486                 make::expr_continue(label.clone())
487             }
488         }
489     }
490
491     fn expr_ty(&self, ctx: &AssistContext<'_>) -> Option<hir::Type> {
492         match self {
493             FlowKind::Return(Some(expr)) | FlowKind::Break(_, Some(expr)) => {
494                 ctx.sema.type_of_expr(expr).map(TypeInfo::adjusted)
495             }
496             FlowKind::Try { .. } => {
497                 stdx::never!("try does not have defined expr_ty");
498                 None
499             }
500             _ => None,
501         }
502     }
503 }
504
505 impl FunctionBody {
506     fn parent(&self) -> Option<SyntaxNode> {
507         match self {
508             FunctionBody::Expr(expr) => expr.syntax().parent(),
509             FunctionBody::Span { parent, .. } => Some(parent.syntax().clone()),
510         }
511     }
512
513     fn node(&self) -> &SyntaxNode {
514         match self {
515             FunctionBody::Expr(e) => e.syntax(),
516             FunctionBody::Span { parent, .. } => parent.syntax(),
517         }
518     }
519
520     fn extracted_from_trait_impl(&self) -> bool {
521         match self.node().ancestors().find_map(ast::Impl::cast) {
522             Some(c) => return c.trait_().is_some(),
523             None => false,
524         }
525     }
526
527     fn descendants(&self) -> impl Iterator<Item = SyntaxNode> {
528         match self {
529             FunctionBody::Expr(expr) => expr.syntax().descendants(),
530             FunctionBody::Span { parent, .. } => parent.syntax().descendants(),
531         }
532     }
533
534     fn descendant_paths(&self) -> impl Iterator<Item = ast::Path> {
535         self.descendants().filter_map(|node| {
536             match_ast! {
537                 match node {
538                     ast::Path(it) => Some(it),
539                     _ => None
540                 }
541             }
542         })
543     }
544
545     fn from_expr(expr: ast::Expr) -> Option<Self> {
546         match expr {
547             ast::Expr::BreakExpr(it) => it.expr().map(Self::Expr),
548             ast::Expr::ReturnExpr(it) => it.expr().map(Self::Expr),
549             ast::Expr::BlockExpr(it) if !it.is_standalone() => None,
550             expr => Some(Self::Expr(expr)),
551         }
552     }
553
554     fn from_range(parent: ast::StmtList, selected: TextRange) -> FunctionBody {
555         let full_body = parent.syntax().children_with_tokens();
556
557         let mut text_range = full_body
558             .filter(|it| ast::Stmt::can_cast(it.kind()) || it.kind() == COMMENT)
559             .map(|element| element.text_range())
560             .filter(|&range| selected.intersect(range).filter(|it| !it.is_empty()).is_some())
561             .reduce(|acc, stmt| acc.cover(stmt));
562
563         if let Some(tail_range) = parent
564             .tail_expr()
565             .map(|it| it.syntax().text_range())
566             .filter(|&it| selected.intersect(it).is_some())
567         {
568             text_range = Some(match text_range {
569                 Some(text_range) => text_range.cover(tail_range),
570                 None => tail_range,
571             });
572         }
573         Self::Span { parent, text_range: text_range.unwrap_or(selected) }
574     }
575
576     fn indent_level(&self) -> IndentLevel {
577         match &self {
578             FunctionBody::Expr(expr) => IndentLevel::from_node(expr.syntax()),
579             FunctionBody::Span { parent, .. } => IndentLevel::from_node(parent.syntax()) + 1,
580         }
581     }
582
583     fn tail_expr(&self) -> Option<ast::Expr> {
584         match &self {
585             FunctionBody::Expr(expr) => Some(expr.clone()),
586             FunctionBody::Span { parent, text_range } => {
587                 let tail_expr = parent.tail_expr()?;
588                 text_range.contains_range(tail_expr.syntax().text_range()).then(|| tail_expr)
589             }
590         }
591     }
592
593     fn walk_expr(&self, cb: &mut dyn FnMut(ast::Expr)) {
594         match self {
595             FunctionBody::Expr(expr) => walk_expr(expr, cb),
596             FunctionBody::Span { parent, text_range } => {
597                 parent
598                     .statements()
599                     .filter(|stmt| text_range.contains_range(stmt.syntax().text_range()))
600                     .filter_map(|stmt| match stmt {
601                         ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr(),
602                         ast::Stmt::Item(_) => None,
603                         ast::Stmt::LetStmt(stmt) => stmt.initializer(),
604                     })
605                     .for_each(|expr| walk_expr(&expr, cb));
606                 if let Some(expr) = parent
607                     .tail_expr()
608                     .filter(|it| text_range.contains_range(it.syntax().text_range()))
609                 {
610                     walk_expr(&expr, cb);
611                 }
612             }
613         }
614     }
615
616     fn preorder_expr(&self, cb: &mut dyn FnMut(WalkEvent<ast::Expr>) -> bool) {
617         match self {
618             FunctionBody::Expr(expr) => preorder_expr(expr, cb),
619             FunctionBody::Span { parent, text_range } => {
620                 parent
621                     .statements()
622                     .filter(|stmt| text_range.contains_range(stmt.syntax().text_range()))
623                     .filter_map(|stmt| match stmt {
624                         ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr(),
625                         ast::Stmt::Item(_) => None,
626                         ast::Stmt::LetStmt(stmt) => stmt.initializer(),
627                     })
628                     .for_each(|expr| preorder_expr(&expr, cb));
629                 if let Some(expr) = parent
630                     .tail_expr()
631                     .filter(|it| text_range.contains_range(it.syntax().text_range()))
632                 {
633                     preorder_expr(&expr, cb);
634                 }
635             }
636         }
637     }
638
639     fn walk_pat(&self, cb: &mut dyn FnMut(ast::Pat)) {
640         match self {
641             FunctionBody::Expr(expr) => walk_patterns_in_expr(expr, cb),
642             FunctionBody::Span { parent, text_range } => {
643                 parent
644                     .statements()
645                     .filter(|stmt| text_range.contains_range(stmt.syntax().text_range()))
646                     .for_each(|stmt| match stmt {
647                         ast::Stmt::ExprStmt(expr_stmt) => {
648                             if let Some(expr) = expr_stmt.expr() {
649                                 walk_patterns_in_expr(&expr, cb)
650                             }
651                         }
652                         ast::Stmt::Item(_) => (),
653                         ast::Stmt::LetStmt(stmt) => {
654                             if let Some(pat) = stmt.pat() {
655                                 walk_pat(&pat, cb);
656                             }
657                             if let Some(expr) = stmt.initializer() {
658                                 walk_patterns_in_expr(&expr, cb);
659                             }
660                         }
661                     });
662                 if let Some(expr) = parent
663                     .tail_expr()
664                     .filter(|it| text_range.contains_range(it.syntax().text_range()))
665                 {
666                     walk_patterns_in_expr(&expr, cb);
667                 }
668             }
669         }
670     }
671
672     fn text_range(&self) -> TextRange {
673         match self {
674             FunctionBody::Expr(expr) => expr.syntax().text_range(),
675             &FunctionBody::Span { text_range, .. } => text_range,
676         }
677     }
678
679     fn contains_range(&self, range: TextRange) -> bool {
680         self.text_range().contains_range(range)
681     }
682
683     fn precedes_range(&self, range: TextRange) -> bool {
684         self.text_range().end() <= range.start()
685     }
686
687     fn contains_node(&self, node: &SyntaxNode) -> bool {
688         self.contains_range(node.text_range())
689     }
690 }
691
692 impl FunctionBody {
693     /// Analyzes a function body, returning the used local variables that are referenced in it as well as
694     /// whether it contains an await expression.
695     fn analyze(
696         &self,
697         sema: &Semantics<'_, RootDatabase>,
698     ) -> (FxIndexSet<Local>, Option<ast::SelfParam>) {
699         let mut self_param = None;
700         let mut res = FxIndexSet::default();
701         let mut cb = |name_ref: Option<_>| {
702             let local_ref =
703                 match name_ref.and_then(|name_ref| NameRefClass::classify(sema, &name_ref)) {
704                     Some(
705                         NameRefClass::Definition(Definition::Local(local_ref))
706                         | NameRefClass::FieldShorthand { local_ref, field_ref: _ },
707                     ) => local_ref,
708                     _ => return,
709                 };
710             let InFile { file_id, value } = local_ref.source(sema.db);
711             // locals defined inside macros are not relevant to us
712             if !file_id.is_macro() {
713                 match value {
714                     Either::Right(it) => {
715                         self_param.replace(it);
716                     }
717                     Either::Left(_) => {
718                         res.insert(local_ref);
719                     }
720                 }
721             }
722         };
723         self.walk_expr(&mut |expr| match expr {
724             ast::Expr::PathExpr(path_expr) => {
725                 cb(path_expr.path().and_then(|it| it.as_single_name_ref()))
726             }
727             ast::Expr::ClosureExpr(closure_expr) => {
728                 if let Some(body) = closure_expr.body() {
729                     body.syntax().descendants().map(ast::NameRef::cast).for_each(|it| cb(it));
730                 }
731             }
732             ast::Expr::MacroExpr(expr) => {
733                 if let Some(tt) = expr.macro_call().and_then(|call| call.token_tree()) {
734                     tt.syntax()
735                         .children_with_tokens()
736                         .flat_map(SyntaxElement::into_token)
737                         .filter(|it| it.kind() == SyntaxKind::IDENT)
738                         .flat_map(|t| sema.descend_into_macros(t))
739                         .for_each(|t| cb(t.parent().and_then(ast::NameRef::cast)));
740                 }
741             }
742             _ => (),
743         });
744         (res, self_param)
745     }
746
747     fn analyze_container(&self, sema: &Semantics<'_, RootDatabase>) -> Option<ContainerInfo> {
748         let mut ancestors = self.parent()?.ancestors();
749         let infer_expr_opt = |expr| sema.type_of_expr(&expr?).map(TypeInfo::adjusted);
750         let mut parent_loop = None;
751         let mut set_parent_loop = |loop_: &dyn ast::HasLoopBody| {
752             if loop_
753                 .loop_body()
754                 .map_or(false, |it| it.syntax().text_range().contains_range(self.text_range()))
755             {
756                 parent_loop.get_or_insert(loop_.syntax().clone());
757             }
758         };
759
760         let (is_const, expr, ty) = loop {
761             let anc = ancestors.next()?;
762             break match_ast! {
763                 match anc {
764                     ast::ClosureExpr(closure) => (false, closure.body(), infer_expr_opt(closure.body())),
765                     ast::BlockExpr(block_expr) => {
766                         let (constness, block) = match block_expr.modifier() {
767                             Some(ast::BlockModifier::Const(_)) => (true, block_expr),
768                             Some(ast::BlockModifier::Try(_)) => (false, block_expr),
769                             Some(ast::BlockModifier::Label(label)) if label.lifetime().is_some() => (false, block_expr),
770                             _ => continue,
771                         };
772                         let expr = Some(ast::Expr::BlockExpr(block));
773                         (constness, expr.clone(), infer_expr_opt(expr))
774                     },
775                     ast::Fn(fn_) => {
776                         let func = sema.to_def(&fn_)?;
777                         let mut ret_ty = func.ret_type(sema.db);
778                         if func.is_async(sema.db) {
779                             if let Some(async_ret) = func.async_ret_type(sema.db) {
780                                 ret_ty = async_ret;
781                             }
782                         }
783                         (fn_.const_token().is_some(), fn_.body().map(ast::Expr::BlockExpr), Some(ret_ty))
784                     },
785                     ast::Static(statik) => {
786                         (true, statik.body(), Some(sema.to_def(&statik)?.ty(sema.db)))
787                     },
788                     ast::ConstArg(ca) => {
789                         (true, ca.expr(), infer_expr_opt(ca.expr()))
790                     },
791                     ast::Const(konst) => {
792                         (true, konst.body(), Some(sema.to_def(&konst)?.ty(sema.db)))
793                     },
794                     ast::ConstParam(cp) => {
795                         (true, cp.default_val(), Some(sema.to_def(&cp)?.ty(sema.db)))
796                     },
797                     ast::ConstBlockPat(cbp) => {
798                         let expr = cbp.block_expr().map(ast::Expr::BlockExpr);
799                         (true, expr.clone(), infer_expr_opt(expr))
800                     },
801                     ast::Variant(__) => return None,
802                     ast::Meta(__) => return None,
803                     ast::LoopExpr(it) => {
804                         set_parent_loop(&it);
805                         continue;
806                     },
807                     ast::ForExpr(it) => {
808                         set_parent_loop(&it);
809                         continue;
810                     },
811                     ast::WhileExpr(it) => {
812                         set_parent_loop(&it);
813                         continue;
814                     },
815                     _ => continue,
816                 }
817             };
818         };
819         let container_tail = match expr? {
820             ast::Expr::BlockExpr(block) => block.tail_expr(),
821             expr => Some(expr),
822         };
823         let is_in_tail =
824             container_tail.zip(self.tail_expr()).map_or(false, |(container_tail, body_tail)| {
825                 container_tail.syntax().text_range().contains_range(body_tail.syntax().text_range())
826             });
827
828         let parent = self.parent()?;
829         let parents = generic_parents(&parent);
830         let generic_param_lists = parents.iter().filter_map(|it| it.generic_param_list()).collect();
831         let where_clauses = parents.iter().filter_map(|it| it.where_clause()).collect();
832
833         Some(ContainerInfo {
834             is_in_tail,
835             is_const,
836             parent_loop,
837             ret_type: ty,
838             generic_param_lists,
839             where_clauses,
840         })
841     }
842
843     fn return_ty(&self, ctx: &AssistContext<'_>) -> Option<RetType> {
844         match self.tail_expr() {
845             Some(expr) => ctx.sema.type_of_expr(&expr).map(TypeInfo::original).map(RetType::Expr),
846             None => Some(RetType::Stmt),
847         }
848     }
849
850     /// Local variables defined inside `body` that are accessed outside of it
851     fn ret_values<'a>(
852         &self,
853         ctx: &'a AssistContext<'_>,
854         parent: &SyntaxNode,
855     ) -> impl Iterator<Item = OutlivedLocal> + 'a {
856         let parent = parent.clone();
857         let range = self.text_range();
858         locals_defined_in_body(&ctx.sema, self)
859             .into_iter()
860             .filter_map(move |local| local_outlives_body(ctx, range, local, &parent))
861     }
862
863     /// Analyses the function body for external control flow.
864     fn external_control_flow(
865         &self,
866         ctx: &AssistContext<'_>,
867         container_info: &ContainerInfo,
868     ) -> Option<ControlFlow> {
869         let mut ret_expr = None;
870         let mut try_expr = None;
871         let mut break_expr = None;
872         let mut continue_expr = None;
873         let mut is_async = false;
874         let mut _is_unsafe = false;
875
876         let mut unsafe_depth = 0;
877         let mut loop_depth = 0;
878
879         self.preorder_expr(&mut |expr| {
880             let expr = match expr {
881                 WalkEvent::Enter(e) => e,
882                 WalkEvent::Leave(expr) => {
883                     match expr {
884                         ast::Expr::LoopExpr(_)
885                         | ast::Expr::ForExpr(_)
886                         | ast::Expr::WhileExpr(_) => loop_depth -= 1,
887                         ast::Expr::BlockExpr(block_expr) if block_expr.unsafe_token().is_some() => {
888                             unsafe_depth -= 1
889                         }
890                         _ => (),
891                     }
892                     return false;
893                 }
894             };
895             match expr {
896                 ast::Expr::LoopExpr(_) | ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) => {
897                     loop_depth += 1;
898                 }
899                 ast::Expr::BlockExpr(block_expr) if block_expr.unsafe_token().is_some() => {
900                     unsafe_depth += 1
901                 }
902                 ast::Expr::ReturnExpr(it) => {
903                     ret_expr = Some(it);
904                 }
905                 ast::Expr::TryExpr(it) => {
906                     try_expr = Some(it);
907                 }
908                 ast::Expr::BreakExpr(it) if loop_depth == 0 => {
909                     break_expr = Some(it);
910                 }
911                 ast::Expr::ContinueExpr(it) if loop_depth == 0 => {
912                     continue_expr = Some(it);
913                 }
914                 ast::Expr::AwaitExpr(_) => is_async = true,
915                 // FIXME: Do unsafe analysis on expression, sem highlighting knows this so we should be able
916                 // to just lift that out of there
917                 // expr if unsafe_depth ==0 && expr.is_unsafe => is_unsafe = true,
918                 _ => {}
919             }
920             false
921         });
922
923         let kind = match (try_expr, ret_expr, break_expr, continue_expr) {
924             (Some(_), _, None, None) => {
925                 let ret_ty = container_info.ret_type.clone()?;
926                 let kind = TryKind::of_ty(ret_ty, ctx)?;
927
928                 Some(FlowKind::Try { kind })
929             }
930             (Some(_), _, _, _) => {
931                 cov_mark::hit!(external_control_flow_try_and_bc);
932                 return None;
933             }
934             (None, Some(r), None, None) => Some(FlowKind::Return(r.expr())),
935             (None, Some(_), _, _) => {
936                 cov_mark::hit!(external_control_flow_return_and_bc);
937                 return None;
938             }
939             (None, None, Some(_), Some(_)) => {
940                 cov_mark::hit!(external_control_flow_break_and_continue);
941                 return None;
942             }
943             (None, None, Some(b), None) => Some(FlowKind::Break(b.lifetime(), b.expr())),
944             (None, None, None, Some(c)) => Some(FlowKind::Continue(c.lifetime())),
945             (None, None, None, None) => None,
946         };
947
948         Some(ControlFlow { kind, is_async, is_unsafe: _is_unsafe })
949     }
950
951     /// find variables that should be extracted as params
952     ///
953     /// Computes additional info that affects param type and mutability
954     fn extracted_function_params(
955         &self,
956         ctx: &AssistContext<'_>,
957         container_info: &ContainerInfo,
958         locals: impl Iterator<Item = Local>,
959     ) -> Vec<Param> {
960         locals
961             .map(|local| (local, local.source(ctx.db())))
962             .filter(|(_, src)| is_defined_outside_of_body(ctx, self, src))
963             .filter_map(|(local, src)| match src.value {
964                 Either::Left(src) => Some((local, src)),
965                 Either::Right(_) => {
966                     stdx::never!(false, "Local::is_self returned false, but source is SelfParam");
967                     None
968                 }
969             })
970             .map(|(var, src)| {
971                 let usages = LocalUsages::find_local_usages(ctx, var);
972                 let ty = var.ty(ctx.db());
973
974                 let defined_outside_parent_loop = container_info
975                     .parent_loop
976                     .as_ref()
977                     .map_or(true, |it| it.text_range().contains_range(src.syntax().text_range()));
978
979                 let is_copy = ty.is_copy(ctx.db());
980                 let has_usages = self.has_usages_after_body(&usages);
981                 let requires_mut =
982                     !ty.is_mutable_reference() && has_exclusive_usages(ctx, &usages, self);
983                 // We can move the value into the function call if it's not used after the call,
984                 // if the var is not used but defined outside a loop we are extracting from we can't move it either
985                 // as the function will reuse it in the next iteration.
986                 let move_local = (!has_usages && defined_outside_parent_loop) || ty.is_reference();
987                 Param { var, ty, move_local, requires_mut, is_copy }
988             })
989             .collect()
990     }
991
992     fn has_usages_after_body(&self, usages: &LocalUsages) -> bool {
993         usages.iter().any(|reference| self.precedes_range(reference.range))
994     }
995 }
996
997 enum GenericParent {
998     Fn(ast::Fn),
999     Impl(ast::Impl),
1000     Trait(ast::Trait),
1001 }
1002
1003 impl GenericParent {
1004     fn generic_param_list(&self) -> Option<ast::GenericParamList> {
1005         match self {
1006             GenericParent::Fn(fn_) => fn_.generic_param_list(),
1007             GenericParent::Impl(impl_) => impl_.generic_param_list(),
1008             GenericParent::Trait(trait_) => trait_.generic_param_list(),
1009         }
1010     }
1011
1012     fn where_clause(&self) -> Option<ast::WhereClause> {
1013         match self {
1014             GenericParent::Fn(fn_) => fn_.where_clause(),
1015             GenericParent::Impl(impl_) => impl_.where_clause(),
1016             GenericParent::Trait(trait_) => trait_.where_clause(),
1017         }
1018     }
1019 }
1020
1021 /// Search `parent`'s ancestors for items with potentially applicable generic parameters
1022 fn generic_parents(parent: &SyntaxNode) -> Vec<GenericParent> {
1023     let mut list = Vec::new();
1024     if let Some(parent_item) = parent.ancestors().find_map(ast::Item::cast) {
1025         match parent_item {
1026             ast::Item::Fn(ref fn_) => {
1027                 if let Some(parent_parent) = parent_item
1028                     .syntax()
1029                     .parent()
1030                     .and_then(|it| it.parent())
1031                     .and_then(ast::Item::cast)
1032                 {
1033                     match parent_parent {
1034                         ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)),
1035                         ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)),
1036                         _ => (),
1037                     }
1038                 }
1039                 list.push(GenericParent::Fn(fn_.clone()));
1040             }
1041             _ => (),
1042         }
1043     }
1044     list
1045 }
1046
1047 /// checks if relevant var is used with `&mut` access inside body
1048 fn has_exclusive_usages(
1049     ctx: &AssistContext<'_>,
1050     usages: &LocalUsages,
1051     body: &FunctionBody,
1052 ) -> bool {
1053     usages
1054         .iter()
1055         .filter(|reference| body.contains_range(reference.range))
1056         .any(|reference| reference_is_exclusive(reference, body, ctx))
1057 }
1058
1059 /// checks if this reference requires `&mut` access inside node
1060 fn reference_is_exclusive(
1061     reference: &FileReference,
1062     node: &dyn HasTokenAtOffset,
1063     ctx: &AssistContext<'_>,
1064 ) -> bool {
1065     // we directly modify variable with set: `n = 0`, `n += 1`
1066     if reference.category == Some(ReferenceCategory::Write) {
1067         return true;
1068     }
1069
1070     // we take `&mut` reference to variable: `&mut v`
1071     let path = match path_element_of_reference(node, reference) {
1072         Some(path) => path,
1073         None => return false,
1074     };
1075
1076     expr_require_exclusive_access(ctx, &path).unwrap_or(false)
1077 }
1078
1079 /// checks if this expr requires `&mut` access, recurses on field access
1080 fn expr_require_exclusive_access(ctx: &AssistContext<'_>, expr: &ast::Expr) -> Option<bool> {
1081     if let ast::Expr::MacroExpr(_) = expr {
1082         // FIXME: expand macro and check output for mutable usages of the variable?
1083         return None;
1084     }
1085
1086     let parent = expr.syntax().parent()?;
1087
1088     if let Some(bin_expr) = ast::BinExpr::cast(parent.clone()) {
1089         if matches!(bin_expr.op_kind()?, ast::BinaryOp::Assignment { .. }) {
1090             return Some(bin_expr.lhs()?.syntax() == expr.syntax());
1091         }
1092         return Some(false);
1093     }
1094
1095     if let Some(ref_expr) = ast::RefExpr::cast(parent.clone()) {
1096         return Some(ref_expr.mut_token().is_some());
1097     }
1098
1099     if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
1100         let func = ctx.sema.resolve_method_call(&method_call)?;
1101         let self_param = func.self_param(ctx.db())?;
1102         let access = self_param.access(ctx.db());
1103
1104         return Some(matches!(access, hir::Access::Exclusive));
1105     }
1106
1107     if let Some(field) = ast::FieldExpr::cast(parent) {
1108         return expr_require_exclusive_access(ctx, &field.into());
1109     }
1110
1111     Some(false)
1112 }
1113
1114 trait HasTokenAtOffset {
1115     fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken>;
1116 }
1117
1118 impl HasTokenAtOffset for SyntaxNode {
1119     fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
1120         SyntaxNode::token_at_offset(self, offset)
1121     }
1122 }
1123
1124 impl HasTokenAtOffset for FunctionBody {
1125     fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
1126         match self {
1127             FunctionBody::Expr(expr) => expr.syntax().token_at_offset(offset),
1128             FunctionBody::Span { parent, text_range } => {
1129                 match parent.syntax().token_at_offset(offset) {
1130                     TokenAtOffset::None => TokenAtOffset::None,
1131                     TokenAtOffset::Single(t) => {
1132                         if text_range.contains_range(t.text_range()) {
1133                             TokenAtOffset::Single(t)
1134                         } else {
1135                             TokenAtOffset::None
1136                         }
1137                     }
1138                     TokenAtOffset::Between(a, b) => {
1139                         match (
1140                             text_range.contains_range(a.text_range()),
1141                             text_range.contains_range(b.text_range()),
1142                         ) {
1143                             (true, true) => TokenAtOffset::Between(a, b),
1144                             (true, false) => TokenAtOffset::Single(a),
1145                             (false, true) => TokenAtOffset::Single(b),
1146                             (false, false) => TokenAtOffset::None,
1147                         }
1148                     }
1149                 }
1150             }
1151         }
1152     }
1153 }
1154
1155 /// find relevant `ast::Expr` for reference
1156 ///
1157 /// # Preconditions
1158 ///
1159 /// `node` must cover `reference`, that is `node.text_range().contains_range(reference.range)`
1160 fn path_element_of_reference(
1161     node: &dyn HasTokenAtOffset,
1162     reference: &FileReference,
1163 ) -> Option<ast::Expr> {
1164     let token = node.token_at_offset(reference.range.start()).right_biased().or_else(|| {
1165         stdx::never!(false, "cannot find token at variable usage: {:?}", reference);
1166         None
1167     })?;
1168     let path = token.parent_ancestors().find_map(ast::Expr::cast).or_else(|| {
1169         stdx::never!(false, "cannot find path parent of variable usage: {:?}", token);
1170         None
1171     })?;
1172     stdx::always!(
1173         matches!(path, ast::Expr::PathExpr(_) | ast::Expr::MacroExpr(_)),
1174         "unexpected expression type for variable usage: {:?}",
1175         path
1176     );
1177     Some(path)
1178 }
1179
1180 /// list local variables defined inside `body`
1181 fn locals_defined_in_body(
1182     sema: &Semantics<'_, RootDatabase>,
1183     body: &FunctionBody,
1184 ) -> FxIndexSet<Local> {
1185     // FIXME: this doesn't work well with macros
1186     //        see https://github.com/rust-lang/rust-analyzer/pull/7535#discussion_r570048550
1187     let mut res = FxIndexSet::default();
1188     body.walk_pat(&mut |pat| {
1189         if let ast::Pat::IdentPat(pat) = pat {
1190             if let Some(local) = sema.to_def(&pat) {
1191                 res.insert(local);
1192             }
1193         }
1194     });
1195     res
1196 }
1197
1198 /// Returns usage details if local variable is used after(outside of) body
1199 fn local_outlives_body(
1200     ctx: &AssistContext<'_>,
1201     body_range: TextRange,
1202     local: Local,
1203     parent: &SyntaxNode,
1204 ) -> Option<OutlivedLocal> {
1205     let usages = LocalUsages::find_local_usages(ctx, local);
1206     let mut has_mut_usages = false;
1207     let mut any_outlives = false;
1208     for usage in usages.iter() {
1209         if body_range.end() <= usage.range.start() {
1210             has_mut_usages |= reference_is_exclusive(usage, parent, ctx);
1211             any_outlives |= true;
1212             if has_mut_usages {
1213                 break; // no need to check more elements we have all the info we wanted
1214             }
1215         }
1216     }
1217     if !any_outlives {
1218         return None;
1219     }
1220     Some(OutlivedLocal { local, mut_usage_outside_body: has_mut_usages })
1221 }
1222
1223 /// checks if the relevant local was defined before(outside of) body
1224 fn is_defined_outside_of_body(
1225     ctx: &AssistContext<'_>,
1226     body: &FunctionBody,
1227     src: &hir::InFile<Either<ast::IdentPat, ast::SelfParam>>,
1228 ) -> bool {
1229     src.file_id.original_file(ctx.db()) == ctx.file_id()
1230         && !body.contains_node(either_syntax(&src.value))
1231 }
1232
1233 fn either_syntax(value: &Either<ast::IdentPat, ast::SelfParam>) -> &SyntaxNode {
1234     match value {
1235         Either::Left(pat) => pat.syntax(),
1236         Either::Right(it) => it.syntax(),
1237     }
1238 }
1239
1240 /// find where to put extracted function definition
1241 ///
1242 /// Function should be put right after returned node
1243 fn node_to_insert_after(body: &FunctionBody, anchor: Anchor) -> Option<SyntaxNode> {
1244     let node = body.node();
1245     let mut ancestors = node.ancestors().peekable();
1246     let mut last_ancestor = None;
1247     while let Some(next_ancestor) = ancestors.next() {
1248         match next_ancestor.kind() {
1249             SyntaxKind::SOURCE_FILE => break,
1250             SyntaxKind::IMPL => {
1251                 if body.extracted_from_trait_impl() && matches!(anchor, Anchor::Method) {
1252                     let impl_node = find_non_trait_impl(&next_ancestor);
1253                     let target_node = impl_node.as_ref().and_then(last_impl_member);
1254                     if target_node.is_some() {
1255                         return target_node;
1256                     }
1257                 }
1258             }
1259             SyntaxKind::ITEM_LIST if !matches!(anchor, Anchor::Freestanding) => continue,
1260             SyntaxKind::ITEM_LIST => {
1261                 if ancestors.peek().map(SyntaxNode::kind) == Some(SyntaxKind::MODULE) {
1262                     break;
1263                 }
1264             }
1265             SyntaxKind::ASSOC_ITEM_LIST if !matches!(anchor, Anchor::Method) => continue,
1266             SyntaxKind::ASSOC_ITEM_LIST if body.extracted_from_trait_impl() => continue,
1267             SyntaxKind::ASSOC_ITEM_LIST => {
1268                 if ancestors.peek().map(SyntaxNode::kind) == Some(SyntaxKind::IMPL) {
1269                     break;
1270                 }
1271             }
1272             _ => (),
1273         }
1274         last_ancestor = Some(next_ancestor);
1275     }
1276     last_ancestor
1277 }
1278
1279 fn find_non_trait_impl(trait_impl: &SyntaxNode) -> Option<SyntaxNode> {
1280     let impl_type = Some(impl_type_name(trait_impl)?);
1281
1282     let mut sibblings = trait_impl.parent()?.children();
1283     sibblings.find(|s| impl_type_name(s) == impl_type && !is_trait_impl(s))
1284 }
1285
1286 fn last_impl_member(impl_node: &SyntaxNode) -> Option<SyntaxNode> {
1287     impl_node.children().find(|c| c.kind() == SyntaxKind::ASSOC_ITEM_LIST)?.last_child()
1288 }
1289
1290 fn is_trait_impl(node: &SyntaxNode) -> bool {
1291     if !ast::Impl::can_cast(node.kind()) {
1292         return false;
1293     }
1294     match ast::Impl::cast(node.clone()) {
1295         Some(c) => c.trait_().is_some(),
1296         None => false,
1297     }
1298 }
1299
1300 fn impl_type_name(impl_node: &SyntaxNode) -> Option<String> {
1301     if !ast::Impl::can_cast(impl_node.kind()) {
1302         return None;
1303     }
1304     Some(ast::Impl::cast(impl_node.clone())?.self_ty()?.to_string())
1305 }
1306
1307 fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> String {
1308     let ret_ty = fun.return_type(ctx);
1309
1310     let args = make::arg_list(fun.params.iter().map(|param| param.to_arg(ctx)));
1311     let name = fun.name.clone();
1312     let mut call_expr = if fun.self_param.is_some() {
1313         let self_arg = make::expr_path(make::ext::ident_path("self"));
1314         make::expr_method_call(self_arg, name, args)
1315     } else {
1316         let func = make::expr_path(make::path_unqualified(make::path_segment(name)));
1317         make::expr_call(func, args)
1318     };
1319
1320     let handler = FlowHandler::from_ret_ty(fun, &ret_ty);
1321
1322     if fun.control_flow.is_async {
1323         call_expr = make::expr_await(call_expr);
1324     }
1325     let expr = handler.make_call_expr(call_expr).indent(indent);
1326
1327     let mut_modifier = |var: &OutlivedLocal| if var.mut_usage_outside_body { "mut " } else { "" };
1328
1329     let mut buf = String::new();
1330     match fun.outliving_locals.as_slice() {
1331         [] => {}
1332         [var] => {
1333             format_to!(buf, "let {}{} = ", mut_modifier(var), var.local.name(ctx.db()))
1334         }
1335         vars => {
1336             buf.push_str("let (");
1337             let bindings = vars.iter().format_with(", ", |local, f| {
1338                 f(&format_args!("{}{}", mut_modifier(local), local.local.name(ctx.db())))
1339             });
1340             format_to!(buf, "{}", bindings);
1341             buf.push_str(") = ");
1342         }
1343     }
1344
1345     format_to!(buf, "{}", expr);
1346     let insert_comma = fun
1347         .body
1348         .parent()
1349         .and_then(ast::MatchArm::cast)
1350         .map_or(false, |it| it.comma_token().is_none());
1351     if insert_comma {
1352         buf.push(',');
1353     } else if fun.ret_ty.is_unit() && (!fun.outliving_locals.is_empty() || !expr.is_block_like()) {
1354         buf.push(';');
1355     }
1356     buf
1357 }
1358
1359 enum FlowHandler {
1360     None,
1361     Try { kind: TryKind },
1362     If { action: FlowKind },
1363     IfOption { action: FlowKind },
1364     MatchOption { none: FlowKind },
1365     MatchResult { err: FlowKind },
1366 }
1367
1368 impl FlowHandler {
1369     fn from_ret_ty(fun: &Function, ret_ty: &FunType) -> FlowHandler {
1370         match &fun.control_flow.kind {
1371             None => FlowHandler::None,
1372             Some(flow_kind) => {
1373                 let action = flow_kind.clone();
1374                 if *ret_ty == FunType::Unit {
1375                     match flow_kind {
1376                         FlowKind::Return(None)
1377                         | FlowKind::Break(_, None)
1378                         | FlowKind::Continue(_) => FlowHandler::If { action },
1379                         FlowKind::Return(_) | FlowKind::Break(_, _) => {
1380                             FlowHandler::IfOption { action }
1381                         }
1382                         FlowKind::Try { kind } => FlowHandler::Try { kind: kind.clone() },
1383                     }
1384                 } else {
1385                     match flow_kind {
1386                         FlowKind::Return(None)
1387                         | FlowKind::Break(_, None)
1388                         | FlowKind::Continue(_) => FlowHandler::MatchOption { none: action },
1389                         FlowKind::Return(_) | FlowKind::Break(_, _) => {
1390                             FlowHandler::MatchResult { err: action }
1391                         }
1392                         FlowKind::Try { kind } => FlowHandler::Try { kind: kind.clone() },
1393                     }
1394                 }
1395             }
1396         }
1397     }
1398
1399     fn make_call_expr(&self, call_expr: ast::Expr) -> ast::Expr {
1400         match self {
1401             FlowHandler::None => call_expr,
1402             FlowHandler::Try { kind: _ } => make::expr_try(call_expr),
1403             FlowHandler::If { action } => {
1404                 let action = action.make_result_handler(None);
1405                 let stmt = make::expr_stmt(action);
1406                 let block = make::block_expr(iter::once(stmt.into()), None);
1407                 let controlflow_break_path = make::path_from_text("ControlFlow::Break");
1408                 let condition = make::expr_let(
1409                     make::tuple_struct_pat(
1410                         controlflow_break_path,
1411                         iter::once(make::wildcard_pat().into()),
1412                     )
1413                     .into(),
1414                     call_expr,
1415                 );
1416                 make::expr_if(condition.into(), block, None)
1417             }
1418             FlowHandler::IfOption { action } => {
1419                 let path = make::ext::ident_path("Some");
1420                 let value_pat = make::ext::simple_ident_pat(make::name("value"));
1421                 let pattern = make::tuple_struct_pat(path, iter::once(value_pat.into()));
1422                 let cond = make::expr_let(pattern.into(), call_expr);
1423                 let value = make::expr_path(make::ext::ident_path("value"));
1424                 let action_expr = action.make_result_handler(Some(value));
1425                 let action_stmt = make::expr_stmt(action_expr);
1426                 let then = make::block_expr(iter::once(action_stmt.into()), None);
1427                 make::expr_if(cond.into(), then, None)
1428             }
1429             FlowHandler::MatchOption { none } => {
1430                 let some_name = "value";
1431
1432                 let some_arm = {
1433                     let path = make::ext::ident_path("Some");
1434                     let value_pat = make::ext::simple_ident_pat(make::name(some_name));
1435                     let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
1436                     let value = make::expr_path(make::ext::ident_path(some_name));
1437                     make::match_arm(iter::once(pat.into()), None, value)
1438                 };
1439                 let none_arm = {
1440                     let path = make::ext::ident_path("None");
1441                     let pat = make::path_pat(path);
1442                     make::match_arm(iter::once(pat), None, none.make_result_handler(None))
1443                 };
1444                 let arms = make::match_arm_list(vec![some_arm, none_arm]);
1445                 make::expr_match(call_expr, arms)
1446             }
1447             FlowHandler::MatchResult { err } => {
1448                 let ok_name = "value";
1449                 let err_name = "value";
1450
1451                 let ok_arm = {
1452                     let path = make::ext::ident_path("Ok");
1453                     let value_pat = make::ext::simple_ident_pat(make::name(ok_name));
1454                     let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
1455                     let value = make::expr_path(make::ext::ident_path(ok_name));
1456                     make::match_arm(iter::once(pat.into()), None, value)
1457                 };
1458                 let err_arm = {
1459                     let path = make::ext::ident_path("Err");
1460                     let value_pat = make::ext::simple_ident_pat(make::name(err_name));
1461                     let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
1462                     let value = make::expr_path(make::ext::ident_path(err_name));
1463                     make::match_arm(
1464                         iter::once(pat.into()),
1465                         None,
1466                         err.make_result_handler(Some(value)),
1467                     )
1468                 };
1469                 let arms = make::match_arm_list(vec![ok_arm, err_arm]);
1470                 make::expr_match(call_expr, arms)
1471             }
1472         }
1473     }
1474 }
1475
1476 fn path_expr_from_local(ctx: &AssistContext<'_>, var: Local) -> ast::Expr {
1477     let name = var.name(ctx.db()).to_string();
1478     make::expr_path(make::ext::ident_path(&name))
1479 }
1480
1481 fn format_function(
1482     ctx: &AssistContext<'_>,
1483     module: hir::Module,
1484     fun: &Function,
1485     old_indent: IndentLevel,
1486     new_indent: IndentLevel,
1487 ) -> String {
1488     let mut fn_def = String::new();
1489     let params = fun.make_param_list(ctx, module);
1490     let ret_ty = fun.make_ret_ty(ctx, module);
1491     let body = make_body(ctx, old_indent, new_indent, fun);
1492     let const_kw = if fun.mods.is_const { "const " } else { "" };
1493     let async_kw = if fun.control_flow.is_async { "async " } else { "" };
1494     let unsafe_kw = if fun.control_flow.is_unsafe { "unsafe " } else { "" };
1495     let (generic_params, where_clause) = make_generic_params_and_where_clause(ctx, fun);
1496     match ctx.config.snippet_cap {
1497         Some(_) => format_to!(
1498             fn_def,
1499             "\n\n{}{}{}{}fn $0{}",
1500             new_indent,
1501             const_kw,
1502             async_kw,
1503             unsafe_kw,
1504             fun.name,
1505         ),
1506         None => format_to!(
1507             fn_def,
1508             "\n\n{}{}{}{}fn {}",
1509             new_indent,
1510             const_kw,
1511             async_kw,
1512             unsafe_kw,
1513             fun.name,
1514         ),
1515     }
1516
1517     if let Some(generic_params) = generic_params {
1518         format_to!(fn_def, "{}", generic_params);
1519     }
1520
1521     format_to!(fn_def, "{}", params);
1522
1523     if let Some(ret_ty) = ret_ty {
1524         format_to!(fn_def, " {}", ret_ty);
1525     }
1526
1527     if let Some(where_clause) = where_clause {
1528         format_to!(fn_def, " {}", where_clause);
1529     }
1530
1531     format_to!(fn_def, " {}", body);
1532
1533     fn_def
1534 }
1535
1536 fn make_generic_params_and_where_clause(
1537     ctx: &AssistContext<'_>,
1538     fun: &Function,
1539 ) -> (Option<ast::GenericParamList>, Option<ast::WhereClause>) {
1540     let used_type_params = fun.type_params(ctx);
1541
1542     let generic_param_list = make_generic_param_list(ctx, fun, &used_type_params);
1543     let where_clause = make_where_clause(ctx, fun, &used_type_params);
1544
1545     (generic_param_list, where_clause)
1546 }
1547
1548 fn make_generic_param_list(
1549     ctx: &AssistContext<'_>,
1550     fun: &Function,
1551     used_type_params: &[TypeParam],
1552 ) -> Option<ast::GenericParamList> {
1553     let mut generic_params = fun
1554         .mods
1555         .generic_param_lists
1556         .iter()
1557         .flat_map(|parent_params| {
1558             parent_params
1559                 .generic_params()
1560                 .filter(|param| param_is_required(ctx, param, used_type_params))
1561         })
1562         .peekable();
1563
1564     if generic_params.peek().is_some() {
1565         Some(make::generic_param_list(generic_params))
1566     } else {
1567         None
1568     }
1569 }
1570
1571 fn param_is_required(
1572     ctx: &AssistContext<'_>,
1573     param: &ast::GenericParam,
1574     used_type_params: &[TypeParam],
1575 ) -> bool {
1576     match param {
1577         ast::GenericParam::ConstParam(_) | ast::GenericParam::LifetimeParam(_) => false,
1578         ast::GenericParam::TypeParam(type_param) => match &ctx.sema.to_def(type_param) {
1579             Some(def) => used_type_params.contains(def),
1580             _ => false,
1581         },
1582     }
1583 }
1584
1585 fn make_where_clause(
1586     ctx: &AssistContext<'_>,
1587     fun: &Function,
1588     used_type_params: &[TypeParam],
1589 ) -> Option<ast::WhereClause> {
1590     let mut predicates = fun
1591         .mods
1592         .where_clauses
1593         .iter()
1594         .flat_map(|parent_where_clause| {
1595             parent_where_clause
1596                 .predicates()
1597                 .filter(|pred| pred_is_required(ctx, pred, used_type_params))
1598         })
1599         .peekable();
1600
1601     if predicates.peek().is_some() {
1602         Some(make::where_clause(predicates))
1603     } else {
1604         None
1605     }
1606 }
1607
1608 fn pred_is_required(
1609     ctx: &AssistContext<'_>,
1610     pred: &ast::WherePred,
1611     used_type_params: &[TypeParam],
1612 ) -> bool {
1613     match resolved_type_param(ctx, pred) {
1614         Some(it) => used_type_params.contains(&it),
1615         None => false,
1616     }
1617 }
1618
1619 fn resolved_type_param(ctx: &AssistContext<'_>, pred: &ast::WherePred) -> Option<TypeParam> {
1620     let path = match pred.ty()? {
1621         ast::Type::PathType(path_type) => path_type.path(),
1622         _ => None,
1623     }?;
1624
1625     match ctx.sema.resolve_path(&path)? {
1626         PathResolution::TypeParam(type_param) => Some(type_param),
1627         _ => None,
1628     }
1629 }
1630
1631 impl Function {
1632     /// Collect all the `TypeParam`s used in the `body` and `params`.
1633     fn type_params(&self, ctx: &AssistContext<'_>) -> Vec<TypeParam> {
1634         let type_params_in_descendant_paths =
1635             self.body.descendant_paths().filter_map(|it| match ctx.sema.resolve_path(&it) {
1636                 Some(PathResolution::TypeParam(type_param)) => Some(type_param),
1637                 _ => None,
1638             });
1639         let type_params_in_params = self.params.iter().filter_map(|p| p.ty.as_type_param(ctx.db()));
1640         type_params_in_descendant_paths.chain(type_params_in_params).collect()
1641     }
1642
1643     fn make_param_list(&self, ctx: &AssistContext<'_>, module: hir::Module) -> ast::ParamList {
1644         let self_param = self.self_param.clone();
1645         let params = self.params.iter().map(|param| param.to_param(ctx, module));
1646         make::param_list(self_param, params)
1647     }
1648
1649     fn make_ret_ty(&self, ctx: &AssistContext<'_>, module: hir::Module) -> Option<ast::RetType> {
1650         let fun_ty = self.return_type(ctx);
1651         let handler = if self.mods.is_in_tail {
1652             FlowHandler::None
1653         } else {
1654             FlowHandler::from_ret_ty(self, &fun_ty)
1655         };
1656         let ret_ty = match &handler {
1657             FlowHandler::None => {
1658                 if matches!(fun_ty, FunType::Unit) {
1659                     return None;
1660                 }
1661                 fun_ty.make_ty(ctx, module)
1662             }
1663             FlowHandler::Try { kind: TryKind::Option } => {
1664                 make::ext::ty_option(fun_ty.make_ty(ctx, module))
1665             }
1666             FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => {
1667                 let handler_ty = parent_ret_ty
1668                     .type_arguments()
1669                     .nth(1)
1670                     .map(|ty| make_ty(&ty, ctx, module))
1671                     .unwrap_or_else(make::ty_placeholder);
1672                 make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty)
1673             }
1674             FlowHandler::If { .. } => make::ty("ControlFlow<()>"),
1675             FlowHandler::IfOption { action } => {
1676                 let handler_ty = action
1677                     .expr_ty(ctx)
1678                     .map(|ty| make_ty(&ty, ctx, module))
1679                     .unwrap_or_else(make::ty_placeholder);
1680                 make::ext::ty_option(handler_ty)
1681             }
1682             FlowHandler::MatchOption { .. } => make::ext::ty_option(fun_ty.make_ty(ctx, module)),
1683             FlowHandler::MatchResult { err } => {
1684                 let handler_ty = err
1685                     .expr_ty(ctx)
1686                     .map(|ty| make_ty(&ty, ctx, module))
1687                     .unwrap_or_else(make::ty_placeholder);
1688                 make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty)
1689             }
1690         };
1691         Some(make::ret_type(ret_ty))
1692     }
1693 }
1694
1695 impl FunType {
1696     fn make_ty(&self, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type {
1697         match self {
1698             FunType::Unit => make::ty_unit(),
1699             FunType::Single(ty) => make_ty(ty, ctx, module),
1700             FunType::Tuple(types) => match types.as_slice() {
1701                 [] => {
1702                     stdx::never!("tuple type with 0 elements");
1703                     make::ty_unit()
1704                 }
1705                 [ty] => {
1706                     stdx::never!("tuple type with 1 element");
1707                     make_ty(ty, ctx, module)
1708                 }
1709                 types => {
1710                     let types = types.iter().map(|ty| make_ty(ty, ctx, module));
1711                     make::ty_tuple(types)
1712                 }
1713             },
1714         }
1715     }
1716 }
1717
1718 fn make_body(
1719     ctx: &AssistContext<'_>,
1720     old_indent: IndentLevel,
1721     new_indent: IndentLevel,
1722     fun: &Function,
1723 ) -> ast::BlockExpr {
1724     let ret_ty = fun.return_type(ctx);
1725     let handler = if fun.mods.is_in_tail {
1726         FlowHandler::None
1727     } else {
1728         FlowHandler::from_ret_ty(fun, &ret_ty)
1729     };
1730
1731     let block = match &fun.body {
1732         FunctionBody::Expr(expr) => {
1733             let expr = rewrite_body_segment(ctx, &fun.params, &handler, expr.syntax());
1734             let expr = ast::Expr::cast(expr).unwrap();
1735             match expr {
1736                 ast::Expr::BlockExpr(block) => {
1737                     // If the extracted expression is itself a block, there is no need to wrap it inside another block.
1738                     let block = block.dedent(old_indent);
1739                     // Recreate the block for formatting consistency with other extracted functions.
1740                     make::block_expr(block.statements(), block.tail_expr())
1741                 }
1742                 _ => {
1743                     let expr = expr.dedent(old_indent).indent(IndentLevel(1));
1744
1745                     make::block_expr(Vec::new(), Some(expr))
1746                 }
1747             }
1748         }
1749         FunctionBody::Span { parent, text_range } => {
1750             let mut elements: Vec<_> = parent
1751                 .syntax()
1752                 .children_with_tokens()
1753                 .filter(|it| text_range.contains_range(it.text_range()))
1754                 .map(|it| match &it {
1755                     syntax::NodeOrToken::Node(n) => syntax::NodeOrToken::Node(
1756                         rewrite_body_segment(ctx, &fun.params, &handler, n),
1757                     ),
1758                     _ => it,
1759                 })
1760                 .collect();
1761
1762             let mut tail_expr = match &elements.last() {
1763                 Some(syntax::NodeOrToken::Node(node)) if ast::Expr::can_cast(node.kind()) => {
1764                     ast::Expr::cast(node.clone())
1765                 }
1766                 _ => None,
1767             };
1768
1769             match tail_expr {
1770                 Some(_) => {
1771                     elements.pop();
1772                 }
1773                 None => match fun.outliving_locals.as_slice() {
1774                     [] => {}
1775                     [var] => {
1776                         tail_expr = Some(path_expr_from_local(ctx, var.local));
1777                     }
1778                     vars => {
1779                         let exprs = vars.iter().map(|var| path_expr_from_local(ctx, var.local));
1780                         let expr = make::expr_tuple(exprs);
1781                         tail_expr = Some(expr);
1782                     }
1783                 },
1784             };
1785
1786             let body_indent = IndentLevel(1);
1787             let elements = elements
1788                 .into_iter()
1789                 .map(|node_or_token| match &node_or_token {
1790                     syntax::NodeOrToken::Node(node) => match ast::Stmt::cast(node.clone()) {
1791                         Some(stmt) => {
1792                             let indented = stmt.dedent(old_indent).indent(body_indent);
1793                             let ast_node = indented.syntax().clone_subtree();
1794                             syntax::NodeOrToken::Node(ast_node)
1795                         }
1796                         _ => node_or_token,
1797                     },
1798                     _ => node_or_token,
1799                 })
1800                 .collect::<Vec<SyntaxElement>>();
1801             let tail_expr = tail_expr.map(|expr| expr.dedent(old_indent).indent(body_indent));
1802
1803             make::hacky_block_expr_with_comments(elements, tail_expr)
1804         }
1805     };
1806
1807     let block = match &handler {
1808         FlowHandler::None => block,
1809         FlowHandler::Try { kind } => {
1810             let block = with_default_tail_expr(block, make::expr_unit());
1811             map_tail_expr(block, |tail_expr| {
1812                 let constructor = match kind {
1813                     TryKind::Option => "Some",
1814                     TryKind::Result { .. } => "Ok",
1815                 };
1816                 let func = make::expr_path(make::ext::ident_path(constructor));
1817                 let args = make::arg_list(iter::once(tail_expr));
1818                 make::expr_call(func, args)
1819             })
1820         }
1821         FlowHandler::If { .. } => {
1822             let controlflow_continue = make::expr_call(
1823                 make::expr_path(make::path_from_text("ControlFlow::Continue")),
1824                 make::arg_list(iter::once(make::expr_unit())),
1825             );
1826             with_tail_expr(block, controlflow_continue)
1827         }
1828         FlowHandler::IfOption { .. } => {
1829             let none = make::expr_path(make::ext::ident_path("None"));
1830             with_tail_expr(block, none)
1831         }
1832         FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| {
1833             let some = make::expr_path(make::ext::ident_path("Some"));
1834             let args = make::arg_list(iter::once(tail_expr));
1835             make::expr_call(some, args)
1836         }),
1837         FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| {
1838             let ok = make::expr_path(make::ext::ident_path("Ok"));
1839             let args = make::arg_list(iter::once(tail_expr));
1840             make::expr_call(ok, args)
1841         }),
1842     };
1843
1844     block.indent(new_indent)
1845 }
1846
1847 fn map_tail_expr(block: ast::BlockExpr, f: impl FnOnce(ast::Expr) -> ast::Expr) -> ast::BlockExpr {
1848     let tail_expr = match block.tail_expr() {
1849         Some(tail_expr) => tail_expr,
1850         None => return block,
1851     };
1852     make::block_expr(block.statements(), Some(f(tail_expr)))
1853 }
1854
1855 fn with_default_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr {
1856     match block.tail_expr() {
1857         Some(_) => block,
1858         None => make::block_expr(block.statements(), Some(tail_expr)),
1859     }
1860 }
1861
1862 fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr {
1863     let stmt_tail = block.tail_expr().map(|expr| make::expr_stmt(expr).into());
1864     let stmts = block.statements().chain(stmt_tail);
1865     make::block_expr(stmts, Some(tail_expr))
1866 }
1867
1868 fn format_type(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> String {
1869     ty.display_source_code(ctx.db(), module.into()).ok().unwrap_or_else(|| "_".to_string())
1870 }
1871
1872 fn make_ty(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type {
1873     let ty_str = format_type(ty, ctx, module);
1874     make::ty(&ty_str)
1875 }
1876
1877 fn rewrite_body_segment(
1878     ctx: &AssistContext<'_>,
1879     params: &[Param],
1880     handler: &FlowHandler,
1881     syntax: &SyntaxNode,
1882 ) -> SyntaxNode {
1883     let syntax = fix_param_usages(ctx, params, syntax);
1884     update_external_control_flow(handler, &syntax);
1885     syntax
1886 }
1887
1888 /// change all usages to account for added `&`/`&mut` for some params
1889 fn fix_param_usages(ctx: &AssistContext<'_>, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode {
1890     let mut usages_for_param: Vec<(&Param, Vec<ast::Expr>)> = Vec::new();
1891
1892     let tm = TreeMutator::new(syntax);
1893
1894     for param in params {
1895         if !param.kind().is_ref() {
1896             continue;
1897         }
1898
1899         let usages = LocalUsages::find_local_usages(ctx, param.var);
1900         let usages = usages
1901             .iter()
1902             .filter(|reference| syntax.text_range().contains_range(reference.range))
1903             .filter_map(|reference| path_element_of_reference(syntax, reference))
1904             .map(|expr| tm.make_mut(&expr));
1905
1906         usages_for_param.push((param, usages.collect()));
1907     }
1908
1909     let res = tm.make_syntax_mut(syntax);
1910
1911     for (param, usages) in usages_for_param {
1912         for usage in usages {
1913             match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) {
1914                 Some(ast::Expr::MethodCallExpr(_) | ast::Expr::FieldExpr(_)) => {
1915                     // do nothing
1916                 }
1917                 Some(ast::Expr::RefExpr(node))
1918                     if param.kind() == ParamKind::MutRef && node.mut_token().is_some() =>
1919                 {
1920                     ted::replace(node.syntax(), node.expr().unwrap().syntax());
1921                 }
1922                 Some(ast::Expr::RefExpr(node))
1923                     if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() =>
1924                 {
1925                     ted::replace(node.syntax(), node.expr().unwrap().syntax());
1926                 }
1927                 Some(_) | None => {
1928                     let p = &make::expr_prefix(T![*], usage.clone()).clone_for_update();
1929                     ted::replace(usage.syntax(), p.syntax())
1930                 }
1931             }
1932         }
1933     }
1934
1935     res
1936 }
1937
1938 fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) {
1939     let mut nested_loop = None;
1940     let mut nested_scope = None;
1941     for event in syntax.preorder() {
1942         match event {
1943             WalkEvent::Enter(e) => match e.kind() {
1944                 SyntaxKind::LOOP_EXPR | SyntaxKind::WHILE_EXPR | SyntaxKind::FOR_EXPR => {
1945                     if nested_loop.is_none() {
1946                         nested_loop = Some(e.clone());
1947                     }
1948                 }
1949                 SyntaxKind::FN
1950                 | SyntaxKind::CONST
1951                 | SyntaxKind::STATIC
1952                 | SyntaxKind::IMPL
1953                 | SyntaxKind::MODULE => {
1954                     if nested_scope.is_none() {
1955                         nested_scope = Some(e.clone());
1956                     }
1957                 }
1958                 _ => {}
1959             },
1960             WalkEvent::Leave(e) => {
1961                 if nested_scope.is_none() {
1962                     if let Some(expr) = ast::Expr::cast(e.clone()) {
1963                         match expr {
1964                             ast::Expr::ReturnExpr(return_expr) if nested_scope.is_none() => {
1965                                 let expr = return_expr.expr();
1966                                 if let Some(replacement) = make_rewritten_flow(handler, expr) {
1967                                     ted::replace(return_expr.syntax(), replacement.syntax())
1968                                 }
1969                             }
1970                             ast::Expr::BreakExpr(break_expr) if nested_loop.is_none() => {
1971                                 let expr = break_expr.expr();
1972                                 if let Some(replacement) = make_rewritten_flow(handler, expr) {
1973                                     ted::replace(break_expr.syntax(), replacement.syntax())
1974                                 }
1975                             }
1976                             ast::Expr::ContinueExpr(continue_expr) if nested_loop.is_none() => {
1977                                 if let Some(replacement) = make_rewritten_flow(handler, None) {
1978                                     ted::replace(continue_expr.syntax(), replacement.syntax())
1979                                 }
1980                             }
1981                             _ => {
1982                                 // do nothing
1983                             }
1984                         }
1985                     }
1986                 }
1987
1988                 if nested_loop.as_ref() == Some(&e) {
1989                     nested_loop = None;
1990                 }
1991                 if nested_scope.as_ref() == Some(&e) {
1992                     nested_scope = None;
1993                 }
1994             }
1995         };
1996     }
1997 }
1998
1999 fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Option<ast::Expr> {
2000     let value = match handler {
2001         FlowHandler::None | FlowHandler::Try { .. } => return None,
2002         FlowHandler::If { .. } => make::expr_call(
2003             make::expr_path(make::path_from_text("ControlFlow::Break")),
2004             make::arg_list(iter::once(make::expr_unit())),
2005         ),
2006         FlowHandler::IfOption { .. } => {
2007             let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new()));
2008             let args = make::arg_list(iter::once(expr));
2009             make::expr_call(make::expr_path(make::ext::ident_path("Some")), args)
2010         }
2011         FlowHandler::MatchOption { .. } => make::expr_path(make::ext::ident_path("None")),
2012         FlowHandler::MatchResult { .. } => {
2013             let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new()));
2014             let args = make::arg_list(iter::once(expr));
2015             make::expr_call(make::expr_path(make::ext::ident_path("Err")), args)
2016         }
2017     };
2018     Some(make::expr_return(Some(value)).clone_for_update())
2019 }
2020
2021 #[cfg(test)]
2022 mod tests {
2023     use crate::tests::{check_assist, check_assist_not_applicable};
2024
2025     use super::*;
2026
2027     #[test]
2028     fn no_args_from_binary_expr() {
2029         check_assist(
2030             extract_function,
2031             r#"
2032 fn foo() {
2033     foo($01 + 1$0);
2034 }
2035 "#,
2036             r#"
2037 fn foo() {
2038     foo(fun_name());
2039 }
2040
2041 fn $0fun_name() -> i32 {
2042     1 + 1
2043 }
2044 "#,
2045         );
2046     }
2047
2048     #[test]
2049     fn no_args_from_binary_expr_in_module() {
2050         check_assist(
2051             extract_function,
2052             r#"
2053 mod bar {
2054     fn foo() {
2055         foo($01 + 1$0);
2056     }
2057 }
2058 "#,
2059             r#"
2060 mod bar {
2061     fn foo() {
2062         foo(fun_name());
2063     }
2064
2065     fn $0fun_name() -> i32 {
2066         1 + 1
2067     }
2068 }
2069 "#,
2070         );
2071     }
2072
2073     #[test]
2074     fn no_args_from_binary_expr_indented() {
2075         check_assist(
2076             extract_function,
2077             r#"
2078 fn foo() {
2079     $0{ 1 + 1 }$0;
2080 }
2081 "#,
2082             r#"
2083 fn foo() {
2084     fun_name();
2085 }
2086
2087 fn $0fun_name() -> i32 {
2088     1 + 1
2089 }
2090 "#,
2091         );
2092     }
2093
2094     #[test]
2095     fn no_args_from_stmt_with_last_expr() {
2096         check_assist(
2097             extract_function,
2098             r#"
2099 fn foo() -> i32 {
2100     let k = 1;
2101     $0let m = 1;
2102     m + 1$0
2103 }
2104 "#,
2105             r#"
2106 fn foo() -> i32 {
2107     let k = 1;
2108     fun_name()
2109 }
2110
2111 fn $0fun_name() -> i32 {
2112     let m = 1;
2113     m + 1
2114 }
2115 "#,
2116         );
2117     }
2118
2119     #[test]
2120     fn no_args_from_stmt_unit() {
2121         check_assist(
2122             extract_function,
2123             r#"
2124 fn foo() {
2125     let k = 3;
2126     $0let m = 1;
2127     let n = m + 1;$0
2128     let g = 5;
2129 }
2130 "#,
2131             r#"
2132 fn foo() {
2133     let k = 3;
2134     fun_name();
2135     let g = 5;
2136 }
2137
2138 fn $0fun_name() {
2139     let m = 1;
2140     let n = m + 1;
2141 }
2142 "#,
2143         );
2144     }
2145
2146     #[test]
2147     fn no_args_if() {
2148         check_assist(
2149             extract_function,
2150             r#"
2151 fn foo() {
2152     $0if true { }$0
2153 }
2154 "#,
2155             r#"
2156 fn foo() {
2157     fun_name();
2158 }
2159
2160 fn $0fun_name() {
2161     if true { }
2162 }
2163 "#,
2164         );
2165     }
2166
2167     #[test]
2168     fn no_args_if_else() {
2169         check_assist(
2170             extract_function,
2171             r#"
2172 fn foo() -> i32 {
2173     $0if true { 1 } else { 2 }$0
2174 }
2175 "#,
2176             r#"
2177 fn foo() -> i32 {
2178     fun_name()
2179 }
2180
2181 fn $0fun_name() -> i32 {
2182     if true { 1 } else { 2 }
2183 }
2184 "#,
2185         );
2186     }
2187
2188     #[test]
2189     fn no_args_if_let_else() {
2190         check_assist(
2191             extract_function,
2192             r#"
2193 fn foo() -> i32 {
2194     $0if let true = false { 1 } else { 2 }$0
2195 }
2196 "#,
2197             r#"
2198 fn foo() -> i32 {
2199     fun_name()
2200 }
2201
2202 fn $0fun_name() -> i32 {
2203     if let true = false { 1 } else { 2 }
2204 }
2205 "#,
2206         );
2207     }
2208
2209     #[test]
2210     fn no_args_match() {
2211         check_assist(
2212             extract_function,
2213             r#"
2214 fn foo() -> i32 {
2215     $0match true {
2216         true => 1,
2217         false => 2,
2218     }$0
2219 }
2220 "#,
2221             r#"
2222 fn foo() -> i32 {
2223     fun_name()
2224 }
2225
2226 fn $0fun_name() -> i32 {
2227     match true {
2228         true => 1,
2229         false => 2,
2230     }
2231 }
2232 "#,
2233         );
2234     }
2235
2236     #[test]
2237     fn no_args_while() {
2238         check_assist(
2239             extract_function,
2240             r#"
2241 fn foo() {
2242     $0while true { }$0
2243 }
2244 "#,
2245             r#"
2246 fn foo() {
2247     fun_name();
2248 }
2249
2250 fn $0fun_name() {
2251     while true { }
2252 }
2253 "#,
2254         );
2255     }
2256
2257     #[test]
2258     fn no_args_for() {
2259         check_assist(
2260             extract_function,
2261             r#"
2262 fn foo() {
2263     $0for v in &[0, 1] { }$0
2264 }
2265 "#,
2266             r#"
2267 fn foo() {
2268     fun_name();
2269 }
2270
2271 fn $0fun_name() {
2272     for v in &[0, 1] { }
2273 }
2274 "#,
2275         );
2276     }
2277
2278     #[test]
2279     fn no_args_from_loop_unit() {
2280         check_assist(
2281             extract_function,
2282             r#"
2283 fn foo() {
2284     $0loop {
2285         let m = 1;
2286     }$0
2287 }
2288 "#,
2289             r#"
2290 fn foo() {
2291     fun_name()
2292 }
2293
2294 fn $0fun_name() -> ! {
2295     loop {
2296         let m = 1;
2297     }
2298 }
2299 "#,
2300         );
2301     }
2302
2303     #[test]
2304     fn no_args_from_loop_with_return() {
2305         check_assist(
2306             extract_function,
2307             r#"
2308 fn foo() {
2309     let v = $0loop {
2310         let m = 1;
2311         break m;
2312     }$0;
2313 }
2314 "#,
2315             r#"
2316 fn foo() {
2317     let v = fun_name();
2318 }
2319
2320 fn $0fun_name() -> i32 {
2321     loop {
2322         let m = 1;
2323         break m;
2324     }
2325 }
2326 "#,
2327         );
2328     }
2329
2330     #[test]
2331     fn no_args_from_match() {
2332         check_assist(
2333             extract_function,
2334             r#"
2335 fn foo() {
2336     let v: i32 = $0match Some(1) {
2337         Some(x) => x,
2338         None => 0,
2339     }$0;
2340 }
2341 "#,
2342             r#"
2343 fn foo() {
2344     let v: i32 = fun_name();
2345 }
2346
2347 fn $0fun_name() -> i32 {
2348     match Some(1) {
2349         Some(x) => x,
2350         None => 0,
2351     }
2352 }
2353 "#,
2354         );
2355     }
2356
2357     #[test]
2358     fn extract_partial_block_single_line() {
2359         check_assist(
2360             extract_function,
2361             r#"
2362 fn foo() {
2363     let n = 1;
2364     let mut v = $0n * n;$0
2365     v += 1;
2366 }
2367 "#,
2368             r#"
2369 fn foo() {
2370     let n = 1;
2371     let mut v = fun_name(n);
2372     v += 1;
2373 }
2374
2375 fn $0fun_name(n: i32) -> i32 {
2376     let mut v = n * n;
2377     v
2378 }
2379 "#,
2380         );
2381     }
2382
2383     #[test]
2384     fn extract_partial_block() {
2385         check_assist(
2386             extract_function,
2387             r#"
2388 fn foo() {
2389     let m = 2;
2390     let n = 1;
2391     let mut v = m $0* n;
2392     let mut w = 3;$0
2393     v += 1;
2394     w += 1;
2395 }
2396 "#,
2397             r#"
2398 fn foo() {
2399     let m = 2;
2400     let n = 1;
2401     let (mut v, mut w) = fun_name(m, n);
2402     v += 1;
2403     w += 1;
2404 }
2405
2406 fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
2407     let mut v = m * n;
2408     let mut w = 3;
2409     (v, w)
2410 }
2411 "#,
2412         );
2413     }
2414
2415     #[test]
2416     fn argument_form_expr() {
2417         check_assist(
2418             extract_function,
2419             r#"
2420 fn foo() -> u32 {
2421     let n = 2;
2422     $0n+2$0
2423 }
2424 "#,
2425             r#"
2426 fn foo() -> u32 {
2427     let n = 2;
2428     fun_name(n)
2429 }
2430
2431 fn $0fun_name(n: u32) -> u32 {
2432     n+2
2433 }
2434 "#,
2435         )
2436     }
2437
2438     #[test]
2439     fn argument_used_twice_form_expr() {
2440         check_assist(
2441             extract_function,
2442             r#"
2443 fn foo() -> u32 {
2444     let n = 2;
2445     $0n+n$0
2446 }
2447 "#,
2448             r#"
2449 fn foo() -> u32 {
2450     let n = 2;
2451     fun_name(n)
2452 }
2453
2454 fn $0fun_name(n: u32) -> u32 {
2455     n+n
2456 }
2457 "#,
2458         )
2459     }
2460
2461     #[test]
2462     fn two_arguments_form_expr() {
2463         check_assist(
2464             extract_function,
2465             r#"
2466 fn foo() -> u32 {
2467     let n = 2;
2468     let m = 3;
2469     $0n+n*m$0
2470 }
2471 "#,
2472             r#"
2473 fn foo() -> u32 {
2474     let n = 2;
2475     let m = 3;
2476     fun_name(n, m)
2477 }
2478
2479 fn $0fun_name(n: u32, m: u32) -> u32 {
2480     n+n*m
2481 }
2482 "#,
2483         )
2484     }
2485
2486     #[test]
2487     fn argument_and_locals() {
2488         check_assist(
2489             extract_function,
2490             r#"
2491 fn foo() -> u32 {
2492     let n = 2;
2493     $0let m = 1;
2494     n + m$0
2495 }
2496 "#,
2497             r#"
2498 fn foo() -> u32 {
2499     let n = 2;
2500     fun_name(n)
2501 }
2502
2503 fn $0fun_name(n: u32) -> u32 {
2504     let m = 1;
2505     n + m
2506 }
2507 "#,
2508         )
2509     }
2510
2511     #[test]
2512     fn in_comment_is_not_applicable() {
2513         cov_mark::check!(extract_function_in_comment_is_not_applicable);
2514         check_assist_not_applicable(extract_function, r"fn main() { 1 + /* $0comment$0 */ 1; }");
2515     }
2516
2517     #[test]
2518     fn part_of_expr_stmt() {
2519         check_assist(
2520             extract_function,
2521             r#"
2522 fn foo() {
2523     $01$0 + 1;
2524 }
2525 "#,
2526             r#"
2527 fn foo() {
2528     fun_name() + 1;
2529 }
2530
2531 fn $0fun_name() -> i32 {
2532     1
2533 }
2534 "#,
2535         );
2536     }
2537
2538     #[test]
2539     fn function_expr() {
2540         check_assist(
2541             extract_function,
2542             r#"
2543 fn foo() {
2544     $0bar(1 + 1)$0
2545 }
2546 "#,
2547             r#"
2548 fn foo() {
2549     fun_name();
2550 }
2551
2552 fn $0fun_name() {
2553     bar(1 + 1)
2554 }
2555 "#,
2556         )
2557     }
2558
2559     #[test]
2560     fn extract_from_nested() {
2561         check_assist(
2562             extract_function,
2563             r#"
2564 fn main() {
2565     let x = true;
2566     let tuple = match x {
2567         true => ($02 + 2$0, true)
2568         _ => (0, false)
2569     };
2570 }
2571 "#,
2572             r#"
2573 fn main() {
2574     let x = true;
2575     let tuple = match x {
2576         true => (fun_name(), true)
2577         _ => (0, false)
2578     };
2579 }
2580
2581 fn $0fun_name() -> i32 {
2582     2 + 2
2583 }
2584 "#,
2585         );
2586     }
2587
2588     #[test]
2589     fn param_from_closure() {
2590         check_assist(
2591             extract_function,
2592             r#"
2593 fn main() {
2594     let lambda = |x: u32| $0x * 2$0;
2595 }
2596 "#,
2597             r#"
2598 fn main() {
2599     let lambda = |x: u32| fun_name(x);
2600 }
2601
2602 fn $0fun_name(x: u32) -> u32 {
2603     x * 2
2604 }
2605 "#,
2606         );
2607     }
2608
2609     #[test]
2610     fn extract_return_stmt() {
2611         check_assist(
2612             extract_function,
2613             r#"
2614 fn foo() -> u32 {
2615     $0return 2 + 2$0;
2616 }
2617 "#,
2618             r#"
2619 fn foo() -> u32 {
2620     return fun_name();
2621 }
2622
2623 fn $0fun_name() -> u32 {
2624     2 + 2
2625 }
2626 "#,
2627         );
2628     }
2629
2630     #[test]
2631     fn does_not_add_extra_whitespace() {
2632         check_assist(
2633             extract_function,
2634             r#"
2635 fn foo() -> u32 {
2636
2637
2638     $0return 2 + 2$0;
2639 }
2640 "#,
2641             r#"
2642 fn foo() -> u32 {
2643
2644
2645     return fun_name();
2646 }
2647
2648 fn $0fun_name() -> u32 {
2649     2 + 2
2650 }
2651 "#,
2652         );
2653     }
2654
2655     #[test]
2656     fn break_stmt() {
2657         check_assist(
2658             extract_function,
2659             r#"
2660 fn main() {
2661     let result = loop {
2662         $0break 2 + 2$0;
2663     };
2664 }
2665 "#,
2666             r#"
2667 fn main() {
2668     let result = loop {
2669         break fun_name();
2670     };
2671 }
2672
2673 fn $0fun_name() -> i32 {
2674     2 + 2
2675 }
2676 "#,
2677         );
2678     }
2679
2680     #[test]
2681     fn extract_cast() {
2682         check_assist(
2683             extract_function,
2684             r#"
2685 fn main() {
2686     let v = $00f32 as u32$0;
2687 }
2688 "#,
2689             r#"
2690 fn main() {
2691     let v = fun_name();
2692 }
2693
2694 fn $0fun_name() -> u32 {
2695     0f32 as u32
2696 }
2697 "#,
2698         );
2699     }
2700
2701     #[test]
2702     fn return_not_applicable() {
2703         check_assist_not_applicable(extract_function, r"fn foo() { $0return$0; } ");
2704     }
2705
2706     #[test]
2707     fn method_to_freestanding() {
2708         check_assist(
2709             extract_function,
2710             r#"
2711 struct S;
2712
2713 impl S {
2714     fn foo(&self) -> i32 {
2715         $01+1$0
2716     }
2717 }
2718 "#,
2719             r#"
2720 struct S;
2721
2722 impl S {
2723     fn foo(&self) -> i32 {
2724         fun_name()
2725     }
2726 }
2727
2728 fn $0fun_name() -> i32 {
2729     1+1
2730 }
2731 "#,
2732         );
2733     }
2734
2735     #[test]
2736     fn method_with_reference() {
2737         check_assist(
2738             extract_function,
2739             r#"
2740 struct S { f: i32 };
2741
2742 impl S {
2743     fn foo(&self) -> i32 {
2744         $0self.f+self.f$0
2745     }
2746 }
2747 "#,
2748             r#"
2749 struct S { f: i32 };
2750
2751 impl S {
2752     fn foo(&self) -> i32 {
2753         self.fun_name()
2754     }
2755
2756     fn $0fun_name(&self) -> i32 {
2757         self.f+self.f
2758     }
2759 }
2760 "#,
2761         );
2762     }
2763
2764     #[test]
2765     fn method_with_mut() {
2766         check_assist(
2767             extract_function,
2768             r#"
2769 struct S { f: i32 };
2770
2771 impl S {
2772     fn foo(&mut self) {
2773         $0self.f += 1;$0
2774     }
2775 }
2776 "#,
2777             r#"
2778 struct S { f: i32 };
2779
2780 impl S {
2781     fn foo(&mut self) {
2782         self.fun_name();
2783     }
2784
2785     fn $0fun_name(&mut self) {
2786         self.f += 1;
2787     }
2788 }
2789 "#,
2790         );
2791     }
2792
2793     #[test]
2794     fn variable_defined_inside_and_used_after_no_ret() {
2795         check_assist(
2796             extract_function,
2797             r#"
2798 fn foo() {
2799     let n = 1;
2800     $0let k = n * n;$0
2801     let m = k + 1;
2802 }
2803 "#,
2804             r#"
2805 fn foo() {
2806     let n = 1;
2807     let k = fun_name(n);
2808     let m = k + 1;
2809 }
2810
2811 fn $0fun_name(n: i32) -> i32 {
2812     let k = n * n;
2813     k
2814 }
2815 "#,
2816         );
2817     }
2818
2819     #[test]
2820     fn variable_defined_inside_and_used_after_mutably_no_ret() {
2821         check_assist(
2822             extract_function,
2823             r#"
2824 fn foo() {
2825     let n = 1;
2826     $0let mut k = n * n;$0
2827     k += 1;
2828 }
2829 "#,
2830             r#"
2831 fn foo() {
2832     let n = 1;
2833     let mut k = fun_name(n);
2834     k += 1;
2835 }
2836
2837 fn $0fun_name(n: i32) -> i32 {
2838     let mut k = n * n;
2839     k
2840 }
2841 "#,
2842         );
2843     }
2844
2845     #[test]
2846     fn two_variables_defined_inside_and_used_after_no_ret() {
2847         check_assist(
2848             extract_function,
2849             r#"
2850 fn foo() {
2851     let n = 1;
2852     $0let k = n * n;
2853     let m = k + 2;$0
2854     let h = k + m;
2855 }
2856 "#,
2857             r#"
2858 fn foo() {
2859     let n = 1;
2860     let (k, m) = fun_name(n);
2861     let h = k + m;
2862 }
2863
2864 fn $0fun_name(n: i32) -> (i32, i32) {
2865     let k = n * n;
2866     let m = k + 2;
2867     (k, m)
2868 }
2869 "#,
2870         );
2871     }
2872
2873     #[test]
2874     fn multi_variables_defined_inside_and_used_after_mutably_no_ret() {
2875         check_assist(
2876             extract_function,
2877             r#"
2878 fn foo() {
2879     let n = 1;
2880     $0let mut k = n * n;
2881     let mut m = k + 2;
2882     let mut o = m + 3;
2883     o += 1;$0
2884     k += o;
2885     m = 1;
2886 }
2887 "#,
2888             r#"
2889 fn foo() {
2890     let n = 1;
2891     let (mut k, mut m, o) = fun_name(n);
2892     k += o;
2893     m = 1;
2894 }
2895
2896 fn $0fun_name(n: i32) -> (i32, i32, i32) {
2897     let mut k = n * n;
2898     let mut m = k + 2;
2899     let mut o = m + 3;
2900     o += 1;
2901     (k, m, o)
2902 }
2903 "#,
2904         );
2905     }
2906
2907     #[test]
2908     fn nontrivial_patterns_define_variables() {
2909         check_assist(
2910             extract_function,
2911             r#"
2912 struct Counter(i32);
2913 fn foo() {
2914     $0let Counter(n) = Counter(0);$0
2915     let m = n;
2916 }
2917 "#,
2918             r#"
2919 struct Counter(i32);
2920 fn foo() {
2921     let n = fun_name();
2922     let m = n;
2923 }
2924
2925 fn $0fun_name() -> i32 {
2926     let Counter(n) = Counter(0);
2927     n
2928 }
2929 "#,
2930         );
2931     }
2932
2933     #[test]
2934     fn struct_with_two_fields_pattern_define_variables() {
2935         check_assist(
2936             extract_function,
2937             r#"
2938 struct Counter { n: i32, m: i32 };
2939 fn foo() {
2940     $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0
2941     let h = n + k;
2942 }
2943 "#,
2944             r#"
2945 struct Counter { n: i32, m: i32 };
2946 fn foo() {
2947     let (n, k) = fun_name();
2948     let h = n + k;
2949 }
2950
2951 fn $0fun_name() -> (i32, i32) {
2952     let Counter { n, m: k } = Counter { n: 1, m: 2 };
2953     (n, k)
2954 }
2955 "#,
2956         );
2957     }
2958
2959     #[test]
2960     fn mut_var_from_outer_scope() {
2961         check_assist(
2962             extract_function,
2963             r#"
2964 fn foo() {
2965     let mut n = 1;
2966     $0n += 1;$0
2967     let m = n + 1;
2968 }
2969 "#,
2970             r#"
2971 fn foo() {
2972     let mut n = 1;
2973     fun_name(&mut n);
2974     let m = n + 1;
2975 }
2976
2977 fn $0fun_name(n: &mut i32) {
2978     *n += 1;
2979 }
2980 "#,
2981         );
2982     }
2983
2984     #[test]
2985     fn mut_field_from_outer_scope() {
2986         check_assist(
2987             extract_function,
2988             r#"
2989 struct C { n: i32 }
2990 fn foo() {
2991     let mut c = C { n: 0 };
2992     $0c.n += 1;$0
2993     let m = c.n + 1;
2994 }
2995 "#,
2996             r#"
2997 struct C { n: i32 }
2998 fn foo() {
2999     let mut c = C { n: 0 };
3000     fun_name(&mut c);
3001     let m = c.n + 1;
3002 }
3003
3004 fn $0fun_name(c: &mut C) {
3005     c.n += 1;
3006 }
3007 "#,
3008         );
3009     }
3010
3011     #[test]
3012     fn mut_nested_field_from_outer_scope() {
3013         check_assist(
3014             extract_function,
3015             r#"
3016 struct P { n: i32}
3017 struct C { p: P }
3018 fn foo() {
3019     let mut c = C { p: P { n: 0 } };
3020     let mut v = C { p: P { n: 0 } };
3021     let u = C { p: P { n: 0 } };
3022     $0c.p.n += u.p.n;
3023     let r = &mut v.p.n;$0
3024     let m = c.p.n + v.p.n + u.p.n;
3025 }
3026 "#,
3027             r#"
3028 struct P { n: i32}
3029 struct C { p: P }
3030 fn foo() {
3031     let mut c = C { p: P { n: 0 } };
3032     let mut v = C { p: P { n: 0 } };
3033     let u = C { p: P { n: 0 } };
3034     fun_name(&mut c, &u, &mut v);
3035     let m = c.p.n + v.p.n + u.p.n;
3036 }
3037
3038 fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
3039     c.p.n += u.p.n;
3040     let r = &mut v.p.n;
3041 }
3042 "#,
3043         );
3044     }
3045
3046     #[test]
3047     fn mut_param_many_usages_stmt() {
3048         check_assist(
3049             extract_function,
3050             r#"
3051 fn bar(k: i32) {}
3052 trait I: Copy {
3053     fn succ(&self) -> Self;
3054     fn inc(&mut self) -> Self { let v = self.succ(); *self = v; v }
3055 }
3056 impl I for i32 {
3057     fn succ(&self) -> Self { *self + 1 }
3058 }
3059 fn foo() {
3060     let mut n = 1;
3061     $0n += n;
3062     bar(n);
3063     bar(n+1);
3064     bar(n*n);
3065     bar(&n);
3066     n.inc();
3067     let v = &mut n;
3068     *v = v.succ();
3069     n.succ();$0
3070     let m = n + 1;
3071 }
3072 "#,
3073             r#"
3074 fn bar(k: i32) {}
3075 trait I: Copy {
3076     fn succ(&self) -> Self;
3077     fn inc(&mut self) -> Self { let v = self.succ(); *self = v; v }
3078 }
3079 impl I for i32 {
3080     fn succ(&self) -> Self { *self + 1 }
3081 }
3082 fn foo() {
3083     let mut n = 1;
3084     fun_name(&mut n);
3085     let m = n + 1;
3086 }
3087
3088 fn $0fun_name(n: &mut i32) {
3089     *n += *n;
3090     bar(*n);
3091     bar(*n+1);
3092     bar(*n**n);
3093     bar(&*n);
3094     n.inc();
3095     let v = n;
3096     *v = v.succ();
3097     n.succ();
3098 }
3099 "#,
3100         );
3101     }
3102
3103     #[test]
3104     fn mut_param_many_usages_expr() {
3105         check_assist(
3106             extract_function,
3107             r#"
3108 fn bar(k: i32) {}
3109 trait I: Copy {
3110     fn succ(&self) -> Self;
3111     fn inc(&mut self) -> Self { let v = self.succ(); *self = v; v }
3112 }
3113 impl I for i32 {
3114     fn succ(&self) -> Self { *self + 1 }
3115 }
3116 fn foo() {
3117     let mut n = 1;
3118     $0{
3119         n += n;
3120         bar(n);
3121         bar(n+1);
3122         bar(n*n);
3123         bar(&n);
3124         n.inc();
3125         let v = &mut n;
3126         *v = v.succ();
3127         n.succ();
3128     }$0
3129     let m = n + 1;
3130 }
3131 "#,
3132             r#"
3133 fn bar(k: i32) {}
3134 trait I: Copy {
3135     fn succ(&self) -> Self;
3136     fn inc(&mut self) -> Self { let v = self.succ(); *self = v; v }
3137 }
3138 impl I for i32 {
3139     fn succ(&self) -> Self { *self + 1 }
3140 }
3141 fn foo() {
3142     let mut n = 1;
3143     fun_name(&mut n);
3144     let m = n + 1;
3145 }
3146
3147 fn $0fun_name(n: &mut i32) {
3148     *n += *n;
3149     bar(*n);
3150     bar(*n+1);
3151     bar(*n**n);
3152     bar(&*n);
3153     n.inc();
3154     let v = n;
3155     *v = v.succ();
3156     n.succ();
3157 }
3158 "#,
3159         );
3160     }
3161
3162     #[test]
3163     fn mut_param_by_value() {
3164         check_assist(
3165             extract_function,
3166             r#"
3167 fn foo() {
3168     let mut n = 1;
3169     $0n += 1;$0
3170 }
3171 "#,
3172             r"
3173 fn foo() {
3174     let mut n = 1;
3175     fun_name(n);
3176 }
3177
3178 fn $0fun_name(mut n: i32) {
3179     n += 1;
3180 }
3181 ",
3182         );
3183     }
3184
3185     #[test]
3186     fn mut_param_because_of_mut_ref() {
3187         check_assist(
3188             extract_function,
3189             r#"
3190 fn foo() {
3191     let mut n = 1;
3192     $0let v = &mut n;
3193     *v += 1;$0
3194     let k = n;
3195 }
3196 "#,
3197             r#"
3198 fn foo() {
3199     let mut n = 1;
3200     fun_name(&mut n);
3201     let k = n;
3202 }
3203
3204 fn $0fun_name(n: &mut i32) {
3205     let v = n;
3206     *v += 1;
3207 }
3208 "#,
3209         );
3210     }
3211
3212     #[test]
3213     fn mut_param_by_value_because_of_mut_ref() {
3214         check_assist(
3215             extract_function,
3216             r"
3217 fn foo() {
3218     let mut n = 1;
3219     $0let v = &mut n;
3220     *v += 1;$0
3221 }
3222 ",
3223             r#"
3224 fn foo() {
3225     let mut n = 1;
3226     fun_name(n);
3227 }
3228
3229 fn $0fun_name(mut n: i32) {
3230     let v = &mut n;
3231     *v += 1;
3232 }
3233 "#,
3234         );
3235     }
3236
3237     #[test]
3238     fn mut_method_call() {
3239         check_assist(
3240             extract_function,
3241             r#"
3242 trait I {
3243     fn inc(&mut self);
3244 }
3245 impl I for i32 {
3246     fn inc(&mut self) { *self += 1 }
3247 }
3248 fn foo() {
3249     let mut n = 1;
3250     $0n.inc();$0
3251 }
3252 "#,
3253             r#"
3254 trait I {
3255     fn inc(&mut self);
3256 }
3257 impl I for i32 {
3258     fn inc(&mut self) { *self += 1 }
3259 }
3260 fn foo() {
3261     let mut n = 1;
3262     fun_name(n);
3263 }
3264
3265 fn $0fun_name(mut n: i32) {
3266     n.inc();
3267 }
3268 "#,
3269         );
3270     }
3271
3272     #[test]
3273     fn shared_method_call() {
3274         check_assist(
3275             extract_function,
3276             r#"
3277 trait I {
3278     fn succ(&self);
3279 }
3280 impl I for i32 {
3281     fn succ(&self) { *self + 1 }
3282 }
3283 fn foo() {
3284     let mut n = 1;
3285     $0n.succ();$0
3286 }
3287 "#,
3288             r"
3289 trait I {
3290     fn succ(&self);
3291 }
3292 impl I for i32 {
3293     fn succ(&self) { *self + 1 }
3294 }
3295 fn foo() {
3296     let mut n = 1;
3297     fun_name(n);
3298 }
3299
3300 fn $0fun_name(n: i32) {
3301     n.succ();
3302 }
3303 ",
3304         );
3305     }
3306
3307     #[test]
3308     fn mut_method_call_with_other_receiver() {
3309         check_assist(
3310             extract_function,
3311             r#"
3312 trait I {
3313     fn inc(&mut self, n: i32);
3314 }
3315 impl I for i32 {
3316     fn inc(&mut self, n: i32) { *self += n }
3317 }
3318 fn foo() {
3319     let mut n = 1;
3320     $0let mut m = 2;
3321     m.inc(n);$0
3322 }
3323 "#,
3324             r"
3325 trait I {
3326     fn inc(&mut self, n: i32);
3327 }
3328 impl I for i32 {
3329     fn inc(&mut self, n: i32) { *self += n }
3330 }
3331 fn foo() {
3332     let mut n = 1;
3333     fun_name(n);
3334 }
3335
3336 fn $0fun_name(n: i32) {
3337     let mut m = 2;
3338     m.inc(n);
3339 }
3340 ",
3341         );
3342     }
3343
3344     #[test]
3345     fn non_copy_without_usages_after() {
3346         check_assist(
3347             extract_function,
3348             r#"
3349 struct Counter(i32);
3350 fn foo() {
3351     let c = Counter(0);
3352     $0let n = c.0;$0
3353 }
3354 "#,
3355             r"
3356 struct Counter(i32);
3357 fn foo() {
3358     let c = Counter(0);
3359     fun_name(c);
3360 }
3361
3362 fn $0fun_name(c: Counter) {
3363     let n = c.0;
3364 }
3365 ",
3366         );
3367     }
3368
3369     #[test]
3370     fn non_copy_used_after() {
3371         check_assist(
3372             extract_function,
3373             r"
3374 struct Counter(i32);
3375 fn foo() {
3376     let c = Counter(0);
3377     $0let n = c.0;$0
3378     let m = c.0;
3379 }
3380 ",
3381             r#"
3382 struct Counter(i32);
3383 fn foo() {
3384     let c = Counter(0);
3385     fun_name(&c);
3386     let m = c.0;
3387 }
3388
3389 fn $0fun_name(c: &Counter) {
3390     let n = c.0;
3391 }
3392 "#,
3393         );
3394     }
3395
3396     #[test]
3397     fn copy_used_after() {
3398         check_assist(
3399             extract_function,
3400             r#"
3401 //- minicore: copy
3402 fn foo() {
3403     let n = 0;
3404     $0let m = n;$0
3405     let k = n;
3406 }
3407 "#,
3408             r#"
3409 fn foo() {
3410     let n = 0;
3411     fun_name(n);
3412     let k = n;
3413 }
3414
3415 fn $0fun_name(n: i32) {
3416     let m = n;
3417 }
3418 "#,
3419         )
3420     }
3421
3422     #[test]
3423     fn copy_custom_used_after() {
3424         check_assist(
3425             extract_function,
3426             r#"
3427 //- minicore: copy, derive
3428 #[derive(Clone, Copy)]
3429 struct Counter(i32);
3430 fn foo() {
3431     let c = Counter(0);
3432     $0let n = c.0;$0
3433     let m = c.0;
3434 }
3435 "#,
3436             r#"
3437 #[derive(Clone, Copy)]
3438 struct Counter(i32);
3439 fn foo() {
3440     let c = Counter(0);
3441     fun_name(c);
3442     let m = c.0;
3443 }
3444
3445 fn $0fun_name(c: Counter) {
3446     let n = c.0;
3447 }
3448 "#,
3449         );
3450     }
3451
3452     #[test]
3453     fn indented_stmts() {
3454         check_assist(
3455             extract_function,
3456             r#"
3457 fn foo() {
3458     if true {
3459         loop {
3460             $0let n = 1;
3461             let m = 2;$0
3462         }
3463     }
3464 }
3465 "#,
3466             r#"
3467 fn foo() {
3468     if true {
3469         loop {
3470             fun_name();
3471         }
3472     }
3473 }
3474
3475 fn $0fun_name() {
3476     let n = 1;
3477     let m = 2;
3478 }
3479 "#,
3480         );
3481     }
3482
3483     #[test]
3484     fn indented_stmts_inside_mod() {
3485         check_assist(
3486             extract_function,
3487             r#"
3488 mod bar {
3489     fn foo() {
3490         if true {
3491             loop {
3492                 $0let n = 1;
3493                 let m = 2;$0
3494             }
3495         }
3496     }
3497 }
3498 "#,
3499             r#"
3500 mod bar {
3501     fn foo() {
3502         if true {
3503             loop {
3504                 fun_name();
3505             }
3506         }
3507     }
3508
3509     fn $0fun_name() {
3510         let n = 1;
3511         let m = 2;
3512     }
3513 }
3514 "#,
3515         );
3516     }
3517
3518     #[test]
3519     fn break_loop() {
3520         check_assist(
3521             extract_function,
3522             r#"
3523 //- minicore: option
3524 fn foo() {
3525     loop {
3526         let n = 1;
3527         $0let m = n + 1;
3528         break;
3529         let k = 2;$0
3530         let h = 1 + k;
3531     }
3532 }
3533 "#,
3534             r#"
3535 fn foo() {
3536     loop {
3537         let n = 1;
3538         let k = match fun_name(n) {
3539             Some(value) => value,
3540             None => break,
3541         };
3542         let h = 1 + k;
3543     }
3544 }
3545
3546 fn $0fun_name(n: i32) -> Option<i32> {
3547     let m = n + 1;
3548     return None;
3549     let k = 2;
3550     Some(k)
3551 }
3552 "#,
3553         );
3554     }
3555
3556     #[test]
3557     fn return_to_parent() {
3558         check_assist(
3559             extract_function,
3560             r#"
3561 //- minicore: copy, result
3562 fn foo() -> i64 {
3563     let n = 1;
3564     $0let m = n + 1;
3565     return 1;
3566     let k = 2;$0
3567     (n + k) as i64
3568 }
3569 "#,
3570             r#"
3571 fn foo() -> i64 {
3572     let n = 1;
3573     let k = match fun_name(n) {
3574         Ok(value) => value,
3575         Err(value) => return value,
3576     };
3577     (n + k) as i64
3578 }
3579
3580 fn $0fun_name(n: i32) -> Result<i32, i64> {
3581     let m = n + 1;
3582     return Err(1);
3583     let k = 2;
3584     Ok(k)
3585 }
3586 "#,
3587         );
3588     }
3589
3590     #[test]
3591     fn break_and_continue() {
3592         cov_mark::check!(external_control_flow_break_and_continue);
3593         check_assist_not_applicable(
3594             extract_function,
3595             r#"
3596 fn foo() {
3597     loop {
3598         let n = 1;
3599         $0let m = n + 1;
3600         break;
3601         let k = 2;
3602         continue;
3603         let k = k + 1;$0
3604         let r = n + k;
3605     }
3606 }
3607 "#,
3608         );
3609     }
3610
3611     #[test]
3612     fn return_and_break() {
3613         cov_mark::check!(external_control_flow_return_and_bc);
3614         check_assist_not_applicable(
3615             extract_function,
3616             r#"
3617 fn foo() {
3618     loop {
3619         let n = 1;
3620         $0let m = n + 1;
3621         break;
3622         let k = 2;
3623         return;
3624         let k = k + 1;$0
3625         let r = n + k;
3626     }
3627 }
3628 "#,
3629         );
3630     }
3631
3632     #[test]
3633     fn break_loop_with_if() {
3634         check_assist(
3635             extract_function,
3636             r#"
3637 //- minicore: try
3638 fn foo() {
3639     loop {
3640         let mut n = 1;
3641         $0let m = n + 1;
3642         break;
3643         n += m;$0
3644         let h = 1 + n;
3645     }
3646 }
3647 "#,
3648             r#"
3649 use core::ops::ControlFlow;
3650
3651 fn foo() {
3652     loop {
3653         let mut n = 1;
3654         if let ControlFlow::Break(_) = fun_name(&mut n) {
3655             break;
3656         }
3657         let h = 1 + n;
3658     }
3659 }
3660
3661 fn $0fun_name(n: &mut i32) -> ControlFlow<()> {
3662     let m = *n + 1;
3663     return ControlFlow::Break(());
3664     *n += m;
3665     ControlFlow::Continue(())
3666 }
3667 "#,
3668         );
3669     }
3670
3671     #[test]
3672     fn break_loop_nested() {
3673         check_assist(
3674             extract_function,
3675             r#"
3676 //- minicore: try
3677 fn foo() {
3678     loop {
3679         let mut n = 1;
3680         $0let m = n + 1;
3681         if m == 42 {
3682             break;
3683         }$0
3684         let h = 1;
3685     }
3686 }
3687 "#,
3688             r#"
3689 use core::ops::ControlFlow;
3690
3691 fn foo() {
3692     loop {
3693         let mut n = 1;
3694         if let ControlFlow::Break(_) = fun_name(n) {
3695             break;
3696         }
3697         let h = 1;
3698     }
3699 }
3700
3701 fn $0fun_name(n: i32) -> ControlFlow<()> {
3702     let m = n + 1;
3703     if m == 42 {
3704         return ControlFlow::Break(());
3705     }
3706     ControlFlow::Continue(())
3707 }
3708 "#,
3709         );
3710     }
3711
3712     #[test]
3713     fn break_loop_nested_labeled() {
3714         check_assist(
3715             extract_function,
3716             r#"
3717 //- minicore: try
3718 fn foo() {
3719     'bar: loop {
3720         loop {
3721             $0break 'bar;$0
3722         }
3723     }
3724 }
3725 "#,
3726             r#"
3727 use core::ops::ControlFlow;
3728
3729 fn foo() {
3730     'bar: loop {
3731         loop {
3732             if let ControlFlow::Break(_) = fun_name() {
3733                 break 'bar;
3734             }
3735         }
3736     }
3737 }
3738
3739 fn $0fun_name() -> ControlFlow<()> {
3740     return ControlFlow::Break(());
3741     ControlFlow::Continue(())
3742 }
3743 "#,
3744         );
3745     }
3746
3747     #[test]
3748     fn continue_loop_nested_labeled() {
3749         check_assist(
3750             extract_function,
3751             r#"
3752 //- minicore: try
3753 fn foo() {
3754     'bar: loop {
3755         loop {
3756             $0continue 'bar;$0
3757         }
3758     }
3759 }
3760 "#,
3761             r#"
3762 use core::ops::ControlFlow;
3763
3764 fn foo() {
3765     'bar: loop {
3766         loop {
3767             if let ControlFlow::Break(_) = fun_name() {
3768                 continue 'bar;
3769             }
3770         }
3771     }
3772 }
3773
3774 fn $0fun_name() -> ControlFlow<()> {
3775     return ControlFlow::Break(());
3776     ControlFlow::Continue(())
3777 }
3778 "#,
3779         );
3780     }
3781
3782     #[test]
3783     fn return_from_nested_loop() {
3784         check_assist(
3785             extract_function,
3786             r#"
3787 fn foo() {
3788     loop {
3789         let n = 1;$0
3790         let k = 1;
3791         loop {
3792             return;
3793         }
3794         let m = k + 1;$0
3795         let h = 1 + m;
3796     }
3797 }
3798 "#,
3799             r#"
3800 fn foo() {
3801     loop {
3802         let n = 1;
3803         let m = match fun_name() {
3804             Some(value) => value,
3805             None => return,
3806         };
3807         let h = 1 + m;
3808     }
3809 }
3810
3811 fn $0fun_name() -> Option<i32> {
3812     let k = 1;
3813     loop {
3814         return None;
3815     }
3816     let m = k + 1;
3817     Some(m)
3818 }
3819 "#,
3820         );
3821     }
3822
3823     #[test]
3824     fn break_from_nested_loop() {
3825         check_assist(
3826             extract_function,
3827             r#"
3828 fn foo() {
3829     loop {
3830         let n = 1;
3831         $0let k = 1;
3832         loop {
3833             break;
3834         }
3835         let m = k + 1;$0
3836         let h = 1 + m;
3837     }
3838 }
3839 "#,
3840             r#"
3841 fn foo() {
3842     loop {
3843         let n = 1;
3844         let m = fun_name();
3845         let h = 1 + m;
3846     }
3847 }
3848
3849 fn $0fun_name() -> i32 {
3850     let k = 1;
3851     loop {
3852         break;
3853     }
3854     let m = k + 1;
3855     m
3856 }
3857 "#,
3858         );
3859     }
3860
3861     #[test]
3862     fn break_from_nested_and_outer_loops() {
3863         check_assist(
3864             extract_function,
3865             r#"
3866 fn foo() {
3867     loop {
3868         let n = 1;
3869         $0let k = 1;
3870         loop {
3871             break;
3872         }
3873         if k == 42 {
3874             break;
3875         }
3876         let m = k + 1;$0
3877         let h = 1 + m;
3878     }
3879 }
3880 "#,
3881             r#"
3882 fn foo() {
3883     loop {
3884         let n = 1;
3885         let m = match fun_name() {
3886             Some(value) => value,
3887             None => break,
3888         };
3889         let h = 1 + m;
3890     }
3891 }
3892
3893 fn $0fun_name() -> Option<i32> {
3894     let k = 1;
3895     loop {
3896         break;
3897     }
3898     if k == 42 {
3899         return None;
3900     }
3901     let m = k + 1;
3902     Some(m)
3903 }
3904 "#,
3905         );
3906     }
3907
3908     #[test]
3909     fn return_from_nested_fn() {
3910         check_assist(
3911             extract_function,
3912             r#"
3913 fn foo() {
3914     loop {
3915         let n = 1;
3916         $0let k = 1;
3917         fn test() {
3918             return;
3919         }
3920         let m = k + 1;$0
3921         let h = 1 + m;
3922     }
3923 }
3924 "#,
3925             r#"
3926 fn foo() {
3927     loop {
3928         let n = 1;
3929         let m = fun_name();
3930         let h = 1 + m;
3931     }
3932 }
3933
3934 fn $0fun_name() -> i32 {
3935     let k = 1;
3936     fn test() {
3937         return;
3938     }
3939     let m = k + 1;
3940     m
3941 }
3942 "#,
3943         );
3944     }
3945
3946     #[test]
3947     fn break_with_value() {
3948         check_assist(
3949             extract_function,
3950             r#"
3951 fn foo() -> i32 {
3952     loop {
3953         let n = 1;
3954         $0let k = 1;
3955         if k == 42 {
3956             break 3;
3957         }
3958         let m = k + 1;$0
3959         let h = 1;
3960     }
3961 }
3962 "#,
3963             r#"
3964 fn foo() -> i32 {
3965     loop {
3966         let n = 1;
3967         if let Some(value) = fun_name() {
3968             break value;
3969         }
3970         let h = 1;
3971     }
3972 }
3973
3974 fn $0fun_name() -> Option<i32> {
3975     let k = 1;
3976     if k == 42 {
3977         return Some(3);
3978     }
3979     let m = k + 1;
3980     None
3981 }
3982 "#,
3983         );
3984     }
3985
3986     #[test]
3987     fn break_with_value_and_label() {
3988         check_assist(
3989             extract_function,
3990             r#"
3991 fn foo() -> i32 {
3992     'bar: loop {
3993         let n = 1;
3994         $0let k = 1;
3995         if k == 42 {
3996             break 'bar 4;
3997         }
3998         let m = k + 1;$0
3999         let h = 1;
4000     }
4001 }
4002 "#,
4003             r#"
4004 fn foo() -> i32 {
4005     'bar: loop {
4006         let n = 1;
4007         if let Some(value) = fun_name() {
4008             break 'bar value;
4009         }
4010         let h = 1;
4011     }
4012 }
4013
4014 fn $0fun_name() -> Option<i32> {
4015     let k = 1;
4016     if k == 42 {
4017         return Some(4);
4018     }
4019     let m = k + 1;
4020     None
4021 }
4022 "#,
4023         );
4024     }
4025
4026     #[test]
4027     fn break_with_value_and_return() {
4028         check_assist(
4029             extract_function,
4030             r#"
4031 fn foo() -> i64 {
4032     loop {
4033         let n = 1;$0
4034         let k = 1;
4035         if k == 42 {
4036             break 3;
4037         }
4038         let m = k + 1;$0
4039         let h = 1 + m;
4040     }
4041 }
4042 "#,
4043             r#"
4044 fn foo() -> i64 {
4045     loop {
4046         let n = 1;
4047         let m = match fun_name() {
4048             Ok(value) => value,
4049             Err(value) => break value,
4050         };
4051         let h = 1 + m;
4052     }
4053 }
4054
4055 fn $0fun_name() -> Result<i32, i64> {
4056     let k = 1;
4057     if k == 42 {
4058         return Err(3);
4059     }
4060     let m = k + 1;
4061     Ok(m)
4062 }
4063 "#,
4064         );
4065     }
4066
4067     #[test]
4068     fn try_option() {
4069         check_assist(
4070             extract_function,
4071             r#"
4072 //- minicore: option
4073 fn bar() -> Option<i32> { None }
4074 fn foo() -> Option<()> {
4075     let n = bar()?;
4076     $0let k = foo()?;
4077     let m = k + 1;$0
4078     let h = 1 + m;
4079     Some(())
4080 }
4081 "#,
4082             r#"
4083 fn bar() -> Option<i32> { None }
4084 fn foo() -> Option<()> {
4085     let n = bar()?;
4086     let m = fun_name()?;
4087     let h = 1 + m;
4088     Some(())
4089 }
4090
4091 fn $0fun_name() -> Option<i32> {
4092     let k = foo()?;
4093     let m = k + 1;
4094     Some(m)
4095 }
4096 "#,
4097         );
4098     }
4099
4100     #[test]
4101     fn try_option_unit() {
4102         check_assist(
4103             extract_function,
4104             r#"
4105 //- minicore: option
4106 fn foo() -> Option<()> {
4107     let n = 1;
4108     $0let k = foo()?;
4109     let m = k + 1;$0
4110     let h = 1 + n;
4111     Some(())
4112 }
4113 "#,
4114             r#"
4115 fn foo() -> Option<()> {
4116     let n = 1;
4117     fun_name()?;
4118     let h = 1 + n;
4119     Some(())
4120 }
4121
4122 fn $0fun_name() -> Option<()> {
4123     let k = foo()?;
4124     let m = k + 1;
4125     Some(())
4126 }
4127 "#,
4128         );
4129     }
4130
4131     #[test]
4132     fn try_result() {
4133         check_assist(
4134             extract_function,
4135             r#"
4136 //- minicore: result
4137 fn foo() -> Result<(), i64> {
4138     let n = 1;
4139     $0let k = foo()?;
4140     let m = k + 1;$0
4141     let h = 1 + m;
4142     Ok(())
4143 }
4144 "#,
4145             r#"
4146 fn foo() -> Result<(), i64> {
4147     let n = 1;
4148     let m = fun_name()?;
4149     let h = 1 + m;
4150     Ok(())
4151 }
4152
4153 fn $0fun_name() -> Result<i32, i64> {
4154     let k = foo()?;
4155     let m = k + 1;
4156     Ok(m)
4157 }
4158 "#,
4159         );
4160     }
4161
4162     #[test]
4163     fn try_option_with_return() {
4164         check_assist(
4165             extract_function,
4166             r#"
4167 //- minicore: option
4168 fn foo() -> Option<()> {
4169     let n = 1;
4170     $0let k = foo()?;
4171     if k == 42 {
4172         return None;
4173     }
4174     let m = k + 1;$0
4175     let h = 1 + m;
4176     Some(())
4177 }
4178 "#,
4179             r#"
4180 fn foo() -> Option<()> {
4181     let n = 1;
4182     let m = fun_name()?;
4183     let h = 1 + m;
4184     Some(())
4185 }
4186
4187 fn $0fun_name() -> Option<i32> {
4188     let k = foo()?;
4189     if k == 42 {
4190         return None;
4191     }
4192     let m = k + 1;
4193     Some(m)
4194 }
4195 "#,
4196         );
4197     }
4198
4199     #[test]
4200     fn try_result_with_return() {
4201         check_assist(
4202             extract_function,
4203             r#"
4204 //- minicore: result
4205 fn foo() -> Result<(), i64> {
4206     let n = 1;
4207     $0let k = foo()?;
4208     if k == 42 {
4209         return Err(1);
4210     }
4211     let m = k + 1;$0
4212     let h = 1 + m;
4213     Ok(())
4214 }
4215 "#,
4216             r#"
4217 fn foo() -> Result<(), i64> {
4218     let n = 1;
4219     let m = fun_name()?;
4220     let h = 1 + m;
4221     Ok(())
4222 }
4223
4224 fn $0fun_name() -> Result<i32, i64> {
4225     let k = foo()?;
4226     if k == 42 {
4227         return Err(1);
4228     }
4229     let m = k + 1;
4230     Ok(m)
4231 }
4232 "#,
4233         );
4234     }
4235
4236     #[test]
4237     fn try_and_break() {
4238         cov_mark::check!(external_control_flow_try_and_bc);
4239         check_assist_not_applicable(
4240             extract_function,
4241             r#"
4242 //- minicore: option
4243 fn foo() -> Option<()> {
4244     loop {
4245         let n = Some(1);
4246         $0let m = n? + 1;
4247         break;
4248         let k = 2;
4249         let k = k + 1;$0
4250         let r = n + k;
4251     }
4252     Some(())
4253 }
4254 "#,
4255         );
4256     }
4257
4258     #[test]
4259     fn try_and_return_ok() {
4260         check_assist(
4261             extract_function,
4262             r#"
4263 //- minicore: result
4264 fn foo() -> Result<(), i64> {
4265     let n = 1;
4266     $0let k = foo()?;
4267     if k == 42 {
4268         return Ok(1);
4269     }
4270     let m = k + 1;$0
4271     let h = 1 + m;
4272     Ok(())
4273 }
4274 "#,
4275             r#"
4276 fn foo() -> Result<(), i64> {
4277     let n = 1;
4278     let m = fun_name()?;
4279     let h = 1 + m;
4280     Ok(())
4281 }
4282
4283 fn $0fun_name() -> Result<i32, i64> {
4284     let k = foo()?;
4285     if k == 42 {
4286         return Ok(1);
4287     }
4288     let m = k + 1;
4289     Ok(m)
4290 }
4291 "#,
4292         );
4293     }
4294
4295     #[test]
4296     fn param_usage_in_macro() {
4297         check_assist(
4298             extract_function,
4299             r#"
4300 macro_rules! m {
4301     ($val:expr) => { $val };
4302 }
4303
4304 fn foo() {
4305     let n = 1;
4306     $0let k = n * m!(n);$0
4307     let m = k + 1;
4308 }
4309 "#,
4310             r#"
4311 macro_rules! m {
4312     ($val:expr) => { $val };
4313 }
4314
4315 fn foo() {
4316     let n = 1;
4317     let k = fun_name(n);
4318     let m = k + 1;
4319 }
4320
4321 fn $0fun_name(n: i32) -> i32 {
4322     let k = n * m!(n);
4323     k
4324 }
4325 "#,
4326         );
4327     }
4328
4329     #[test]
4330     fn extract_with_await() {
4331         check_assist(
4332             extract_function,
4333             r#"
4334 //- minicore: future
4335 fn main() {
4336     $0some_function().await;$0
4337 }
4338
4339 async fn some_function() {
4340
4341 }
4342 "#,
4343             r#"
4344 fn main() {
4345     fun_name().await;
4346 }
4347
4348 async fn $0fun_name() {
4349     some_function().await;
4350 }
4351
4352 async fn some_function() {
4353
4354 }
4355 "#,
4356         );
4357     }
4358
4359     #[test]
4360     fn extract_with_await_and_result_not_producing_match_expr() {
4361         check_assist(
4362             extract_function,
4363             r#"
4364 //- minicore: future, result
4365 async fn foo() -> Result<(), ()> {
4366     $0async {}.await;
4367     Err(())?$0
4368 }
4369 "#,
4370             r#"
4371 async fn foo() -> Result<(), ()> {
4372     fun_name().await?
4373 }
4374
4375 async fn $0fun_name() -> Result<(), ()> {
4376     async {}.await;
4377     Err(())?
4378 }
4379 "#,
4380         );
4381     }
4382
4383     #[test]
4384     fn extract_with_await_and_result_producing_match_expr() {
4385         check_assist(
4386             extract_function,
4387             r#"
4388 //- minicore: future
4389 async fn foo() -> i32 {
4390     loop {
4391         let n = 1;$0
4392         let k = async { 1 }.await;
4393         if k == 42 {
4394             break 3;
4395         }
4396         let m = k + 1;$0
4397         let h = 1 + m;
4398     }
4399 }
4400 "#,
4401             r#"
4402 async fn foo() -> i32 {
4403     loop {
4404         let n = 1;
4405         let m = match fun_name().await {
4406             Ok(value) => value,
4407             Err(value) => break value,
4408         };
4409         let h = 1 + m;
4410     }
4411 }
4412
4413 async fn $0fun_name() -> Result<i32, i32> {
4414     let k = async { 1 }.await;
4415     if k == 42 {
4416         return Err(3);
4417     }
4418     let m = k + 1;
4419     Ok(m)
4420 }
4421 "#,
4422         );
4423     }
4424
4425     #[test]
4426     fn extract_with_await_in_args() {
4427         check_assist(
4428             extract_function,
4429             r#"
4430 //- minicore: future
4431 fn main() {
4432     $0function_call("a", some_function().await);$0
4433 }
4434
4435 async fn some_function() {
4436
4437 }
4438 "#,
4439             r#"
4440 fn main() {
4441     fun_name().await;
4442 }
4443
4444 async fn $0fun_name() {
4445     function_call("a", some_function().await);
4446 }
4447
4448 async fn some_function() {
4449
4450 }
4451 "#,
4452         );
4453     }
4454
4455     #[test]
4456     fn extract_does_not_extract_standalone_blocks() {
4457         check_assist_not_applicable(
4458             extract_function,
4459             r#"
4460 fn main() $0{}$0
4461 "#,
4462         );
4463     }
4464
4465     #[test]
4466     fn extract_adds_comma_for_match_arm() {
4467         check_assist(
4468             extract_function,
4469             r#"
4470 fn main() {
4471     match 6 {
4472         100 => $0{ 100 }$0
4473         _ => 0,
4474     };
4475 }
4476 "#,
4477             r#"
4478 fn main() {
4479     match 6 {
4480         100 => fun_name(),
4481         _ => 0,
4482     };
4483 }
4484
4485 fn $0fun_name() -> i32 {
4486     100
4487 }
4488 "#,
4489         );
4490         check_assist(
4491             extract_function,
4492             r#"
4493 fn main() {
4494     match 6 {
4495         100 => $0{ 100 }$0,
4496         _ => 0,
4497     };
4498 }
4499 "#,
4500             r#"
4501 fn main() {
4502     match 6 {
4503         100 => fun_name(),
4504         _ => 0,
4505     };
4506 }
4507
4508 fn $0fun_name() -> i32 {
4509     100
4510 }
4511 "#,
4512         );
4513     }
4514
4515     #[test]
4516     fn extract_does_not_tear_comments_apart() {
4517         check_assist(
4518             extract_function,
4519             r#"
4520 fn foo() {
4521     /*$0*/
4522     foo();
4523     foo();
4524     /*$0*/
4525 }
4526 "#,
4527             r#"
4528 fn foo() {
4529     fun_name();
4530 }
4531
4532 fn $0fun_name() {
4533     /**/
4534     foo();
4535     foo();
4536     /**/
4537 }
4538 "#,
4539         );
4540     }
4541
4542     #[test]
4543     fn extract_does_not_tear_body_apart() {
4544         check_assist(
4545             extract_function,
4546             r#"
4547 fn foo() {
4548     $0foo();
4549 }$0
4550 "#,
4551             r#"
4552 fn foo() {
4553     fun_name();
4554 }
4555
4556 fn $0fun_name() {
4557     foo();
4558 }
4559 "#,
4560         );
4561     }
4562
4563     #[test]
4564     fn extract_does_not_wrap_res_in_res() {
4565         check_assist(
4566             extract_function,
4567             r#"
4568 //- minicore: result
4569 fn foo() -> Result<(), i64> {
4570     $0Result::<i32, i64>::Ok(0)?;
4571     Ok(())$0
4572 }
4573 "#,
4574             r#"
4575 fn foo() -> Result<(), i64> {
4576     fun_name()?
4577 }
4578
4579 fn $0fun_name() -> Result<(), i64> {
4580     Result::<i32, i64>::Ok(0)?;
4581     Ok(())
4582 }
4583 "#,
4584         );
4585     }
4586
4587     #[test]
4588     fn extract_knows_const() {
4589         check_assist(
4590             extract_function,
4591             r#"
4592 const fn foo() {
4593     $0()$0
4594 }
4595 "#,
4596             r#"
4597 const fn foo() {
4598     fun_name();
4599 }
4600
4601 const fn $0fun_name() {
4602     ()
4603 }
4604 "#,
4605         );
4606         check_assist(
4607             extract_function,
4608             r#"
4609 const FOO: () = {
4610     $0()$0
4611 };
4612 "#,
4613             r#"
4614 const FOO: () = {
4615     fun_name();
4616 };
4617
4618 const fn $0fun_name() {
4619     ()
4620 }
4621 "#,
4622         );
4623     }
4624
4625     #[test]
4626     fn extract_does_not_move_outer_loop_vars() {
4627         check_assist(
4628             extract_function,
4629             r#"
4630 fn foo() {
4631     let mut x = 5;
4632     for _ in 0..10 {
4633         $0x += 1;$0
4634     }
4635 }
4636 "#,
4637             r#"
4638 fn foo() {
4639     let mut x = 5;
4640     for _ in 0..10 {
4641         fun_name(&mut x);
4642     }
4643 }
4644
4645 fn $0fun_name(x: &mut i32) {
4646     *x += 1;
4647 }
4648 "#,
4649         );
4650         check_assist(
4651             extract_function,
4652             r#"
4653 fn foo() {
4654     for _ in 0..10 {
4655         let mut x = 5;
4656         $0x += 1;$0
4657     }
4658 }
4659 "#,
4660             r#"
4661 fn foo() {
4662     for _ in 0..10 {
4663         let mut x = 5;
4664         fun_name(x);
4665     }
4666 }
4667
4668 fn $0fun_name(mut x: i32) {
4669     x += 1;
4670 }
4671 "#,
4672         );
4673         check_assist(
4674             extract_function,
4675             r#"
4676 fn foo() {
4677     loop {
4678         let mut x = 5;
4679         for _ in 0..10 {
4680             $0x += 1;$0
4681         }
4682     }
4683 }
4684 "#,
4685             r#"
4686 fn foo() {
4687     loop {
4688         let mut x = 5;
4689         for _ in 0..10 {
4690             fun_name(&mut x);
4691         }
4692     }
4693 }
4694
4695 fn $0fun_name(x: &mut i32) {
4696     *x += 1;
4697 }
4698 "#,
4699         );
4700     }
4701
4702     // regression test for #9822
4703     #[test]
4704     fn extract_mut_ref_param_has_no_mut_binding_in_loop() {
4705         check_assist(
4706             extract_function,
4707             r#"
4708 struct Foo;
4709 impl Foo {
4710     fn foo(&mut self) {}
4711 }
4712 fn foo() {
4713     let mut x = Foo;
4714     while false {
4715         let y = &mut x;
4716         $0y.foo();$0
4717     }
4718     let z = x;
4719 }
4720 "#,
4721             r#"
4722 struct Foo;
4723 impl Foo {
4724     fn foo(&mut self) {}
4725 }
4726 fn foo() {
4727     let mut x = Foo;
4728     while false {
4729         let y = &mut x;
4730         fun_name(y);
4731     }
4732     let z = x;
4733 }
4734
4735 fn $0fun_name(y: &mut Foo) {
4736     y.foo();
4737 }
4738 "#,
4739         );
4740     }
4741
4742     #[test]
4743     fn extract_with_macro_arg() {
4744         check_assist(
4745             extract_function,
4746             r#"
4747 macro_rules! m {
4748     ($val:expr) => { $val };
4749 }
4750 fn main() {
4751     let bar = "bar";
4752     $0m!(bar);$0
4753 }
4754 "#,
4755             r#"
4756 macro_rules! m {
4757     ($val:expr) => { $val };
4758 }
4759 fn main() {
4760     let bar = "bar";
4761     fun_name(bar);
4762 }
4763
4764 fn $0fun_name(bar: &str) {
4765     m!(bar);
4766 }
4767 "#,
4768         );
4769     }
4770
4771     #[test]
4772     fn unresolveable_types_default_to_placeholder() {
4773         check_assist(
4774             extract_function,
4775             r#"
4776 fn foo() {
4777     let a = __unresolved;
4778     let _ = $0{a}$0;
4779 }
4780 "#,
4781             r#"
4782 fn foo() {
4783     let a = __unresolved;
4784     let _ = fun_name(a);
4785 }
4786
4787 fn $0fun_name(a: _) -> _ {
4788     a
4789 }
4790 "#,
4791         );
4792     }
4793
4794     #[test]
4795     fn reference_mutable_param_with_further_usages() {
4796         check_assist(
4797             extract_function,
4798             r#"
4799 pub struct Foo {
4800     field: u32,
4801 }
4802
4803 pub fn testfn(arg: &mut Foo) {
4804     $0arg.field = 8;$0
4805     // Simulating access after the extracted portion
4806     arg.field = 16;
4807 }
4808 "#,
4809             r#"
4810 pub struct Foo {
4811     field: u32,
4812 }
4813
4814 pub fn testfn(arg: &mut Foo) {
4815     fun_name(arg);
4816     // Simulating access after the extracted portion
4817     arg.field = 16;
4818 }
4819
4820 fn $0fun_name(arg: &mut Foo) {
4821     arg.field = 8;
4822 }
4823 "#,
4824         );
4825     }
4826
4827     #[test]
4828     fn reference_mutable_param_without_further_usages() {
4829         check_assist(
4830             extract_function,
4831             r#"
4832 pub struct Foo {
4833     field: u32,
4834 }
4835
4836 pub fn testfn(arg: &mut Foo) {
4837     $0arg.field = 8;$0
4838 }
4839 "#,
4840             r#"
4841 pub struct Foo {
4842     field: u32,
4843 }
4844
4845 pub fn testfn(arg: &mut Foo) {
4846     fun_name(arg);
4847 }
4848
4849 fn $0fun_name(arg: &mut Foo) {
4850     arg.field = 8;
4851 }
4852 "#,
4853         );
4854     }
4855
4856     #[test]
4857     fn extract_function_copies_comment_at_start() {
4858         check_assist(
4859             extract_function,
4860             r#"
4861 fn func() {
4862     let i = 0;
4863     $0// comment here!
4864     let x = 0;$0
4865 }
4866 "#,
4867             r#"
4868 fn func() {
4869     let i = 0;
4870     fun_name();
4871 }
4872
4873 fn $0fun_name() {
4874     // comment here!
4875     let x = 0;
4876 }
4877 "#,
4878         );
4879     }
4880
4881     #[test]
4882     fn extract_function_copies_comment_in_between() {
4883         check_assist(
4884             extract_function,
4885             r#"
4886 fn func() {
4887     let i = 0;$0
4888     let a = 0;
4889     // comment here!
4890     let x = 0;$0
4891 }
4892 "#,
4893             r#"
4894 fn func() {
4895     let i = 0;
4896     fun_name();
4897 }
4898
4899 fn $0fun_name() {
4900     let a = 0;
4901     // comment here!
4902     let x = 0;
4903 }
4904 "#,
4905         );
4906     }
4907
4908     #[test]
4909     fn extract_function_copies_comment_at_end() {
4910         check_assist(
4911             extract_function,
4912             r#"
4913 fn func() {
4914     let i = 0;
4915     $0let x = 0;
4916     // comment here!$0
4917 }
4918 "#,
4919             r#"
4920 fn func() {
4921     let i = 0;
4922     fun_name();
4923 }
4924
4925 fn $0fun_name() {
4926     let x = 0;
4927     // comment here!
4928 }
4929 "#,
4930         );
4931     }
4932
4933     #[test]
4934     fn extract_function_copies_comment_indented() {
4935         check_assist(
4936             extract_function,
4937             r#"
4938 fn func() {
4939     let i = 0;
4940     $0let x = 0;
4941     while(true) {
4942         // comment here!
4943     }$0
4944 }
4945 "#,
4946             r#"
4947 fn func() {
4948     let i = 0;
4949     fun_name();
4950 }
4951
4952 fn $0fun_name() {
4953     let x = 0;
4954     while(true) {
4955         // comment here!
4956     }
4957 }
4958 "#,
4959         );
4960     }
4961
4962     // FIXME: we do want to preserve whitespace
4963     #[test]
4964     fn extract_function_does_not_preserve_whitespace() {
4965         check_assist(
4966             extract_function,
4967             r#"
4968 fn func() {
4969     let i = 0;
4970     $0let a = 0;
4971
4972     let x = 0;$0
4973 }
4974 "#,
4975             r#"
4976 fn func() {
4977     let i = 0;
4978     fun_name();
4979 }
4980
4981 fn $0fun_name() {
4982     let a = 0;
4983     let x = 0;
4984 }
4985 "#,
4986         );
4987     }
4988
4989     #[test]
4990     fn extract_function_long_form_comment() {
4991         check_assist(
4992             extract_function,
4993             r#"
4994 fn func() {
4995     let i = 0;
4996     $0/* a comment */
4997     let x = 0;$0
4998 }
4999 "#,
5000             r#"
5001 fn func() {
5002     let i = 0;
5003     fun_name();
5004 }
5005
5006 fn $0fun_name() {
5007     /* a comment */
5008     let x = 0;
5009 }
5010 "#,
5011         );
5012     }
5013
5014     #[test]
5015     fn it_should_not_generate_duplicate_function_names() {
5016         check_assist(
5017             extract_function,
5018             r#"
5019 fn fun_name() {
5020     $0let x = 0;$0
5021 }
5022 "#,
5023             r#"
5024 fn fun_name() {
5025     fun_name1();
5026 }
5027
5028 fn $0fun_name1() {
5029     let x = 0;
5030 }
5031 "#,
5032         );
5033     }
5034
5035     #[test]
5036     fn should_increment_suffix_until_it_finds_space() {
5037         check_assist(
5038             extract_function,
5039             r#"
5040 fn fun_name1() {
5041     let y = 0;
5042 }
5043
5044 fn fun_name() {
5045     $0let x = 0;$0
5046 }
5047 "#,
5048             r#"
5049 fn fun_name1() {
5050     let y = 0;
5051 }
5052
5053 fn fun_name() {
5054     fun_name2();
5055 }
5056
5057 fn $0fun_name2() {
5058     let x = 0;
5059 }
5060 "#,
5061         );
5062     }
5063
5064     #[test]
5065     fn extract_method_from_trait_impl() {
5066         check_assist(
5067             extract_function,
5068             r#"
5069 struct Struct(i32);
5070 trait Trait {
5071     fn bar(&self) -> i32;
5072 }
5073
5074 impl Trait for Struct {
5075     fn bar(&self) -> i32 {
5076         $0self.0 + 2$0
5077     }
5078 }
5079 "#,
5080             r#"
5081 struct Struct(i32);
5082 trait Trait {
5083     fn bar(&self) -> i32;
5084 }
5085
5086 impl Trait for Struct {
5087     fn bar(&self) -> i32 {
5088         self.fun_name()
5089     }
5090 }
5091
5092 impl Struct {
5093     fn $0fun_name(&self) -> i32 {
5094         self.0 + 2
5095     }
5096 }
5097 "#,
5098         );
5099     }
5100
5101     #[test]
5102     fn extract_method_from_trait_with_existing_non_empty_impl_block() {
5103         check_assist(
5104             extract_function,
5105             r#"
5106 struct Struct(i32);
5107 trait Trait {
5108     fn bar(&self) -> i32;
5109 }
5110
5111 impl Struct {
5112     fn foo() {}
5113 }
5114
5115 impl Trait for Struct {
5116     fn bar(&self) -> i32 {
5117         $0self.0 + 2$0
5118     }
5119 }
5120 "#,
5121             r#"
5122 struct Struct(i32);
5123 trait Trait {
5124     fn bar(&self) -> i32;
5125 }
5126
5127 impl Struct {
5128     fn foo() {}
5129
5130     fn $0fun_name(&self) -> i32 {
5131         self.0 + 2
5132     }
5133 }
5134
5135 impl Trait for Struct {
5136     fn bar(&self) -> i32 {
5137         self.fun_name()
5138     }
5139 }
5140 "#,
5141         )
5142     }
5143
5144     #[test]
5145     fn extract_function_from_trait_with_existing_non_empty_impl_block() {
5146         check_assist(
5147             extract_function,
5148             r#"
5149 struct Struct(i32);
5150 trait Trait {
5151     fn bar(&self) -> i32;
5152 }
5153
5154 impl Struct {
5155     fn foo() {}
5156 }
5157
5158 impl Trait for Struct {
5159     fn bar(&self) -> i32 {
5160         let three_squared = $03 * 3$0;
5161         self.0 + three_squared
5162     }
5163 }
5164 "#,
5165             r#"
5166 struct Struct(i32);
5167 trait Trait {
5168     fn bar(&self) -> i32;
5169 }
5170
5171 impl Struct {
5172     fn foo() {}
5173 }
5174
5175 impl Trait for Struct {
5176     fn bar(&self) -> i32 {
5177         let three_squared = fun_name();
5178         self.0 + three_squared
5179     }
5180 }
5181
5182 fn $0fun_name() -> i32 {
5183     3 * 3
5184 }
5185 "#,
5186         )
5187     }
5188
5189     #[test]
5190     fn extract_method_from_trait_with_multiple_existing_impl_blocks() {
5191         check_assist(
5192             extract_function,
5193             r#"
5194 struct Struct(i32);
5195 struct StructBefore(i32);
5196 struct StructAfter(i32);
5197 trait Trait {
5198     fn bar(&self) -> i32;
5199 }
5200
5201 impl StructBefore {
5202     fn foo(){}
5203 }
5204
5205 impl Struct {
5206     fn foo(){}
5207 }
5208
5209 impl StructAfter {
5210     fn foo(){}
5211 }
5212
5213 impl Trait for Struct {
5214     fn bar(&self) -> i32 {
5215         $0self.0 + 2$0
5216     }
5217 }
5218 "#,
5219             r#"
5220 struct Struct(i32);
5221 struct StructBefore(i32);
5222 struct StructAfter(i32);
5223 trait Trait {
5224     fn bar(&self) -> i32;
5225 }
5226
5227 impl StructBefore {
5228     fn foo(){}
5229 }
5230
5231 impl Struct {
5232     fn foo(){}
5233
5234     fn $0fun_name(&self) -> i32 {
5235         self.0 + 2
5236     }
5237 }
5238
5239 impl StructAfter {
5240     fn foo(){}
5241 }
5242
5243 impl Trait for Struct {
5244     fn bar(&self) -> i32 {
5245         self.fun_name()
5246     }
5247 }
5248 "#,
5249         )
5250     }
5251
5252     #[test]
5253     fn extract_method_from_trait_with_multiple_existing_trait_impl_blocks() {
5254         check_assist(
5255             extract_function,
5256             r#"
5257 struct Struct(i32);
5258 trait Trait {
5259     fn bar(&self) -> i32;
5260 }
5261 trait TraitBefore {
5262     fn before(&self) -> i32;
5263 }
5264 trait TraitAfter {
5265     fn after(&self) -> i32;
5266 }
5267
5268 impl TraitBefore for Struct {
5269     fn before(&self) -> i32 {
5270         42
5271     }
5272 }
5273
5274 impl Struct {
5275     fn foo(){}
5276 }
5277
5278 impl TraitAfter for Struct {
5279     fn after(&self) -> i32 {
5280         42
5281     }
5282 }
5283
5284 impl Trait for Struct {
5285     fn bar(&self) -> i32 {
5286         $0self.0 + 2$0
5287     }
5288 }
5289 "#,
5290             r#"
5291 struct Struct(i32);
5292 trait Trait {
5293     fn bar(&self) -> i32;
5294 }
5295 trait TraitBefore {
5296     fn before(&self) -> i32;
5297 }
5298 trait TraitAfter {
5299     fn after(&self) -> i32;
5300 }
5301
5302 impl TraitBefore for Struct {
5303     fn before(&self) -> i32 {
5304         42
5305     }
5306 }
5307
5308 impl Struct {
5309     fn foo(){}
5310
5311     fn $0fun_name(&self) -> i32 {
5312         self.0 + 2
5313     }
5314 }
5315
5316 impl TraitAfter for Struct {
5317     fn after(&self) -> i32 {
5318         42
5319     }
5320 }
5321
5322 impl Trait for Struct {
5323     fn bar(&self) -> i32 {
5324         self.fun_name()
5325     }
5326 }
5327 "#,
5328         )
5329     }
5330
5331     #[test]
5332     fn closure_arguments() {
5333         check_assist(
5334             extract_function,
5335             r#"
5336 fn parent(factor: i32) {
5337     let v = &[1, 2, 3];
5338
5339     $0v.iter().map(|it| it * factor);$0
5340 }
5341 "#,
5342             r#"
5343 fn parent(factor: i32) {
5344     let v = &[1, 2, 3];
5345
5346     fun_name(v, factor);
5347 }
5348
5349 fn $0fun_name(v: &[i32; 3], factor: i32) {
5350     v.iter().map(|it| it * factor);
5351 }
5352 "#,
5353         );
5354     }
5355
5356     #[test]
5357     fn preserve_generics() {
5358         check_assist(
5359             extract_function,
5360             r#"
5361 fn func<T: Debug>(i: T) {
5362     $0foo(i);$0
5363 }
5364 "#,
5365             r#"
5366 fn func<T: Debug>(i: T) {
5367     fun_name(i);
5368 }
5369
5370 fn $0fun_name<T: Debug>(i: T) {
5371     foo(i);
5372 }
5373 "#,
5374         );
5375     }
5376
5377     #[test]
5378     fn preserve_generics_from_body() {
5379         check_assist(
5380             extract_function,
5381             r#"
5382 fn func<T: Default>() -> T {
5383     $0T::default()$0
5384 }
5385 "#,
5386             r#"
5387 fn func<T: Default>() -> T {
5388     fun_name()
5389 }
5390
5391 fn $0fun_name<T: Default>() -> T {
5392     T::default()
5393 }
5394 "#,
5395         );
5396     }
5397
5398     #[test]
5399     fn filter_unused_generics() {
5400         check_assist(
5401             extract_function,
5402             r#"
5403 fn func<T: Debug, U: Copy>(i: T, u: U) {
5404     bar(u);
5405     $0foo(i);$0
5406 }
5407 "#,
5408             r#"
5409 fn func<T: Debug, U: Copy>(i: T, u: U) {
5410     bar(u);
5411     fun_name(i);
5412 }
5413
5414 fn $0fun_name<T: Debug>(i: T) {
5415     foo(i);
5416 }
5417 "#,
5418         );
5419     }
5420
5421     #[test]
5422     fn empty_generic_param_list() {
5423         check_assist(
5424             extract_function,
5425             r#"
5426 fn func<T: Debug>(t: T, i: u32) {
5427     bar(t);
5428     $0foo(i);$0
5429 }
5430 "#,
5431             r#"
5432 fn func<T: Debug>(t: T, i: u32) {
5433     bar(t);
5434     fun_name(i);
5435 }
5436
5437 fn $0fun_name(i: u32) {
5438     foo(i);
5439 }
5440 "#,
5441         );
5442     }
5443
5444     #[test]
5445     fn preserve_where_clause() {
5446         check_assist(
5447             extract_function,
5448             r#"
5449 fn func<T>(i: T) where T: Debug {
5450     $0foo(i);$0
5451 }
5452 "#,
5453             r#"
5454 fn func<T>(i: T) where T: Debug {
5455     fun_name(i);
5456 }
5457
5458 fn $0fun_name<T>(i: T) where T: Debug {
5459     foo(i);
5460 }
5461 "#,
5462         );
5463     }
5464
5465     #[test]
5466     fn filter_unused_where_clause() {
5467         check_assist(
5468             extract_function,
5469             r#"
5470 fn func<T, U>(i: T, u: U) where T: Debug, U: Copy {
5471     bar(u);
5472     $0foo(i);$0
5473 }
5474 "#,
5475             r#"
5476 fn func<T, U>(i: T, u: U) where T: Debug, U: Copy {
5477     bar(u);
5478     fun_name(i);
5479 }
5480
5481 fn $0fun_name<T>(i: T) where T: Debug {
5482     foo(i);
5483 }
5484 "#,
5485         );
5486     }
5487
5488     #[test]
5489     fn nested_generics() {
5490         check_assist(
5491             extract_function,
5492             r#"
5493 struct Struct<T: Into<i32>>(T);
5494 impl <T: Into<i32> + Copy> Struct<T> {
5495     fn func<V: Into<i32>>(&self, v: V) -> i32 {
5496         let t = self.0;
5497         $0t.into() + v.into()$0
5498     }
5499 }
5500 "#,
5501             r#"
5502 struct Struct<T: Into<i32>>(T);
5503 impl <T: Into<i32> + Copy> Struct<T> {
5504     fn func<V: Into<i32>>(&self, v: V) -> i32 {
5505         let t = self.0;
5506         fun_name(t, v)
5507     }
5508 }
5509
5510 fn $0fun_name<T: Into<i32> + Copy, V: Into<i32>>(t: T, v: V) -> i32 {
5511     t.into() + v.into()
5512 }
5513 "#,
5514         );
5515     }
5516
5517     #[test]
5518     fn filters_unused_nested_generics() {
5519         check_assist(
5520             extract_function,
5521             r#"
5522 struct Struct<T: Into<i32>, U: Debug>(T, U);
5523 impl <T: Into<i32> + Copy, U: Debug> Struct<T, U> {
5524     fn func<V: Into<i32>>(&self, v: V) -> i32 {
5525         let t = self.0;
5526         $0t.into() + v.into()$0
5527     }
5528 }
5529 "#,
5530             r#"
5531 struct Struct<T: Into<i32>, U: Debug>(T, U);
5532 impl <T: Into<i32> + Copy, U: Debug> Struct<T, U> {
5533     fn func<V: Into<i32>>(&self, v: V) -> i32 {
5534         let t = self.0;
5535         fun_name(t, v)
5536     }
5537 }
5538
5539 fn $0fun_name<T: Into<i32> + Copy, V: Into<i32>>(t: T, v: V) -> i32 {
5540     t.into() + v.into()
5541 }
5542 "#,
5543         );
5544     }
5545
5546     #[test]
5547     fn nested_where_clauses() {
5548         check_assist(
5549             extract_function,
5550             r#"
5551 struct Struct<T>(T) where T: Into<i32>;
5552 impl <T> Struct<T> where T: Into<i32> + Copy {
5553     fn func<V>(&self, v: V) -> i32 where V: Into<i32> {
5554         let t = self.0;
5555         $0t.into() + v.into()$0
5556     }
5557 }
5558 "#,
5559             r#"
5560 struct Struct<T>(T) where T: Into<i32>;
5561 impl <T> Struct<T> where T: Into<i32> + Copy {
5562     fn func<V>(&self, v: V) -> i32 where V: Into<i32> {
5563         let t = self.0;
5564         fun_name(t, v)
5565     }
5566 }
5567
5568 fn $0fun_name<T, V>(t: T, v: V) -> i32 where T: Into<i32> + Copy, V: Into<i32> {
5569     t.into() + v.into()
5570 }
5571 "#,
5572         );
5573     }
5574
5575     #[test]
5576     fn filters_unused_nested_where_clauses() {
5577         check_assist(
5578             extract_function,
5579             r#"
5580 struct Struct<T, U>(T, U) where T: Into<i32>, U: Debug;
5581 impl <T, U> Struct<T, U> where T: Into<i32> + Copy, U: Debug {
5582     fn func<V>(&self, v: V) -> i32 where V: Into<i32> {
5583         let t = self.0;
5584         $0t.into() + v.into()$0
5585     }
5586 }
5587 "#,
5588             r#"
5589 struct Struct<T, U>(T, U) where T: Into<i32>, U: Debug;
5590 impl <T, U> Struct<T, U> where T: Into<i32> + Copy, U: Debug {
5591     fn func<V>(&self, v: V) -> i32 where V: Into<i32> {
5592         let t = self.0;
5593         fun_name(t, v)
5594     }
5595 }
5596
5597 fn $0fun_name<T, V>(t: T, v: V) -> i32 where T: Into<i32> + Copy, V: Into<i32> {
5598     t.into() + v.into()
5599 }
5600 "#,
5601         );
5602     }
5603 }