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