aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/handlers/add_new.rs56
-rw-r--r--crates/ra_assists/src/handlers/auto_import.rs7
-rw-r--r--crates/ra_assists/src/handlers/change_return_type_to_result.rs98
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/ra_assists/src/tests/generated.rs4
-rw-r--r--crates/ra_assists/src/utils/insert_use.rs6
-rw-r--r--docs/user/assists.md4
7 files changed, 85 insertions, 92 deletions
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs
index fe7451dcf..837aa8377 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/add_new.rs
@@ -3,7 +3,7 @@ use ra_syntax::{
3 ast::{ 3 ast::{
4 self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, 4 self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner,
5 }, 5 },
6 TextSize, T, 6 T,
7}; 7};
8use stdx::{format_to, SepBy}; 8use stdx::{format_to, SepBy};
9 9
@@ -25,7 +25,7 @@ use crate::{AssistContext, AssistId, Assists};
25// } 25// }
26// 26//
27// impl<T: Clone> Ctx<T> { 27// impl<T: Clone> Ctx<T> {
28// fn new(data: T) -> Self { Self { data } } 28// fn $0new(data: T) -> Self { Self { data } }
29// } 29// }
30// 30//
31// ``` 31// ```
@@ -42,31 +42,26 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
42 let impl_def = find_struct_impl(&ctx, &strukt)?; 42 let impl_def = find_struct_impl(&ctx, &strukt)?;
43 43
44 let target = strukt.syntax().text_range(); 44 let target = strukt.syntax().text_range();
45 acc.add(AssistId("add_new"), "Add default constructor", target, |edit| { 45 acc.add(AssistId("add_new"), "Add default constructor", target, |builder| {
46 let mut buf = String::with_capacity(512); 46 let mut buf = String::with_capacity(512);
47 47
48 if impl_def.is_some() { 48 if impl_def.is_some() {
49 buf.push('\n'); 49 buf.push('\n');
50 } 50 }
51 51
52 let vis = strukt.visibility().map(|v| format!("{} ", v)); 52 let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
53 let vis = vis.as_deref().unwrap_or("");
54 53
55 let params = field_list 54 let params = field_list
56 .fields() 55 .fields()
57 .filter_map(|f| { 56 .filter_map(|f| {
58 Some(format!( 57 Some(format!("{}: {}", f.name()?.syntax(), f.ascribed_type()?.syntax()))
59 "{}: {}",
60 f.name()?.syntax().text(),
61 f.ascribed_type()?.syntax().text()
62 ))
63 }) 58 })
64 .sep_by(", "); 59 .sep_by(", ");
65 let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); 60 let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", ");
66 61
67 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); 62 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
68 63
69 let (start_offset, end_offset) = impl_def 64 let start_offset = impl_def
70 .and_then(|impl_def| { 65 .and_then(|impl_def| {
71 buf.push('\n'); 66 buf.push('\n');
72 let start = impl_def 67 let start = impl_def
@@ -76,17 +71,20 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
76 .text_range() 71 .text_range()
77 .end(); 72 .end();
78 73
79 Some((start, TextSize::of("\n"))) 74 Some(start)
80 }) 75 })
81 .unwrap_or_else(|| { 76 .unwrap_or_else(|| {
82 buf = generate_impl_text(&strukt, &buf); 77 buf = generate_impl_text(&strukt, &buf);
83 let start = strukt.syntax().text_range().end(); 78 strukt.syntax().text_range().end()
84
85 (start, TextSize::of("\n}\n"))
86 }); 79 });
87 80
88 edit.set_cursor(start_offset + TextSize::of(&buf) - end_offset); 81 match ctx.config.snippet_cap {
89 edit.insert(start_offset, buf); 82 None => builder.insert(start_offset, buf),
83 Some(cap) => {
84 buf = buf.replace("fn new", "fn $0new");
85 builder.insert_snippet(cap, start_offset, buf);
86 }
87 }
90 }) 88 })
91} 89}
92 90
@@ -191,7 +189,7 @@ mod tests {
191"struct Foo {} 189"struct Foo {}
192 190
193impl Foo { 191impl Foo {
194 fn new() -> Self { Self { } }<|> 192 fn $0new() -> Self { Self { } }
195} 193}
196", 194",
197 ); 195 );
@@ -201,7 +199,7 @@ impl Foo {
201"struct Foo<T: Clone> {} 199"struct Foo<T: Clone> {}
202 200
203impl<T: Clone> Foo<T> { 201impl<T: Clone> Foo<T> {
204 fn new() -> Self { Self { } }<|> 202 fn $0new() -> Self { Self { } }
205} 203}
206", 204",
207 ); 205 );
@@ -211,7 +209,7 @@ impl<T: Clone> Foo<T> {
211"struct Foo<'a, T: Foo<'a>> {} 209"struct Foo<'a, T: Foo<'a>> {}
212 210
213impl<'a, T: Foo<'a>> Foo<'a, T> { 211impl<'a, T: Foo<'a>> Foo<'a, T> {
214 fn new() -> Self { Self { } }<|> 212 fn $0new() -> Self { Self { } }
215} 213}
216", 214",
217 ); 215 );
@@ -221,7 +219,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> {
221"struct Foo { baz: String } 219"struct Foo { baz: String }
222 220
223impl Foo { 221impl Foo {
224 fn new(baz: String) -> Self { Self { baz } }<|> 222 fn $0new(baz: String) -> Self { Self { baz } }
225} 223}
226", 224",
227 ); 225 );
@@ -231,7 +229,7 @@ impl Foo {
231"struct Foo { baz: String, qux: Vec<i32> } 229"struct Foo { baz: String, qux: Vec<i32> }
232 230
233impl Foo { 231impl Foo {
234 fn new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }<|> 232 fn $0new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }
235} 233}
236", 234",
237 ); 235 );
@@ -243,7 +241,7 @@ impl Foo {
243"struct Foo { pub baz: String, pub qux: Vec<i32> } 241"struct Foo { pub baz: String, pub qux: Vec<i32> }
244 242
245impl Foo { 243impl Foo {
246 fn new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }<|> 244 fn $0new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }
247} 245}
248", 246",
249 ); 247 );
@@ -258,7 +256,7 @@ impl Foo {}
258"struct Foo {} 256"struct Foo {}
259 257
260impl Foo { 258impl Foo {
261 fn new() -> Self { Self { } }<|> 259 fn $0new() -> Self { Self { } }
262} 260}
263", 261",
264 ); 262 );
@@ -273,7 +271,7 @@ impl Foo {
273"struct Foo {} 271"struct Foo {}
274 272
275impl Foo { 273impl Foo {
276 fn new() -> Self { Self { } }<|> 274 fn $0new() -> Self { Self { } }
277 275
278 fn qux(&self) {} 276 fn qux(&self) {}
279} 277}
@@ -294,7 +292,7 @@ impl Foo {
294"struct Foo {} 292"struct Foo {}
295 293
296impl Foo { 294impl Foo {
297 fn new() -> Self { Self { } }<|> 295 fn $0new() -> Self { Self { } }
298 296
299 fn qux(&self) {} 297 fn qux(&self) {}
300 fn baz() -> i32 { 298 fn baz() -> i32 {
@@ -311,7 +309,7 @@ impl Foo {
311"pub struct Foo {} 309"pub struct Foo {}
312 310
313impl Foo { 311impl Foo {
314 pub fn new() -> Self { Self { } }<|> 312 pub fn $0new() -> Self { Self { } }
315} 313}
316", 314",
317 ); 315 );
@@ -321,7 +319,7 @@ impl Foo {
321"pub(crate) struct Foo {} 319"pub(crate) struct Foo {}
322 320
323impl Foo { 321impl Foo {
324 pub(crate) fn new() -> Self { Self { } }<|> 322 pub(crate) fn $0new() -> Self { Self { } }
325} 323}
326", 324",
327 ); 325 );
@@ -414,7 +412,7 @@ pub struct Source<T> {
414} 412}
415 413
416impl<T> Source<T> { 414impl<T> Source<T> {
417 pub fn new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } }<|> 415 pub fn $0new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } }
418 416
419 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { 417 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> {
420 Source { file_id: self.file_id, ast: f(self.ast) } 418 Source { file_id: self.file_id, ast: f(self.ast) }
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs
index 78d23150d..f6d25579e 100644
--- a/crates/ra_assists/src/handlers/auto_import.rs
+++ b/crates/ra_assists/src/handlers/auto_import.rs
@@ -50,7 +50,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
50 format!("Import `{}`", &import), 50 format!("Import `{}`", &import),
51 range, 51 range,
52 |builder| { 52 |builder| {
53 insert_use_statement(&auto_import_assets.syntax_under_caret, &import, ctx, builder); 53 insert_use_statement(
54 &auto_import_assets.syntax_under_caret,
55 &import,
56 ctx,
57 builder.text_edit_builder(),
58 );
54 }, 59 },
55 ); 60 );
56 } 61 }
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
index 5c907097e..c6baa0a57 100644
--- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs
+++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
@@ -1,8 +1,6 @@
1use ra_syntax::{ 1use ra_syntax::{
2 ast::{self, BlockExpr, Expr, LoopBodyOwner}, 2 ast::{self, BlockExpr, Expr, LoopBodyOwner},
3 AstNode, 3 AstNode, SyntaxNode,
4 SyntaxKind::{COMMENT, WHITESPACE},
5 SyntaxNode, TextSize,
6}; 4};
7 5
8use crate::{AssistContext, AssistId, Assists}; 6use crate::{AssistContext, AssistId, Assists};
@@ -16,39 +14,40 @@ use crate::{AssistContext, AssistId, Assists};
16// ``` 14// ```
17// -> 15// ->
18// ``` 16// ```
19// fn foo() -> Result<i32, > { Ok(42i32) } 17// fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
20// ``` 18// ```
21pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 19pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
22 let fn_def = ctx.find_node_at_offset::<ast::FnDef>(); 20 let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
23 let fn_def = &mut fn_def?; 21 // FIXME: extend to lambdas as well
24 let ret_type = &fn_def.ret_type()?.type_ref()?; 22 let fn_def = ret_type.syntax().parent().and_then(ast::FnDef::cast)?;
25 if ret_type.syntax().text().to_string().starts_with("Result<") { 23
24 let type_ref = &ret_type.type_ref()?;
25 if type_ref.syntax().text().to_string().starts_with("Result<") {
26 return None; 26 return None;
27 } 27 }
28 28
29 let block_expr = &fn_def.body()?; 29 let block_expr = &fn_def.body()?;
30 let cursor_in_ret_type =
31 fn_def.ret_type()?.syntax().text_range().contains_range(ctx.frange.range);
32 if !cursor_in_ret_type {
33 return None;
34 }
35 30
36 acc.add( 31 acc.add(
37 AssistId("change_return_type_to_result"), 32 AssistId("change_return_type_to_result"),
38 "Change return type to Result", 33 "Change return type to Result",
39 ret_type.syntax().text_range(), 34 type_ref.syntax().text_range(),
40 |edit| { 35 |builder| {
41 let mut tail_return_expr_collector = TailReturnCollector::new(); 36 let mut tail_return_expr_collector = TailReturnCollector::new();
42 tail_return_expr_collector.collect_jump_exprs(block_expr, false); 37 tail_return_expr_collector.collect_jump_exprs(block_expr, false);
43 tail_return_expr_collector.collect_tail_exprs(block_expr); 38 tail_return_expr_collector.collect_tail_exprs(block_expr);
44 39
45 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { 40 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
46 edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); 41 builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg));
47 } 42 }
48 edit.replace_node_and_indent(ret_type.syntax(), format!("Result<{}, >", ret_type));
49 43
50 if let Some(node_start) = result_insertion_offset(&ret_type) { 44 match ctx.config.snippet_cap {
51 edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", ret_type))); 45 Some(cap) => {
46 let snippet = format!("Result<{}, ${{0:_}}>", type_ref);
47 builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet)
48 }
49 None => builder
50 .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)),
52 } 51 }
53 }, 52 },
54 ) 53 )
@@ -250,17 +249,8 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> {
250 } 249 }
251} 250}
252 251
253fn result_insertion_offset(ret_type: &ast::TypeRef) -> Option<TextSize> {
254 let non_ws_child = ret_type
255 .syntax()
256 .children_with_tokens()
257 .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?;
258 Some(non_ws_child.text_range().start())
259}
260
261#[cfg(test)] 252#[cfg(test)]
262mod tests { 253mod tests {
263
264 use crate::tests::{check_assist, check_assist_not_applicable}; 254 use crate::tests::{check_assist, check_assist_not_applicable};
265 255
266 use super::*; 256 use super::*;
@@ -273,7 +263,7 @@ mod tests {
273 let test = "test"; 263 let test = "test";
274 return 42i32; 264 return 42i32;
275 }"#, 265 }"#,
276 r#"fn foo() -> Result<i32, <|>> { 266 r#"fn foo() -> Result<i32, ${0:_}> {
277 let test = "test"; 267 let test = "test";
278 return Ok(42i32); 268 return Ok(42i32);
279 }"#, 269 }"#,
@@ -288,7 +278,7 @@ mod tests {
288 let test = "test"; 278 let test = "test";
289 return 42i32; 279 return 42i32;
290 }"#, 280 }"#,
291 r#"fn foo() -> Result<i32, <|>> { 281 r#"fn foo() -> Result<i32, ${0:_}> {
292 let test = "test"; 282 let test = "test";
293 return Ok(42i32); 283 return Ok(42i32);
294 }"#, 284 }"#,
@@ -314,7 +304,7 @@ mod tests {
314 let test = "test"; 304 let test = "test";
315 return 42i32; 305 return 42i32;
316 }"#, 306 }"#,
317 r#"fn foo() -> Result<i32, <|>> { 307 r#"fn foo() -> Result<i32, ${0:_}> {
318 let test = "test"; 308 let test = "test";
319 return Ok(42i32); 309 return Ok(42i32);
320 }"#, 310 }"#,
@@ -329,7 +319,7 @@ mod tests {
329 let test = "test"; 319 let test = "test";
330 42i32 320 42i32
331 }"#, 321 }"#,
332 r#"fn foo() -> Result<i32, <|>> { 322 r#"fn foo() -> Result<i32, ${0:_}> {
333 let test = "test"; 323 let test = "test";
334 Ok(42i32) 324 Ok(42i32)
335 }"#, 325 }"#,
@@ -343,7 +333,7 @@ mod tests {
343 r#"fn foo() -> i32<|> { 333 r#"fn foo() -> i32<|> {
344 42i32 334 42i32
345 }"#, 335 }"#,
346 r#"fn foo() -> Result<i32, <|>> { 336 r#"fn foo() -> Result<i32, ${0:_}> {
347 Ok(42i32) 337 Ok(42i32)
348 }"#, 338 }"#,
349 ); 339 );
@@ -359,7 +349,7 @@ mod tests {
359 24i32 349 24i32
360 } 350 }
361 }"#, 351 }"#,
362 r#"fn foo() -> Result<i32, <|>> { 352 r#"fn foo() -> Result<i32, ${0:_}> {
363 if true { 353 if true {
364 Ok(42i32) 354 Ok(42i32)
365 } else { 355 } else {
@@ -384,7 +374,7 @@ mod tests {
384 24i32 374 24i32
385 } 375 }
386 }"#, 376 }"#,
387 r#"fn foo() -> Result<i32, <|>> { 377 r#"fn foo() -> Result<i32, ${0:_}> {
388 if true { 378 if true {
389 if false { 379 if false {
390 Ok(1) 380 Ok(1)
@@ -413,7 +403,7 @@ mod tests {
413 24i32.await 403 24i32.await
414 } 404 }
415 }"#, 405 }"#,
416 r#"async fn foo() -> Result<i32, <|>> { 406 r#"async fn foo() -> Result<i32, ${0:_}> {
417 if true { 407 if true {
418 if false { 408 if false {
419 Ok(1.await) 409 Ok(1.await)
@@ -434,7 +424,7 @@ mod tests {
434 r#"fn foo() -> [i32;<|> 3] { 424 r#"fn foo() -> [i32;<|> 3] {
435 [1, 2, 3] 425 [1, 2, 3]
436 }"#, 426 }"#,
437 r#"fn foo() -> Result<[i32; 3], <|>> { 427 r#"fn foo() -> Result<[i32; 3], ${0:_}> {
438 Ok([1, 2, 3]) 428 Ok([1, 2, 3])
439 }"#, 429 }"#,
440 ); 430 );
@@ -455,7 +445,7 @@ mod tests {
455 24 as i32 445 24 as i32
456 } 446 }
457 }"#, 447 }"#,
458 r#"fn foo() -> Result<i32, <|>> { 448 r#"fn foo() -> Result<i32, ${0:_}> {
459 if true { 449 if true {
460 if false { 450 if false {
461 Ok(1 as i32) 451 Ok(1 as i32)
@@ -480,7 +470,7 @@ mod tests {
480 _ => 24i32, 470 _ => 24i32,
481 } 471 }
482 }"#, 472 }"#,
483 r#"fn foo() -> Result<i32, <|>> { 473 r#"fn foo() -> Result<i32, ${0:_}> {
484 let my_var = 5; 474 let my_var = 5;
485 match my_var { 475 match my_var {
486 5 => Ok(42i32), 476 5 => Ok(42i32),
@@ -503,7 +493,7 @@ mod tests {
503 493
504 my_var 494 my_var
505 }"#, 495 }"#,
506 r#"fn foo() -> Result<i32, <|>> { 496 r#"fn foo() -> Result<i32, ${0:_}> {
507 let my_var = 5; 497 let my_var = 5;
508 loop { 498 loop {
509 println!("test"); 499 println!("test");
@@ -526,7 +516,7 @@ mod tests {
526 516
527 my_var 517 my_var
528 }"#, 518 }"#,
529 r#"fn foo() -> Result<i32, <|>> { 519 r#"fn foo() -> Result<i32, ${0:_}> {
530 let my_var = let x = loop { 520 let my_var = let x = loop {
531 break 1; 521 break 1;
532 }; 522 };
@@ -549,7 +539,7 @@ mod tests {
549 539
550 res 540 res
551 }"#, 541 }"#,
552 r#"fn foo() -> Result<i32, <|>> { 542 r#"fn foo() -> Result<i32, ${0:_}> {
553 let my_var = 5; 543 let my_var = 5;
554 let res = match my_var { 544 let res = match my_var {
555 5 => 42i32, 545 5 => 42i32,
@@ -572,7 +562,7 @@ mod tests {
572 562
573 res 563 res
574 }"#, 564 }"#,
575 r#"fn foo() -> Result<i32, <|>> { 565 r#"fn foo() -> Result<i32, ${0:_}> {
576 let my_var = 5; 566 let my_var = 5;
577 let res = if my_var == 5 { 567 let res = if my_var == 5 {
578 42i32 568 42i32
@@ -608,7 +598,7 @@ mod tests {
608 }, 598 },
609 } 599 }
610 }"#, 600 }"#,
611 r#"fn foo() -> Result<i32, <|>> { 601 r#"fn foo() -> Result<i32, ${0:_}> {
612 let my_var = 5; 602 let my_var = 5;
613 match my_var { 603 match my_var {
614 5 => { 604 5 => {
@@ -641,7 +631,7 @@ mod tests {
641 } 631 }
642 53i32 632 53i32
643 }"#, 633 }"#,
644 r#"fn foo() -> Result<i32, <|>> { 634 r#"fn foo() -> Result<i32, ${0:_}> {
645 let test = "test"; 635 let test = "test";
646 if test == "test" { 636 if test == "test" {
647 return Ok(24i32); 637 return Ok(24i32);
@@ -672,7 +662,7 @@ mod tests {
672 662
673 the_field 663 the_field
674 }"#, 664 }"#,
675 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 665 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
676 let true_closure = || { 666 let true_closure = || {
677 return true; 667 return true;
678 }; 668 };
@@ -711,7 +701,7 @@ mod tests {
711 701
712 t.unwrap_or_else(|| the_field) 702 t.unwrap_or_else(|| the_field)
713 }"#, 703 }"#,
714 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 704 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
715 let true_closure = || { 705 let true_closure = || {
716 return true; 706 return true;
717 }; 707 };
@@ -749,7 +739,7 @@ mod tests {
749 i += 1; 739 i += 1;
750 } 740 }
751 }"#, 741 }"#,
752 r#"fn foo() -> Result<i32, <|>> { 742 r#"fn foo() -> Result<i32, ${0:_}> {
753 let test = "test"; 743 let test = "test";
754 if test == "test" { 744 if test == "test" {
755 return Ok(24i32); 745 return Ok(24i32);
@@ -781,7 +771,7 @@ mod tests {
781 } 771 }
782 } 772 }
783 }"#, 773 }"#,
784 r#"fn foo() -> Result<i32, <|>> { 774 r#"fn foo() -> Result<i32, ${0:_}> {
785 let test = "test"; 775 let test = "test";
786 if test == "test" { 776 if test == "test" {
787 return Ok(24i32); 777 return Ok(24i32);
@@ -819,7 +809,7 @@ mod tests {
819 } 809 }
820 } 810 }
821 }"#, 811 }"#,
822 r#"fn foo() -> Result<i32, <|>> { 812 r#"fn foo() -> Result<i32, ${0:_}> {
823 let test = "test"; 813 let test = "test";
824 let other = 5; 814 let other = 5;
825 if test == "test" { 815 if test == "test" {
@@ -860,7 +850,7 @@ mod tests {
860 850
861 the_field 851 the_field
862 }"#, 852 }"#,
863 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 853 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
864 if the_field < 5 { 854 if the_field < 5 {
865 let mut i = 0; 855 let mut i = 0;
866 loop { 856 loop {
@@ -894,7 +884,7 @@ mod tests {
894 884
895 the_field 885 the_field
896 }"#, 886 }"#,
897 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 887 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
898 if the_field < 5 { 888 if the_field < 5 {
899 let mut i = 0; 889 let mut i = 0;
900 890
@@ -923,7 +913,7 @@ mod tests {
923 913
924 the_field 914 the_field
925 }"#, 915 }"#,
926 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 916 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
927 if the_field < 5 { 917 if the_field < 5 {
928 let mut i = 0; 918 let mut i = 0;
929 919
@@ -953,7 +943,7 @@ mod tests {
953 943
954 the_field 944 the_field
955 }"#, 945 }"#,
956 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 946 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
957 if the_field < 5 { 947 if the_field < 5 {
958 let mut i = 0; 948 let mut i = 0;
959 949
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 1a81d8a0e..d9f84208d 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -39,7 +39,7 @@ pub(crate) fn replace_qualified_name_with_use(
39 target, 39 target,
40 |builder| { 40 |builder| {
41 let path_to_import = hir_path.mod_path().clone(); 41 let path_to_import = hir_path.mod_path().clone();
42 insert_use_statement(path.syntax(), &path_to_import, ctx, builder); 42 insert_use_statement(path.syntax(), &path_to_import, ctx, builder.text_edit_builder());
43 43
44 if let Some(last) = path.segment() { 44 if let Some(last) = path.segment() {
45 // Here we are assuming the assist will provide a correct use statement 45 // Here we are assuming the assist will provide a correct use statement
diff --git a/crates/ra_assists/src/tests/generated.rs b/crates/ra_assists/src/tests/generated.rs
index 3808aded1..cd6129dc5 100644
--- a/crates/ra_assists/src/tests/generated.rs
+++ b/crates/ra_assists/src/tests/generated.rs
@@ -204,7 +204,7 @@ struct Ctx<T: Clone> {
204} 204}
205 205
206impl<T: Clone> Ctx<T> { 206impl<T: Clone> Ctx<T> {
207 fn new(data: T) -> Self { Self { data } } 207 fn $0new(data: T) -> Self { Self { data } }
208} 208}
209 209
210"#####, 210"#####,
@@ -276,7 +276,7 @@ fn doctest_change_return_type_to_result() {
276fn foo() -> i32<|> { 42i32 } 276fn foo() -> i32<|> { 42i32 }
277"#####, 277"#####,
278 r#####" 278 r#####"
279fn foo() -> Result<i32, > { Ok(42i32) } 279fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
280"#####, 280"#####,
281 ) 281 )
282} 282}
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs
index 1214e3cd4..0ee43482f 100644
--- a/crates/ra_assists/src/utils/insert_use.rs
+++ b/crates/ra_assists/src/utils/insert_use.rs
@@ -11,7 +11,7 @@ use ra_syntax::{
11}; 11};
12use ra_text_edit::TextEditBuilder; 12use ra_text_edit::TextEditBuilder;
13 13
14use crate::assist_context::{AssistBuilder, AssistContext}; 14use crate::assist_context::AssistContext;
15 15
16/// Creates and inserts a use statement for the given path to import. 16/// Creates and inserts a use statement for the given path to import.
17/// The use statement is inserted in the scope most appropriate to the 17/// The use statement is inserted in the scope most appropriate to the
@@ -21,7 +21,7 @@ pub(crate) fn insert_use_statement(
21 position: &SyntaxNode, 21 position: &SyntaxNode,
22 path_to_import: &ModPath, 22 path_to_import: &ModPath,
23 ctx: &AssistContext, 23 ctx: &AssistContext,
24 builder: &mut AssistBuilder, 24 builder: &mut TextEditBuilder,
25) { 25) {
26 let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>(); 26 let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>();
27 let container = ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { 27 let container = ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| {
@@ -33,7 +33,7 @@ pub(crate) fn insert_use_statement(
33 33
34 if let Some(container) = container { 34 if let Some(container) = container {
35 let action = best_action_for_target(container, position.clone(), &target); 35 let action = best_action_for_target(container, position.clone(), &target);
36 make_assist(&action, &target, builder.text_edit_builder()); 36 make_assist(&action, &target, builder);
37 } 37 }
38} 38}
39 39
diff --git a/docs/user/assists.md b/docs/user/assists.md
index f329fcc10..006ec4d54 100644
--- a/docs/user/assists.md
+++ b/docs/user/assists.md
@@ -198,7 +198,7 @@ struct Ctx<T: Clone> {
198} 198}
199 199
200impl<T: Clone> Ctx<T> { 200impl<T: Clone> Ctx<T> {
201 fn new(data: T) -> Self { Self { data } } 201 fn $0new(data: T) -> Self { Self { data } }
202} 202}
203 203
204``` 204```
@@ -268,7 +268,7 @@ Change the function's return type to Result.
268fn foo() -> i32┃ { 42i32 } 268fn foo() -> i32┃ { 42i32 }
269 269
270// AFTER 270// AFTER
271fn foo() -> Result<i32, > { Ok(42i32) } 271fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
272``` 272```
273 273
274## `change_visibility` 274## `change_visibility`