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