diff options
Diffstat (limited to 'crates/assists/src/handlers/add_missing_impl_members.rs')
-rw-r--r-- | crates/assists/src/handlers/add_missing_impl_members.rs | 814 |
1 files changed, 0 insertions, 814 deletions
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs deleted file mode 100644 index 63cea754d..000000000 --- a/crates/assists/src/handlers/add_missing_impl_members.rs +++ /dev/null | |||
@@ -1,814 +0,0 @@ | |||
1 | use ide_db::traits::resolve_target_trait; | ||
2 | use syntax::ast::{self, AstNode}; | ||
3 | |||
4 | use crate::{ | ||
5 | assist_context::{AssistContext, Assists}, | ||
6 | utils::add_trait_assoc_items_to_impl, | ||
7 | utils::DefaultMethods, | ||
8 | utils::{filter_assoc_items, render_snippet, Cursor}, | ||
9 | AssistId, AssistKind, | ||
10 | }; | ||
11 | |||
12 | // Assist: add_impl_missing_members | ||
13 | // | ||
14 | // Adds scaffold for required impl members. | ||
15 | // | ||
16 | // ``` | ||
17 | // trait Trait<T> { | ||
18 | // type X; | ||
19 | // fn foo(&self) -> T; | ||
20 | // fn bar(&self) {} | ||
21 | // } | ||
22 | // | ||
23 | // impl Trait<u32> for () {$0 | ||
24 | // | ||
25 | // } | ||
26 | // ``` | ||
27 | // -> | ||
28 | // ``` | ||
29 | // trait Trait<T> { | ||
30 | // type X; | ||
31 | // fn foo(&self) -> T; | ||
32 | // fn bar(&self) {} | ||
33 | // } | ||
34 | // | ||
35 | // impl Trait<u32> for () { | ||
36 | // $0type X; | ||
37 | // | ||
38 | // fn foo(&self) -> u32 { | ||
39 | // todo!() | ||
40 | // } | ||
41 | // } | ||
42 | // ``` | ||
43 | pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
44 | add_missing_impl_members_inner( | ||
45 | acc, | ||
46 | ctx, | ||
47 | DefaultMethods::No, | ||
48 | "add_impl_missing_members", | ||
49 | "Implement missing members", | ||
50 | ) | ||
51 | } | ||
52 | |||
53 | // Assist: add_impl_default_members | ||
54 | // | ||
55 | // Adds scaffold for overriding default impl members. | ||
56 | // | ||
57 | // ``` | ||
58 | // trait Trait { | ||
59 | // type X; | ||
60 | // fn foo(&self); | ||
61 | // fn bar(&self) {} | ||
62 | // } | ||
63 | // | ||
64 | // impl Trait for () { | ||
65 | // type X = (); | ||
66 | // fn foo(&self) {}$0 | ||
67 | // | ||
68 | // } | ||
69 | // ``` | ||
70 | // -> | ||
71 | // ``` | ||
72 | // trait Trait { | ||
73 | // type X; | ||
74 | // fn foo(&self); | ||
75 | // fn bar(&self) {} | ||
76 | // } | ||
77 | // | ||
78 | // impl Trait for () { | ||
79 | // type X = (); | ||
80 | // fn foo(&self) {} | ||
81 | // | ||
82 | // $0fn bar(&self) {} | ||
83 | // } | ||
84 | // ``` | ||
85 | pub(crate) fn add_missing_default_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
86 | add_missing_impl_members_inner( | ||
87 | acc, | ||
88 | ctx, | ||
89 | DefaultMethods::Only, | ||
90 | "add_impl_default_members", | ||
91 | "Implement default members", | ||
92 | ) | ||
93 | } | ||
94 | |||
95 | fn add_missing_impl_members_inner( | ||
96 | acc: &mut Assists, | ||
97 | ctx: &AssistContext, | ||
98 | mode: DefaultMethods, | ||
99 | assist_id: &'static str, | ||
100 | label: &'static str, | ||
101 | ) -> Option<()> { | ||
102 | let _p = profile::span("add_missing_impl_members_inner"); | ||
103 | let impl_def = ctx.find_node_at_offset::<ast::Impl>()?; | ||
104 | let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; | ||
105 | |||
106 | let missing_items = filter_assoc_items( | ||
107 | ctx.db(), | ||
108 | &ide_db::traits::get_missing_assoc_items(&ctx.sema, &impl_def), | ||
109 | mode, | ||
110 | ); | ||
111 | |||
112 | if missing_items.is_empty() { | ||
113 | return None; | ||
114 | } | ||
115 | |||
116 | let target = impl_def.syntax().text_range(); | ||
117 | acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| { | ||
118 | let target_scope = ctx.sema.scope(impl_def.syntax()); | ||
119 | let (new_impl_def, first_new_item) = | ||
120 | add_trait_assoc_items_to_impl(&ctx.sema, missing_items, trait_, impl_def, target_scope); | ||
121 | match ctx.config.snippet_cap { | ||
122 | None => builder.replace(target, new_impl_def.to_string()), | ||
123 | Some(cap) => { | ||
124 | let mut cursor = Cursor::Before(first_new_item.syntax()); | ||
125 | let placeholder; | ||
126 | if let ast::AssocItem::Fn(func) = &first_new_item { | ||
127 | if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) { | ||
128 | if m.syntax().text() == "todo!()" { | ||
129 | placeholder = m; | ||
130 | cursor = Cursor::Replace(placeholder.syntax()); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | builder.replace_snippet( | ||
135 | cap, | ||
136 | target, | ||
137 | render_snippet(cap, new_impl_def.syntax(), cursor), | ||
138 | ) | ||
139 | } | ||
140 | }; | ||
141 | }) | ||
142 | } | ||
143 | |||
144 | #[cfg(test)] | ||
145 | mod tests { | ||
146 | use crate::tests::{check_assist, check_assist_not_applicable}; | ||
147 | |||
148 | use super::*; | ||
149 | |||
150 | #[test] | ||
151 | fn test_add_missing_impl_members() { | ||
152 | check_assist( | ||
153 | add_missing_impl_members, | ||
154 | r#" | ||
155 | trait Foo { | ||
156 | type Output; | ||
157 | |||
158 | const CONST: usize = 42; | ||
159 | |||
160 | fn foo(&self); | ||
161 | fn bar(&self); | ||
162 | fn baz(&self); | ||
163 | } | ||
164 | |||
165 | struct S; | ||
166 | |||
167 | impl Foo for S { | ||
168 | fn bar(&self) {} | ||
169 | $0 | ||
170 | }"#, | ||
171 | r#" | ||
172 | trait Foo { | ||
173 | type Output; | ||
174 | |||
175 | const CONST: usize = 42; | ||
176 | |||
177 | fn foo(&self); | ||
178 | fn bar(&self); | ||
179 | fn baz(&self); | ||
180 | } | ||
181 | |||
182 | struct S; | ||
183 | |||
184 | impl Foo for S { | ||
185 | fn bar(&self) {} | ||
186 | |||
187 | $0type Output; | ||
188 | |||
189 | const CONST: usize = 42; | ||
190 | |||
191 | fn foo(&self) { | ||
192 | todo!() | ||
193 | } | ||
194 | |||
195 | fn baz(&self) { | ||
196 | todo!() | ||
197 | } | ||
198 | }"#, | ||
199 | ); | ||
200 | } | ||
201 | |||
202 | #[test] | ||
203 | fn test_copied_overriden_members() { | ||
204 | check_assist( | ||
205 | add_missing_impl_members, | ||
206 | r#" | ||
207 | trait Foo { | ||
208 | fn foo(&self); | ||
209 | fn bar(&self) -> bool { true } | ||
210 | fn baz(&self) -> u32 { 42 } | ||
211 | } | ||
212 | |||
213 | struct S; | ||
214 | |||
215 | impl Foo for S { | ||
216 | fn bar(&self) {} | ||
217 | $0 | ||
218 | }"#, | ||
219 | r#" | ||
220 | trait Foo { | ||
221 | fn foo(&self); | ||
222 | fn bar(&self) -> bool { true } | ||
223 | fn baz(&self) -> u32 { 42 } | ||
224 | } | ||
225 | |||
226 | struct S; | ||
227 | |||
228 | impl Foo for S { | ||
229 | fn bar(&self) {} | ||
230 | |||
231 | fn foo(&self) { | ||
232 | ${0:todo!()} | ||
233 | } | ||
234 | }"#, | ||
235 | ); | ||
236 | } | ||
237 | |||
238 | #[test] | ||
239 | fn test_empty_impl_def() { | ||
240 | check_assist( | ||
241 | add_missing_impl_members, | ||
242 | r#" | ||
243 | trait Foo { fn foo(&self); } | ||
244 | struct S; | ||
245 | impl Foo for S { $0 }"#, | ||
246 | r#" | ||
247 | trait Foo { fn foo(&self); } | ||
248 | struct S; | ||
249 | impl Foo for S { | ||
250 | fn foo(&self) { | ||
251 | ${0:todo!()} | ||
252 | } | ||
253 | }"#, | ||
254 | ); | ||
255 | } | ||
256 | |||
257 | #[test] | ||
258 | fn test_impl_def_without_braces() { | ||
259 | check_assist( | ||
260 | add_missing_impl_members, | ||
261 | r#" | ||
262 | trait Foo { fn foo(&self); } | ||
263 | struct S; | ||
264 | impl Foo for S$0"#, | ||
265 | r#" | ||
266 | trait Foo { fn foo(&self); } | ||
267 | struct S; | ||
268 | impl Foo for S { | ||
269 | fn foo(&self) { | ||
270 | ${0:todo!()} | ||
271 | } | ||
272 | }"#, | ||
273 | ); | ||
274 | } | ||
275 | |||
276 | #[test] | ||
277 | fn fill_in_type_params_1() { | ||
278 | check_assist( | ||
279 | add_missing_impl_members, | ||
280 | r#" | ||
281 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | ||
282 | struct S; | ||
283 | impl Foo<u32> for S { $0 }"#, | ||
284 | r#" | ||
285 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | ||
286 | struct S; | ||
287 | impl Foo<u32> for S { | ||
288 | fn foo(&self, t: u32) -> &u32 { | ||
289 | ${0:todo!()} | ||
290 | } | ||
291 | }"#, | ||
292 | ); | ||
293 | } | ||
294 | |||
295 | #[test] | ||
296 | fn fill_in_type_params_2() { | ||
297 | check_assist( | ||
298 | add_missing_impl_members, | ||
299 | r#" | ||
300 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | ||
301 | struct S; | ||
302 | impl<U> Foo<U> for S { $0 }"#, | ||
303 | r#" | ||
304 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | ||
305 | struct S; | ||
306 | impl<U> Foo<U> for S { | ||
307 | fn foo(&self, t: U) -> &U { | ||
308 | ${0:todo!()} | ||
309 | } | ||
310 | }"#, | ||
311 | ); | ||
312 | } | ||
313 | |||
314 | #[test] | ||
315 | fn test_cursor_after_empty_impl_def() { | ||
316 | check_assist( | ||
317 | add_missing_impl_members, | ||
318 | r#" | ||
319 | trait Foo { fn foo(&self); } | ||
320 | struct S; | ||
321 | impl Foo for S {}$0"#, | ||
322 | r#" | ||
323 | trait Foo { fn foo(&self); } | ||
324 | struct S; | ||
325 | impl Foo for S { | ||
326 | fn foo(&self) { | ||
327 | ${0:todo!()} | ||
328 | } | ||
329 | }"#, | ||
330 | ) | ||
331 | } | ||
332 | |||
333 | #[test] | ||
334 | fn test_qualify_path_1() { | ||
335 | check_assist( | ||
336 | add_missing_impl_members, | ||
337 | r#" | ||
338 | mod foo { | ||
339 | pub struct Bar; | ||
340 | trait Foo { fn foo(&self, bar: Bar); } | ||
341 | } | ||
342 | struct S; | ||
343 | impl foo::Foo for S { $0 }"#, | ||
344 | r#" | ||
345 | mod foo { | ||
346 | pub struct Bar; | ||
347 | trait Foo { fn foo(&self, bar: Bar); } | ||
348 | } | ||
349 | struct S; | ||
350 | impl foo::Foo for S { | ||
351 | fn foo(&self, bar: foo::Bar) { | ||
352 | ${0:todo!()} | ||
353 | } | ||
354 | }"#, | ||
355 | ); | ||
356 | } | ||
357 | |||
358 | #[test] | ||
359 | fn test_qualify_path_2() { | ||
360 | check_assist( | ||
361 | add_missing_impl_members, | ||
362 | r#" | ||
363 | mod foo { | ||
364 | pub mod bar { | ||
365 | pub struct Bar; | ||
366 | pub trait Foo { fn foo(&self, bar: Bar); } | ||
367 | } | ||
368 | } | ||
369 | |||
370 | use foo::bar; | ||
371 | |||
372 | struct S; | ||
373 | impl bar::Foo for S { $0 }"#, | ||
374 | r#" | ||
375 | mod foo { | ||
376 | pub mod bar { | ||
377 | pub struct Bar; | ||
378 | pub trait Foo { fn foo(&self, bar: Bar); } | ||
379 | } | ||
380 | } | ||
381 | |||
382 | use foo::bar; | ||
383 | |||
384 | struct S; | ||
385 | impl bar::Foo for S { | ||
386 | fn foo(&self, bar: bar::Bar) { | ||
387 | ${0:todo!()} | ||
388 | } | ||
389 | }"#, | ||
390 | ); | ||
391 | } | ||
392 | |||
393 | #[test] | ||
394 | fn test_qualify_path_generic() { | ||
395 | check_assist( | ||
396 | add_missing_impl_members, | ||
397 | r#" | ||
398 | mod foo { | ||
399 | pub struct Bar<T>; | ||
400 | trait Foo { fn foo(&self, bar: Bar<u32>); } | ||
401 | } | ||
402 | struct S; | ||
403 | impl foo::Foo for S { $0 }"#, | ||
404 | r#" | ||
405 | mod foo { | ||
406 | pub struct Bar<T>; | ||
407 | trait Foo { fn foo(&self, bar: Bar<u32>); } | ||
408 | } | ||
409 | struct S; | ||
410 | impl foo::Foo for S { | ||
411 | fn foo(&self, bar: foo::Bar<u32>) { | ||
412 | ${0:todo!()} | ||
413 | } | ||
414 | }"#, | ||
415 | ); | ||
416 | } | ||
417 | |||
418 | #[test] | ||
419 | fn test_qualify_path_and_substitute_param() { | ||
420 | check_assist( | ||
421 | add_missing_impl_members, | ||
422 | r#" | ||
423 | mod foo { | ||
424 | pub struct Bar<T>; | ||
425 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } | ||
426 | } | ||
427 | struct S; | ||
428 | impl foo::Foo<u32> for S { $0 }"#, | ||
429 | r#" | ||
430 | mod foo { | ||
431 | pub struct Bar<T>; | ||
432 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } | ||
433 | } | ||
434 | struct S; | ||
435 | impl foo::Foo<u32> for S { | ||
436 | fn foo(&self, bar: foo::Bar<u32>) { | ||
437 | ${0:todo!()} | ||
438 | } | ||
439 | }"#, | ||
440 | ); | ||
441 | } | ||
442 | |||
443 | #[test] | ||
444 | fn test_substitute_param_no_qualify() { | ||
445 | // when substituting params, the substituted param should not be qualified! | ||
446 | check_assist( | ||
447 | add_missing_impl_members, | ||
448 | r#" | ||
449 | mod foo { | ||
450 | trait Foo<T> { fn foo(&self, bar: T); } | ||
451 | pub struct Param; | ||
452 | } | ||
453 | struct Param; | ||
454 | struct S; | ||
455 | impl foo::Foo<Param> for S { $0 }"#, | ||
456 | r#" | ||
457 | mod foo { | ||
458 | trait Foo<T> { fn foo(&self, bar: T); } | ||
459 | pub struct Param; | ||
460 | } | ||
461 | struct Param; | ||
462 | struct S; | ||
463 | impl foo::Foo<Param> for S { | ||
464 | fn foo(&self, bar: Param) { | ||
465 | ${0:todo!()} | ||
466 | } | ||
467 | }"#, | ||
468 | ); | ||
469 | } | ||
470 | |||
471 | #[test] | ||
472 | fn test_qualify_path_associated_item() { | ||
473 | check_assist( | ||
474 | add_missing_impl_members, | ||
475 | r#" | ||
476 | mod foo { | ||
477 | pub struct Bar<T>; | ||
478 | impl Bar<T> { type Assoc = u32; } | ||
479 | trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } | ||
480 | } | ||
481 | struct S; | ||
482 | impl foo::Foo for S { $0 }"#, | ||
483 | r#" | ||
484 | mod foo { | ||
485 | pub struct Bar<T>; | ||
486 | impl Bar<T> { type Assoc = u32; } | ||
487 | trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } | ||
488 | } | ||
489 | struct S; | ||
490 | impl foo::Foo for S { | ||
491 | fn foo(&self, bar: foo::Bar<u32>::Assoc) { | ||
492 | ${0:todo!()} | ||
493 | } | ||
494 | }"#, | ||
495 | ); | ||
496 | } | ||
497 | |||
498 | #[test] | ||
499 | fn test_qualify_path_nested() { | ||
500 | check_assist( | ||
501 | add_missing_impl_members, | ||
502 | r#" | ||
503 | mod foo { | ||
504 | pub struct Bar<T>; | ||
505 | pub struct Baz; | ||
506 | trait Foo { fn foo(&self, bar: Bar<Baz>); } | ||
507 | } | ||
508 | struct S; | ||
509 | impl foo::Foo for S { $0 }"#, | ||
510 | r#" | ||
511 | mod foo { | ||
512 | pub struct Bar<T>; | ||
513 | pub struct Baz; | ||
514 | trait Foo { fn foo(&self, bar: Bar<Baz>); } | ||
515 | } | ||
516 | struct S; | ||
517 | impl foo::Foo for S { | ||
518 | fn foo(&self, bar: foo::Bar<foo::Baz>) { | ||
519 | ${0:todo!()} | ||
520 | } | ||
521 | }"#, | ||
522 | ); | ||
523 | } | ||
524 | |||
525 | #[test] | ||
526 | fn test_qualify_path_fn_trait_notation() { | ||
527 | check_assist( | ||
528 | add_missing_impl_members, | ||
529 | r#" | ||
530 | mod foo { | ||
531 | pub trait Fn<Args> { type Output; } | ||
532 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } | ||
533 | } | ||
534 | struct S; | ||
535 | impl foo::Foo for S { $0 }"#, | ||
536 | r#" | ||
537 | mod foo { | ||
538 | pub trait Fn<Args> { type Output; } | ||
539 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } | ||
540 | } | ||
541 | struct S; | ||
542 | impl foo::Foo for S { | ||
543 | fn foo(&self, bar: dyn Fn(u32) -> i32) { | ||
544 | ${0:todo!()} | ||
545 | } | ||
546 | }"#, | ||
547 | ); | ||
548 | } | ||
549 | |||
550 | #[test] | ||
551 | fn test_empty_trait() { | ||
552 | check_assist_not_applicable( | ||
553 | add_missing_impl_members, | ||
554 | r#" | ||
555 | trait Foo; | ||
556 | struct S; | ||
557 | impl Foo for S { $0 }"#, | ||
558 | ) | ||
559 | } | ||
560 | |||
561 | #[test] | ||
562 | fn test_ignore_unnamed_trait_members_and_default_methods() { | ||
563 | check_assist_not_applicable( | ||
564 | add_missing_impl_members, | ||
565 | r#" | ||
566 | trait Foo { | ||
567 | fn (arg: u32); | ||
568 | fn valid(some: u32) -> bool { false } | ||
569 | } | ||
570 | struct S; | ||
571 | impl Foo for S { $0 }"#, | ||
572 | ) | ||
573 | } | ||
574 | |||
575 | #[test] | ||
576 | fn test_with_docstring_and_attrs() { | ||
577 | check_assist( | ||
578 | add_missing_impl_members, | ||
579 | r#" | ||
580 | #[doc(alias = "test alias")] | ||
581 | trait Foo { | ||
582 | /// doc string | ||
583 | type Output; | ||
584 | |||
585 | #[must_use] | ||
586 | fn foo(&self); | ||
587 | } | ||
588 | struct S; | ||
589 | impl Foo for S {}$0"#, | ||
590 | r#" | ||
591 | #[doc(alias = "test alias")] | ||
592 | trait Foo { | ||
593 | /// doc string | ||
594 | type Output; | ||
595 | |||
596 | #[must_use] | ||
597 | fn foo(&self); | ||
598 | } | ||
599 | struct S; | ||
600 | impl Foo for S { | ||
601 | $0type Output; | ||
602 | |||
603 | fn foo(&self) { | ||
604 | todo!() | ||
605 | } | ||
606 | }"#, | ||
607 | ) | ||
608 | } | ||
609 | |||
610 | #[test] | ||
611 | fn test_default_methods() { | ||
612 | check_assist( | ||
613 | add_missing_default_members, | ||
614 | r#" | ||
615 | trait Foo { | ||
616 | type Output; | ||
617 | |||
618 | const CONST: usize = 42; | ||
619 | |||
620 | fn valid(some: u32) -> bool { false } | ||
621 | fn foo(some: u32) -> bool; | ||
622 | } | ||
623 | struct S; | ||
624 | impl Foo for S { $0 }"#, | ||
625 | r#" | ||
626 | trait Foo { | ||
627 | type Output; | ||
628 | |||
629 | const CONST: usize = 42; | ||
630 | |||
631 | fn valid(some: u32) -> bool { false } | ||
632 | fn foo(some: u32) -> bool; | ||
633 | } | ||
634 | struct S; | ||
635 | impl Foo for S { | ||
636 | $0fn valid(some: u32) -> bool { false } | ||
637 | }"#, | ||
638 | ) | ||
639 | } | ||
640 | |||
641 | #[test] | ||
642 | fn test_generic_single_default_parameter() { | ||
643 | check_assist( | ||
644 | add_missing_impl_members, | ||
645 | r#" | ||
646 | trait Foo<T = Self> { | ||
647 | fn bar(&self, other: &T); | ||
648 | } | ||
649 | |||
650 | struct S; | ||
651 | impl Foo for S { $0 }"#, | ||
652 | r#" | ||
653 | trait Foo<T = Self> { | ||
654 | fn bar(&self, other: &T); | ||
655 | } | ||
656 | |||
657 | struct S; | ||
658 | impl Foo for S { | ||
659 | fn bar(&self, other: &Self) { | ||
660 | ${0:todo!()} | ||
661 | } | ||
662 | }"#, | ||
663 | ) | ||
664 | } | ||
665 | |||
666 | #[test] | ||
667 | fn test_generic_default_parameter_is_second() { | ||
668 | check_assist( | ||
669 | add_missing_impl_members, | ||
670 | r#" | ||
671 | trait Foo<T1, T2 = Self> { | ||
672 | fn bar(&self, this: &T1, that: &T2); | ||
673 | } | ||
674 | |||
675 | struct S<T>; | ||
676 | impl Foo<T> for S<T> { $0 }"#, | ||
677 | r#" | ||
678 | trait Foo<T1, T2 = Self> { | ||
679 | fn bar(&self, this: &T1, that: &T2); | ||
680 | } | ||
681 | |||
682 | struct S<T>; | ||
683 | impl Foo<T> for S<T> { | ||
684 | fn bar(&self, this: &T, that: &Self) { | ||
685 | ${0:todo!()} | ||
686 | } | ||
687 | }"#, | ||
688 | ) | ||
689 | } | ||
690 | |||
691 | #[test] | ||
692 | fn test_assoc_type_bounds_are_removed() { | ||
693 | check_assist( | ||
694 | add_missing_impl_members, | ||
695 | r#" | ||
696 | trait Tr { | ||
697 | type Ty: Copy + 'static; | ||
698 | } | ||
699 | |||
700 | impl Tr for ()$0 { | ||
701 | }"#, | ||
702 | r#" | ||
703 | trait Tr { | ||
704 | type Ty: Copy + 'static; | ||
705 | } | ||
706 | |||
707 | impl Tr for () { | ||
708 | $0type Ty; | ||
709 | }"#, | ||
710 | ) | ||
711 | } | ||
712 | |||
713 | #[test] | ||
714 | fn test_whitespace_fixup_preserves_bad_tokens() { | ||
715 | check_assist( | ||
716 | add_missing_impl_members, | ||
717 | r#" | ||
718 | trait Tr { | ||
719 | fn foo(); | ||
720 | } | ||
721 | |||
722 | impl Tr for ()$0 { | ||
723 | +++ | ||
724 | }"#, | ||
725 | r#" | ||
726 | trait Tr { | ||
727 | fn foo(); | ||
728 | } | ||
729 | |||
730 | impl Tr for () { | ||
731 | fn foo() { | ||
732 | ${0:todo!()} | ||
733 | } | ||
734 | +++ | ||
735 | }"#, | ||
736 | ) | ||
737 | } | ||
738 | |||
739 | #[test] | ||
740 | fn test_whitespace_fixup_preserves_comments() { | ||
741 | check_assist( | ||
742 | add_missing_impl_members, | ||
743 | r#" | ||
744 | trait Tr { | ||
745 | fn foo(); | ||
746 | } | ||
747 | |||
748 | impl Tr for ()$0 { | ||
749 | // very important | ||
750 | }"#, | ||
751 | r#" | ||
752 | trait Tr { | ||
753 | fn foo(); | ||
754 | } | ||
755 | |||
756 | impl Tr for () { | ||
757 | fn foo() { | ||
758 | ${0:todo!()} | ||
759 | } | ||
760 | // very important | ||
761 | }"#, | ||
762 | ) | ||
763 | } | ||
764 | |||
765 | #[test] | ||
766 | fn weird_path() { | ||
767 | check_assist( | ||
768 | add_missing_impl_members, | ||
769 | r#" | ||
770 | trait Test { | ||
771 | fn foo(&self, x: crate) | ||
772 | } | ||
773 | impl Test for () { | ||
774 | $0 | ||
775 | } | ||
776 | "#, | ||
777 | r#" | ||
778 | trait Test { | ||
779 | fn foo(&self, x: crate) | ||
780 | } | ||
781 | impl Test for () { | ||
782 | fn foo(&self, x: crate) { | ||
783 | ${0:todo!()} | ||
784 | } | ||
785 | } | ||
786 | "#, | ||
787 | ) | ||
788 | } | ||
789 | |||
790 | #[test] | ||
791 | fn missing_generic_type() { | ||
792 | check_assist( | ||
793 | add_missing_impl_members, | ||
794 | r#" | ||
795 | trait Foo<BAR> { | ||
796 | fn foo(&self, bar: BAR); | ||
797 | } | ||
798 | impl Foo for () { | ||
799 | $0 | ||
800 | } | ||
801 | "#, | ||
802 | r#" | ||
803 | trait Foo<BAR> { | ||
804 | fn foo(&self, bar: BAR); | ||
805 | } | ||
806 | impl Foo for () { | ||
807 | fn foo(&self, bar: BAR) { | ||
808 | ${0:todo!()} | ||
809 | } | ||
810 | } | ||
811 | "#, | ||
812 | ) | ||
813 | } | ||
814 | } | ||