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