]> git.lizzy.rs Git - rust.git/blob - crates/ide-assists/src/handlers/add_missing_impl_members.rs
Auto merge of #12341 - vemoo:exclude_dirs, r=Veykril
[rust.git] / crates / ide-assists / src / handlers / add_missing_impl_members.rs
1 use hir::HasSource;
2 use ide_db::{
3     syntax_helpers::insert_whitespace_into_node::insert_ws_into, traits::resolve_target_trait,
4 };
5 use syntax::ast::{self, make, AstNode};
6
7 use crate::{
8     assist_context::{AssistContext, Assists},
9     utils::{
10         add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_fn_body, render_snippet,
11         Cursor, DefaultMethods,
12     },
13     AssistId, AssistKind,
14 };
15
16 // Assist: add_impl_missing_members
17 //
18 // Adds scaffold for required impl members.
19 //
20 // ```
21 // trait Trait<T> {
22 //     type X;
23 //     fn foo(&self) -> T;
24 //     fn bar(&self) {}
25 // }
26 //
27 // impl Trait<u32> for () {$0
28 //
29 // }
30 // ```
31 // ->
32 // ```
33 // trait Trait<T> {
34 //     type X;
35 //     fn foo(&self) -> T;
36 //     fn bar(&self) {}
37 // }
38 //
39 // impl Trait<u32> for () {
40 //     $0type X;
41 //
42 //     fn foo(&self) -> u32 {
43 //         todo!()
44 //     }
45 // }
46 // ```
47 pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
48     add_missing_impl_members_inner(
49         acc,
50         ctx,
51         DefaultMethods::No,
52         "add_impl_missing_members",
53         "Implement missing members",
54     )
55 }
56
57 // Assist: add_impl_default_members
58 //
59 // Adds scaffold for overriding default impl members.
60 //
61 // ```
62 // trait Trait {
63 //     type X;
64 //     fn foo(&self);
65 //     fn bar(&self) {}
66 // }
67 //
68 // impl Trait for () {
69 //     type X = ();
70 //     fn foo(&self) {}$0
71 // }
72 // ```
73 // ->
74 // ```
75 // trait Trait {
76 //     type X;
77 //     fn foo(&self);
78 //     fn bar(&self) {}
79 // }
80 //
81 // impl Trait for () {
82 //     type X = ();
83 //     fn foo(&self) {}
84 //
85 //     $0fn bar(&self) {}
86 // }
87 // ```
88 pub(crate) fn add_missing_default_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
89     add_missing_impl_members_inner(
90         acc,
91         ctx,
92         DefaultMethods::Only,
93         "add_impl_default_members",
94         "Implement default members",
95     )
96 }
97
98 fn add_missing_impl_members_inner(
99     acc: &mut Assists,
100     ctx: &AssistContext,
101     mode: DefaultMethods,
102     assist_id: &'static str,
103     label: &'static str,
104 ) -> Option<()> {
105     let _p = profile::span("add_missing_impl_members_inner");
106     let impl_def = ctx.find_node_at_offset::<ast::Impl>()?;
107     let target_scope = ctx.sema.scope(impl_def.syntax())?;
108     let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?;
109
110     let missing_items = filter_assoc_items(
111         &ctx.sema,
112         &ide_db::traits::get_missing_assoc_items(&ctx.sema, &impl_def),
113         mode,
114     );
115
116     if missing_items.is_empty() {
117         return None;
118     }
119
120     let target = impl_def.syntax().text_range();
121     acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| {
122         let missing_items = missing_items
123             .into_iter()
124             .map(|it| {
125                 if ctx.sema.hir_file_for(it.syntax()).is_macro() {
126                     if let Some(it) = ast::AssocItem::cast(insert_ws_into(it.syntax().clone())) {
127                         return it;
128                     }
129                 }
130                 it.clone_for_update()
131             })
132             .collect();
133         let (new_impl_def, first_new_item) = add_trait_assoc_items_to_impl(
134             &ctx.sema,
135             missing_items,
136             trait_,
137             impl_def.clone(),
138             target_scope,
139         );
140         match ctx.config.snippet_cap {
141             None => builder.replace(target, new_impl_def.to_string()),
142             Some(cap) => {
143                 let mut cursor = Cursor::Before(first_new_item.syntax());
144                 let placeholder;
145                 if let ast::AssocItem::Fn(func) = &first_new_item {
146                     if try_gen_trait_body(ctx, func, &trait_, &impl_def).is_none() {
147                         if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
148                         {
149                             if m.syntax().text() == "todo!()" {
150                                 placeholder = m;
151                                 cursor = Cursor::Replace(placeholder.syntax());
152                             }
153                         }
154                     }
155                 }
156                 builder.replace_snippet(
157                     cap,
158                     target,
159                     render_snippet(cap, new_impl_def.syntax(), cursor),
160                 )
161             }
162         };
163     })
164 }
165
166 fn try_gen_trait_body(
167     ctx: &AssistContext,
168     func: &ast::Fn,
169     trait_: &hir::Trait,
170     impl_def: &ast::Impl,
171 ) -> Option<()> {
172     let trait_path = make::ext::ident_path(&trait_.name(ctx.db()).to_string());
173     let hir_ty = ctx.sema.resolve_type(&impl_def.self_ty()?)?;
174     let adt = hir_ty.as_adt()?.source(ctx.db())?;
175     gen_trait_fn_body(func, &trait_path, &adt.value)
176 }
177
178 #[cfg(test)]
179 mod tests {
180     use crate::tests::{check_assist, check_assist_not_applicable};
181
182     use super::*;
183
184     #[test]
185     fn test_add_missing_impl_members() {
186         check_assist(
187             add_missing_impl_members,
188             r#"
189 trait Foo {
190     type Output;
191
192     const CONST: usize = 42;
193
194     fn foo(&self);
195     fn bar(&self);
196     fn baz(&self);
197 }
198
199 struct S;
200
201 impl Foo for S {
202     fn bar(&self) {}
203 $0
204 }"#,
205             r#"
206 trait Foo {
207     type Output;
208
209     const CONST: usize = 42;
210
211     fn foo(&self);
212     fn bar(&self);
213     fn baz(&self);
214 }
215
216 struct S;
217
218 impl Foo for S {
219     fn bar(&self) {}
220
221     $0type Output;
222
223     const CONST: usize = 42;
224
225     fn foo(&self) {
226         todo!()
227     }
228
229     fn baz(&self) {
230         todo!()
231     }
232
233 }"#,
234         );
235     }
236
237     #[test]
238     fn test_copied_overriden_members() {
239         check_assist(
240             add_missing_impl_members,
241             r#"
242 trait Foo {
243     fn foo(&self);
244     fn bar(&self) -> bool { true }
245     fn baz(&self) -> u32 { 42 }
246 }
247
248 struct S;
249
250 impl Foo for S {
251     fn bar(&self) {}
252 $0
253 }"#,
254             r#"
255 trait Foo {
256     fn foo(&self);
257     fn bar(&self) -> bool { true }
258     fn baz(&self) -> u32 { 42 }
259 }
260
261 struct S;
262
263 impl Foo for S {
264     fn bar(&self) {}
265
266     fn foo(&self) {
267         ${0:todo!()}
268     }
269
270 }"#,
271         );
272     }
273
274     #[test]
275     fn test_empty_impl_def() {
276         check_assist(
277             add_missing_impl_members,
278             r#"
279 trait Foo { fn foo(&self); }
280 struct S;
281 impl Foo for S { $0 }"#,
282             r#"
283 trait Foo { fn foo(&self); }
284 struct S;
285 impl Foo for S {
286     fn foo(&self) {
287         ${0:todo!()}
288     }
289 }"#,
290         );
291     }
292
293     #[test]
294     fn test_impl_def_without_braces() {
295         check_assist(
296             add_missing_impl_members,
297             r#"
298 trait Foo { fn foo(&self); }
299 struct S;
300 impl Foo for S$0"#,
301             r#"
302 trait Foo { fn foo(&self); }
303 struct S;
304 impl Foo for S {
305     fn foo(&self) {
306         ${0:todo!()}
307     }
308 }"#,
309         );
310     }
311
312     #[test]
313     fn fill_in_type_params_1() {
314         check_assist(
315             add_missing_impl_members,
316             r#"
317 trait Foo<T> { fn foo(&self, t: T) -> &T; }
318 struct S;
319 impl Foo<u32> for S { $0 }"#,
320             r#"
321 trait Foo<T> { fn foo(&self, t: T) -> &T; }
322 struct S;
323 impl Foo<u32> for S {
324     fn foo(&self, t: u32) -> &u32 {
325         ${0:todo!()}
326     }
327 }"#,
328         );
329     }
330
331     #[test]
332     fn fill_in_type_params_2() {
333         check_assist(
334             add_missing_impl_members,
335             r#"
336 trait Foo<T> { fn foo(&self, t: T) -> &T; }
337 struct S;
338 impl<U> Foo<U> for S { $0 }"#,
339             r#"
340 trait Foo<T> { fn foo(&self, t: T) -> &T; }
341 struct S;
342 impl<U> Foo<U> for S {
343     fn foo(&self, t: U) -> &U {
344         ${0:todo!()}
345     }
346 }"#,
347         );
348     }
349
350     #[test]
351     fn test_cursor_after_empty_impl_def() {
352         check_assist(
353             add_missing_impl_members,
354             r#"
355 trait Foo { fn foo(&self); }
356 struct S;
357 impl Foo for S {}$0"#,
358             r#"
359 trait Foo { fn foo(&self); }
360 struct S;
361 impl Foo for S {
362     fn foo(&self) {
363         ${0:todo!()}
364     }
365 }"#,
366         )
367     }
368
369     #[test]
370     fn test_qualify_path_1() {
371         check_assist(
372             add_missing_impl_members,
373             r#"
374 mod foo {
375     pub struct Bar;
376     trait Foo { fn foo(&self, bar: Bar); }
377 }
378 struct S;
379 impl foo::Foo for S { $0 }"#,
380             r#"
381 mod foo {
382     pub struct Bar;
383     trait Foo { fn foo(&self, bar: Bar); }
384 }
385 struct S;
386 impl foo::Foo for S {
387     fn foo(&self, bar: foo::Bar) {
388         ${0:todo!()}
389     }
390 }"#,
391         );
392     }
393
394     #[test]
395     fn test_qualify_path_2() {
396         check_assist(
397             add_missing_impl_members,
398             r#"
399 mod foo {
400     pub mod bar {
401         pub struct Bar;
402         pub trait Foo { fn foo(&self, bar: Bar); }
403     }
404 }
405
406 use foo::bar;
407
408 struct S;
409 impl bar::Foo for S { $0 }"#,
410             r#"
411 mod foo {
412     pub mod bar {
413         pub struct Bar;
414         pub trait Foo { fn foo(&self, bar: Bar); }
415     }
416 }
417
418 use foo::bar;
419
420 struct S;
421 impl bar::Foo for S {
422     fn foo(&self, bar: bar::Bar) {
423         ${0:todo!()}
424     }
425 }"#,
426         );
427     }
428
429     #[test]
430     fn test_qualify_path_generic() {
431         check_assist(
432             add_missing_impl_members,
433             r#"
434 mod foo {
435     pub struct Bar<T>;
436     trait Foo { fn foo(&self, bar: Bar<u32>); }
437 }
438 struct S;
439 impl foo::Foo for S { $0 }"#,
440             r#"
441 mod foo {
442     pub struct Bar<T>;
443     trait Foo { fn foo(&self, bar: Bar<u32>); }
444 }
445 struct S;
446 impl foo::Foo for S {
447     fn foo(&self, bar: foo::Bar<u32>) {
448         ${0:todo!()}
449     }
450 }"#,
451         );
452     }
453
454     #[test]
455     fn test_qualify_path_and_substitute_param() {
456         check_assist(
457             add_missing_impl_members,
458             r#"
459 mod foo {
460     pub struct Bar<T>;
461     trait Foo<T> { fn foo(&self, bar: Bar<T>); }
462 }
463 struct S;
464 impl foo::Foo<u32> for S { $0 }"#,
465             r#"
466 mod foo {
467     pub struct Bar<T>;
468     trait Foo<T> { fn foo(&self, bar: Bar<T>); }
469 }
470 struct S;
471 impl foo::Foo<u32> for S {
472     fn foo(&self, bar: foo::Bar<u32>) {
473         ${0:todo!()}
474     }
475 }"#,
476         );
477     }
478
479     #[test]
480     fn test_substitute_param_no_qualify() {
481         // when substituting params, the substituted param should not be qualified!
482         check_assist(
483             add_missing_impl_members,
484             r#"
485 mod foo {
486     trait Foo<T> { fn foo(&self, bar: T); }
487     pub struct Param;
488 }
489 struct Param;
490 struct S;
491 impl foo::Foo<Param> for S { $0 }"#,
492             r#"
493 mod foo {
494     trait Foo<T> { fn foo(&self, bar: T); }
495     pub struct Param;
496 }
497 struct Param;
498 struct S;
499 impl foo::Foo<Param> for S {
500     fn foo(&self, bar: Param) {
501         ${0:todo!()}
502     }
503 }"#,
504         );
505     }
506
507     #[test]
508     fn test_qualify_path_associated_item() {
509         check_assist(
510             add_missing_impl_members,
511             r#"
512 mod foo {
513     pub struct Bar<T>;
514     impl Bar<T> { type Assoc = u32; }
515     trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
516 }
517 struct S;
518 impl foo::Foo for S { $0 }"#,
519             r#"
520 mod foo {
521     pub struct Bar<T>;
522     impl Bar<T> { type Assoc = u32; }
523     trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
524 }
525 struct S;
526 impl foo::Foo for S {
527     fn foo(&self, bar: foo::Bar<u32>::Assoc) {
528         ${0:todo!()}
529     }
530 }"#,
531         );
532     }
533
534     #[test]
535     fn test_qualify_path_nested() {
536         check_assist(
537             add_missing_impl_members,
538             r#"
539 mod foo {
540     pub struct Bar<T>;
541     pub struct Baz;
542     trait Foo { fn foo(&self, bar: Bar<Baz>); }
543 }
544 struct S;
545 impl foo::Foo for S { $0 }"#,
546             r#"
547 mod foo {
548     pub struct Bar<T>;
549     pub struct Baz;
550     trait Foo { fn foo(&self, bar: Bar<Baz>); }
551 }
552 struct S;
553 impl foo::Foo for S {
554     fn foo(&self, bar: foo::Bar<foo::Baz>) {
555         ${0:todo!()}
556     }
557 }"#,
558         );
559     }
560
561     #[test]
562     fn test_qualify_path_fn_trait_notation() {
563         check_assist(
564             add_missing_impl_members,
565             r#"
566 mod foo {
567     pub trait Fn<Args> { type Output; }
568     trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
569 }
570 struct S;
571 impl foo::Foo for S { $0 }"#,
572             r#"
573 mod foo {
574     pub trait Fn<Args> { type Output; }
575     trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
576 }
577 struct S;
578 impl foo::Foo for S {
579     fn foo(&self, bar: dyn Fn(u32) -> i32) {
580         ${0:todo!()}
581     }
582 }"#,
583         );
584     }
585
586     #[test]
587     fn test_empty_trait() {
588         check_assist_not_applicable(
589             add_missing_impl_members,
590             r#"
591 trait Foo;
592 struct S;
593 impl Foo for S { $0 }"#,
594         )
595     }
596
597     #[test]
598     fn test_ignore_unnamed_trait_members_and_default_methods() {
599         check_assist_not_applicable(
600             add_missing_impl_members,
601             r#"
602 trait Foo {
603     fn (arg: u32);
604     fn valid(some: u32) -> bool { false }
605 }
606 struct S;
607 impl Foo for S { $0 }"#,
608         )
609     }
610
611     #[test]
612     fn test_with_docstring_and_attrs() {
613         check_assist(
614             add_missing_impl_members,
615             r#"
616 #[doc(alias = "test alias")]
617 trait Foo {
618     /// doc string
619     type Output;
620
621     #[must_use]
622     fn foo(&self);
623 }
624 struct S;
625 impl Foo for S {}$0"#,
626             r#"
627 #[doc(alias = "test alias")]
628 trait Foo {
629     /// doc string
630     type Output;
631
632     #[must_use]
633     fn foo(&self);
634 }
635 struct S;
636 impl Foo for S {
637     $0type Output;
638
639     fn foo(&self) {
640         todo!()
641     }
642 }"#,
643         )
644     }
645
646     #[test]
647     fn test_default_methods() {
648         check_assist(
649             add_missing_default_members,
650             r#"
651 trait Foo {
652     type Output;
653
654     const CONST: usize = 42;
655
656     fn valid(some: u32) -> bool { false }
657     fn foo(some: u32) -> bool;
658 }
659 struct S;
660 impl Foo for S { $0 }"#,
661             r#"
662 trait Foo {
663     type Output;
664
665     const CONST: usize = 42;
666
667     fn valid(some: u32) -> bool { false }
668     fn foo(some: u32) -> bool;
669 }
670 struct S;
671 impl Foo for S {
672     $0fn valid(some: u32) -> bool { false }
673 }"#,
674         )
675     }
676
677     #[test]
678     fn test_generic_single_default_parameter() {
679         check_assist(
680             add_missing_impl_members,
681             r#"
682 trait Foo<T = Self> {
683     fn bar(&self, other: &T);
684 }
685
686 struct S;
687 impl Foo for S { $0 }"#,
688             r#"
689 trait Foo<T = Self> {
690     fn bar(&self, other: &T);
691 }
692
693 struct S;
694 impl Foo for S {
695     fn bar(&self, other: &Self) {
696         ${0:todo!()}
697     }
698 }"#,
699         )
700     }
701
702     #[test]
703     fn test_generic_default_parameter_is_second() {
704         check_assist(
705             add_missing_impl_members,
706             r#"
707 trait Foo<T1, T2 = Self> {
708     fn bar(&self, this: &T1, that: &T2);
709 }
710
711 struct S<T>;
712 impl Foo<T> for S<T> { $0 }"#,
713             r#"
714 trait Foo<T1, T2 = Self> {
715     fn bar(&self, this: &T1, that: &T2);
716 }
717
718 struct S<T>;
719 impl Foo<T> for S<T> {
720     fn bar(&self, this: &T, that: &Self) {
721         ${0:todo!()}
722     }
723 }"#,
724         )
725     }
726
727     #[test]
728     fn test_assoc_type_bounds_are_removed() {
729         check_assist(
730             add_missing_impl_members,
731             r#"
732 trait Tr {
733     type Ty: Copy + 'static;
734 }
735
736 impl Tr for ()$0 {
737 }"#,
738             r#"
739 trait Tr {
740     type Ty: Copy + 'static;
741 }
742
743 impl Tr for () {
744     $0type Ty;
745 }"#,
746         )
747     }
748
749     #[test]
750     fn test_whitespace_fixup_preserves_bad_tokens() {
751         check_assist(
752             add_missing_impl_members,
753             r#"
754 trait Tr {
755     fn foo();
756 }
757
758 impl Tr for ()$0 {
759     +++
760 }"#,
761             r#"
762 trait Tr {
763     fn foo();
764 }
765
766 impl Tr for () {
767     fn foo() {
768         ${0:todo!()}
769     }
770     +++
771 }"#,
772         )
773     }
774
775     #[test]
776     fn test_whitespace_fixup_preserves_comments() {
777         check_assist(
778             add_missing_impl_members,
779             r#"
780 trait Tr {
781     fn foo();
782 }
783
784 impl Tr for ()$0 {
785     // very important
786 }"#,
787             r#"
788 trait Tr {
789     fn foo();
790 }
791
792 impl Tr for () {
793     fn foo() {
794         ${0:todo!()}
795     }
796     // very important
797 }"#,
798         )
799     }
800
801     #[test]
802     fn weird_path() {
803         check_assist(
804             add_missing_impl_members,
805             r#"
806 trait Test {
807     fn foo(&self, x: crate)
808 }
809 impl Test for () {
810     $0
811 }
812 "#,
813             r#"
814 trait Test {
815     fn foo(&self, x: crate)
816 }
817 impl Test for () {
818     fn foo(&self, x: crate) {
819         ${0:todo!()}
820     }
821 }
822 "#,
823         )
824     }
825
826     #[test]
827     fn missing_generic_type() {
828         check_assist(
829             add_missing_impl_members,
830             r#"
831 trait Foo<BAR> {
832     fn foo(&self, bar: BAR);
833 }
834 impl Foo for () {
835     $0
836 }
837 "#,
838             r#"
839 trait Foo<BAR> {
840     fn foo(&self, bar: BAR);
841 }
842 impl Foo for () {
843     fn foo(&self, bar: BAR) {
844         ${0:todo!()}
845     }
846 }
847 "#,
848         )
849     }
850
851     #[test]
852     fn does_not_requalify_self_as_crate() {
853         check_assist(
854             add_missing_default_members,
855             r"
856 struct Wrapper<T>(T);
857
858 trait T {
859     fn f(self) -> Wrapper<Self> {
860         Wrapper(self)
861     }
862 }
863
864 impl T for () {
865     $0
866 }
867 ",
868             r"
869 struct Wrapper<T>(T);
870
871 trait T {
872     fn f(self) -> Wrapper<Self> {
873         Wrapper(self)
874     }
875 }
876
877 impl T for () {
878     $0fn f(self) -> Wrapper<Self> {
879         Wrapper(self)
880     }
881 }
882 ",
883         );
884     }
885
886     #[test]
887     fn test_default_body_generation() {
888         check_assist(
889             add_missing_impl_members,
890             r#"
891 //- minicore: default
892 struct Foo(usize);
893
894 impl Default for Foo {
895     $0
896 }
897 "#,
898             r#"
899 struct Foo(usize);
900
901 impl Default for Foo {
902     $0fn default() -> Self {
903         Self(Default::default())
904     }
905 }
906 "#,
907         )
908     }
909
910     #[test]
911     fn test_from_macro() {
912         check_assist(
913             add_missing_default_members,
914             r#"
915 macro_rules! foo {
916     () => {
917         trait FooB {
918             fn foo<'lt>(&'lt self) {}
919         }
920     }
921 }
922 foo!();
923 struct Foo(usize);
924
925 impl FooB for Foo {
926     $0
927 }
928 "#,
929             r#"
930 macro_rules! foo {
931     () => {
932         trait FooB {
933             fn foo<'lt>(&'lt self) {}
934         }
935     }
936 }
937 foo!();
938 struct Foo(usize);
939
940 impl FooB for Foo {
941     $0fn foo< 'lt>(& 'lt self){}
942 }
943 "#,
944         )
945     }
946
947     #[test]
948     fn test_assoc_type_when_trait_with_same_name_in_scope() {
949         check_assist(
950             add_missing_impl_members,
951             r#"
952 pub trait Foo {}
953
954 pub trait Types {
955     type Foo;
956 }
957
958 pub trait Behavior<T: Types> {
959     fn reproduce(&self, foo: T::Foo);
960 }
961
962 pub struct Impl;
963
964 impl<T: Types> Behavior<T> for Impl { $0 }"#,
965             r#"
966 pub trait Foo {}
967
968 pub trait Types {
969     type Foo;
970 }
971
972 pub trait Behavior<T: Types> {
973     fn reproduce(&self, foo: T::Foo);
974 }
975
976 pub struct Impl;
977
978 impl<T: Types> Behavior<T> for Impl {
979     fn reproduce(&self, foo: <T as Types>::Foo) {
980         ${0:todo!()}
981     }
982 }"#,
983         );
984     }
985
986     #[test]
987     fn test_assoc_type_on_concrete_type() {
988         check_assist(
989             add_missing_impl_members,
990             r#"
991 pub trait Types {
992     type Foo;
993 }
994
995 impl Types for u32 {
996     type Foo = bool;
997 }
998
999 pub trait Behavior<T: Types> {
1000     fn reproduce(&self, foo: T::Foo);
1001 }
1002
1003 pub struct Impl;
1004
1005 impl Behavior<u32> for Impl { $0 }"#,
1006             r#"
1007 pub trait Types {
1008     type Foo;
1009 }
1010
1011 impl Types for u32 {
1012     type Foo = bool;
1013 }
1014
1015 pub trait Behavior<T: Types> {
1016     fn reproduce(&self, foo: T::Foo);
1017 }
1018
1019 pub struct Impl;
1020
1021 impl Behavior<u32> for Impl {
1022     fn reproduce(&self, foo: <u32 as Types>::Foo) {
1023         ${0:todo!()}
1024     }
1025 }"#,
1026         );
1027     }
1028
1029     #[test]
1030     fn test_assoc_type_on_concrete_type_qualified() {
1031         check_assist(
1032             add_missing_impl_members,
1033             r#"
1034 pub trait Types {
1035     type Foo;
1036 }
1037
1038 impl Types for std::string::String {
1039     type Foo = bool;
1040 }
1041
1042 pub trait Behavior<T: Types> {
1043     fn reproduce(&self, foo: T::Foo);
1044 }
1045
1046 pub struct Impl;
1047
1048 impl Behavior<std::string::String> for Impl { $0 }"#,
1049             r#"
1050 pub trait Types {
1051     type Foo;
1052 }
1053
1054 impl Types for std::string::String {
1055     type Foo = bool;
1056 }
1057
1058 pub trait Behavior<T: Types> {
1059     fn reproduce(&self, foo: T::Foo);
1060 }
1061
1062 pub struct Impl;
1063
1064 impl Behavior<std::string::String> for Impl {
1065     fn reproduce(&self, foo: <std::string::String as Types>::Foo) {
1066         ${0:todo!()}
1067     }
1068 }"#,
1069         );
1070     }
1071
1072     #[test]
1073     fn test_assoc_type_on_concrete_type_multi_option_ambiguous() {
1074         check_assist(
1075             add_missing_impl_members,
1076             r#"
1077 pub trait Types {
1078     type Foo;
1079 }
1080
1081 pub trait Types2 {
1082     type Foo;
1083 }
1084
1085 impl Types for u32 {
1086     type Foo = bool;
1087 }
1088
1089 impl Types2 for u32 {
1090     type Foo = String;
1091 }
1092
1093 pub trait Behavior<T: Types + Types2> {
1094     fn reproduce(&self, foo: <T as Types2>::Foo);
1095 }
1096
1097 pub struct Impl;
1098
1099 impl Behavior<u32> for Impl { $0 }"#,
1100             r#"
1101 pub trait Types {
1102     type Foo;
1103 }
1104
1105 pub trait Types2 {
1106     type Foo;
1107 }
1108
1109 impl Types for u32 {
1110     type Foo = bool;
1111 }
1112
1113 impl Types2 for u32 {
1114     type Foo = String;
1115 }
1116
1117 pub trait Behavior<T: Types + Types2> {
1118     fn reproduce(&self, foo: <T as Types2>::Foo);
1119 }
1120
1121 pub struct Impl;
1122
1123 impl Behavior<u32> for Impl {
1124     fn reproduce(&self, foo: <u32 as Types2>::Foo) {
1125         ${0:todo!()}
1126     }
1127 }"#,
1128         );
1129     }
1130
1131     #[test]
1132     fn test_assoc_type_on_concrete_type_multi_option() {
1133         check_assist(
1134             add_missing_impl_members,
1135             r#"
1136 pub trait Types {
1137     type Foo;
1138 }
1139
1140 pub trait Types2 {
1141     type Bar;
1142 }
1143
1144 impl Types for u32 {
1145     type Foo = bool;
1146 }
1147
1148 impl Types2 for u32 {
1149     type Bar = String;
1150 }
1151
1152 pub trait Behavior<T: Types + Types2> {
1153     fn reproduce(&self, foo: T::Bar);
1154 }
1155
1156 pub struct Impl;
1157
1158 impl Behavior<u32> for Impl { $0 }"#,
1159             r#"
1160 pub trait Types {
1161     type Foo;
1162 }
1163
1164 pub trait Types2 {
1165     type Bar;
1166 }
1167
1168 impl Types for u32 {
1169     type Foo = bool;
1170 }
1171
1172 impl Types2 for u32 {
1173     type Bar = String;
1174 }
1175
1176 pub trait Behavior<T: Types + Types2> {
1177     fn reproduce(&self, foo: T::Bar);
1178 }
1179
1180 pub struct Impl;
1181
1182 impl Behavior<u32> for Impl {
1183     fn reproduce(&self, foo: <u32 as Types2>::Bar) {
1184         ${0:todo!()}
1185     }
1186 }"#,
1187         );
1188     }
1189
1190     #[test]
1191     fn test_assoc_type_on_concrete_type_multi_option_foreign() {
1192         check_assist(
1193             add_missing_impl_members,
1194             r#"
1195 mod bar {
1196     pub trait Types2 {
1197         type Bar;
1198     }
1199 }
1200
1201 pub trait Types {
1202     type Foo;
1203 }
1204
1205 impl Types for u32 {
1206     type Foo = bool;
1207 }
1208
1209 impl bar::Types2 for u32 {
1210     type Bar = String;
1211 }
1212
1213 pub trait Behavior<T: Types + bar::Types2> {
1214     fn reproduce(&self, foo: T::Bar);
1215 }
1216
1217 pub struct Impl;
1218
1219 impl Behavior<u32> for Impl { $0 }"#,
1220             r#"
1221 mod bar {
1222     pub trait Types2 {
1223         type Bar;
1224     }
1225 }
1226
1227 pub trait Types {
1228     type Foo;
1229 }
1230
1231 impl Types for u32 {
1232     type Foo = bool;
1233 }
1234
1235 impl bar::Types2 for u32 {
1236     type Bar = String;
1237 }
1238
1239 pub trait Behavior<T: Types + bar::Types2> {
1240     fn reproduce(&self, foo: T::Bar);
1241 }
1242
1243 pub struct Impl;
1244
1245 impl Behavior<u32> for Impl {
1246     fn reproduce(&self, foo: <u32 as bar::Types2>::Bar) {
1247         ${0:todo!()}
1248     }
1249 }"#,
1250         );
1251     }
1252
1253     #[test]
1254     fn test_transform_path_in_path_expr() {
1255         check_assist(
1256             add_missing_default_members,
1257             r#"
1258 pub trait Const {
1259     const FOO: u32;
1260 }
1261
1262 pub trait Trait<T: Const> {
1263     fn foo() -> bool {
1264         match T::FOO {
1265             0 => true,
1266             _ => false,
1267         }
1268     }
1269 }
1270
1271 impl Const for u32 {
1272     const FOO: u32 = 1;
1273 }
1274
1275 struct Impl;
1276
1277 impl Trait<u32> for Impl { $0 }"#,
1278             r#"
1279 pub trait Const {
1280     const FOO: u32;
1281 }
1282
1283 pub trait Trait<T: Const> {
1284     fn foo() -> bool {
1285         match T::FOO {
1286             0 => true,
1287             _ => false,
1288         }
1289     }
1290 }
1291
1292 impl Const for u32 {
1293     const FOO: u32 = 1;
1294 }
1295
1296 struct Impl;
1297
1298 impl Trait<u32> for Impl {
1299     $0fn foo() -> bool {
1300         match <u32 as Const>::FOO {
1301             0 => true,
1302             _ => false,
1303         }
1304     }
1305 }"#,
1306         );
1307     }
1308 }