ide_assists/handlers/
add_missing_impl_members.rs

1use hir::HasSource;
2use syntax::{
3    Edition,
4    ast::{self, AstNode, make},
5    syntax_editor::{Position, SyntaxEditor},
6};
7
8use crate::{
9    AssistId,
10    assist_context::{AssistContext, Assists},
11    utils::{
12        DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items,
13        gen_trait_fn_body,
14    },
15};
16
17// Assist: add_impl_missing_members
18//
19// Adds scaffold for required impl members.
20//
21// ```
22// trait Trait<T> {
23//     type X;
24//     fn foo(&self) -> T;
25//     fn bar(&self) {}
26// }
27//
28// impl Trait<u32> for () {$0
29//
30// }
31// ```
32// ->
33// ```
34// trait Trait<T> {
35//     type X;
36//     fn foo(&self) -> T;
37//     fn bar(&self) {}
38// }
39//
40// impl Trait<u32> for () {
41//     $0type X;
42//
43//     fn foo(&self) -> u32 {
44//         todo!()
45//     }
46// }
47// ```
48pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
49    add_missing_impl_members_inner(
50        acc,
51        ctx,
52        DefaultMethods::No,
53        IgnoreAssocItems::DocHiddenAttrPresent,
54        "add_impl_missing_members",
55        "Implement missing members",
56    )
57}
58
59// Assist: add_impl_default_members
60//
61// Adds scaffold for overriding default impl members.
62//
63// ```
64// trait Trait {
65//     type X;
66//     fn foo(&self);
67//     fn bar(&self) {}
68// }
69//
70// impl Trait for () {
71//     type X = ();
72//     fn foo(&self) {}$0
73// }
74// ```
75// ->
76// ```
77// trait Trait {
78//     type X;
79//     fn foo(&self);
80//     fn bar(&self) {}
81// }
82//
83// impl Trait for () {
84//     type X = ();
85//     fn foo(&self) {}
86//
87//     $0fn bar(&self) {}
88// }
89// ```
90pub(crate) fn add_missing_default_members(
91    acc: &mut Assists,
92    ctx: &AssistContext<'_>,
93) -> Option<()> {
94    add_missing_impl_members_inner(
95        acc,
96        ctx,
97        DefaultMethods::Only,
98        IgnoreAssocItems::DocHiddenAttrPresent,
99        "add_impl_default_members",
100        "Implement default members",
101    )
102}
103
104fn add_missing_impl_members_inner(
105    acc: &mut Assists,
106    ctx: &AssistContext<'_>,
107    mode: DefaultMethods,
108    ignore_items: IgnoreAssocItems,
109    assist_id: &'static str,
110    label: &'static str,
111) -> Option<()> {
112    let _p = tracing::info_span!("add_missing_impl_members_inner").entered();
113    let impl_def = ctx.find_node_at_offset::<ast::Impl>()?;
114    let impl_ = ctx.sema.to_def(&impl_def)?;
115
116    if ctx.token_at_offset().all(|t| {
117        t.parent_ancestors()
118            .take_while(|node| node != impl_def.syntax())
119            .any(|s| ast::BlockExpr::can_cast(s.kind()) || ast::ParamList::can_cast(s.kind()))
120    }) {
121        return None;
122    }
123
124    let target_scope = ctx.sema.scope(impl_def.syntax())?;
125    let trait_ref = impl_.trait_ref(ctx.db())?;
126    let trait_ = trait_ref.trait_();
127
128    let mut ign_item = ignore_items;
129
130    if let IgnoreAssocItems::DocHiddenAttrPresent = ignore_items {
131        // Relax condition for local crates.
132        let db = ctx.db();
133        if trait_.module(db).krate(db).origin(db).is_local() {
134            ign_item = IgnoreAssocItems::No;
135        }
136    }
137
138    let missing_items = filter_assoc_items(
139        &ctx.sema,
140        &ide_db::traits::get_missing_assoc_items(&ctx.sema, &impl_def),
141        mode,
142        ign_item,
143    );
144
145    if missing_items.is_empty() {
146        return None;
147    }
148
149    let target = impl_def.syntax().text_range();
150    acc.add(AssistId::quick_fix(assist_id), label, target, |edit| {
151        let new_item = add_trait_assoc_items_to_impl(
152            &ctx.sema,
153            ctx.config,
154            &missing_items,
155            trait_,
156            &impl_def,
157            &target_scope,
158        );
159
160        let Some((first_new_item, other_items)) = new_item.split_first() else {
161            return;
162        };
163
164        let mut first_new_item = if let DefaultMethods::No = mode
165            && let ast::AssocItem::Fn(func) = &first_new_item
166            && let Some(body) = try_gen_trait_body(
167                ctx,
168                func,
169                trait_ref,
170                &impl_def,
171                target_scope.krate().edition(ctx.sema.db),
172            )
173            && let Some(func_body) = func.body()
174        {
175            let mut func_editor = SyntaxEditor::new(first_new_item.syntax().clone_subtree());
176            func_editor.replace(func_body.syntax(), body.syntax());
177            ast::AssocItem::cast(func_editor.finish().new_root().clone())
178        } else {
179            Some(first_new_item.clone())
180        };
181
182        let new_assoc_items = first_new_item
183            .clone()
184            .into_iter()
185            .chain(other_items.iter().cloned())
186            .collect::<Vec<_>>();
187
188        let mut editor = edit.make_editor(impl_def.syntax());
189        if let Some(assoc_item_list) = impl_def.assoc_item_list() {
190            assoc_item_list.add_items(&mut editor, new_assoc_items);
191        } else {
192            let assoc_item_list = make::assoc_item_list(Some(new_assoc_items)).clone_for_update();
193            editor.insert_all(
194                Position::after(impl_def.syntax()),
195                vec![make::tokens::whitespace(" ").into(), assoc_item_list.syntax().clone().into()],
196            );
197            first_new_item = assoc_item_list.assoc_items().next();
198        }
199
200        if let Some(cap) = ctx.config.snippet_cap {
201            let mut placeholder = None;
202            if let DefaultMethods::No = mode
203                && let Some(ast::AssocItem::Fn(func)) = &first_new_item
204                && let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
205                && m.syntax().text() == "todo!()"
206            {
207                placeholder = Some(m);
208            }
209
210            if let Some(macro_call) = placeholder {
211                let placeholder = edit.make_placeholder_snippet(cap);
212                editor.add_annotation(macro_call.syntax(), placeholder);
213            } else if let Some(first_new_item) = first_new_item {
214                let tabstop = edit.make_tabstop_before(cap);
215                editor.add_annotation(first_new_item.syntax(), tabstop);
216            };
217        };
218        edit.add_file_edits(ctx.vfs_file_id(), editor);
219    })
220}
221
222fn try_gen_trait_body(
223    ctx: &AssistContext<'_>,
224    func: &ast::Fn,
225    trait_ref: hir::TraitRef<'_>,
226    impl_def: &ast::Impl,
227    edition: Edition,
228) -> Option<ast::BlockExpr> {
229    let trait_path = make::ext::ident_path(
230        &trait_ref.trait_().name(ctx.db()).display(ctx.db(), edition).to_string(),
231    );
232    let hir_ty = ctx.sema.resolve_type(&impl_def.self_ty()?)?;
233    let adt = hir_ty.as_adt()?.source(ctx.db())?;
234    gen_trait_fn_body(func, &trait_path, &adt.value, Some(trait_ref))
235}
236
237#[cfg(test)]
238mod tests {
239    use crate::tests::{check_assist, check_assist_not_applicable};
240
241    use super::*;
242
243    #[test]
244    fn test_add_missing_impl_members() {
245        check_assist(
246            add_missing_impl_members,
247            r#"
248trait Foo {
249    type Output;
250
251    const CONST: usize = 42;
252    const CONST_2: i32;
253
254    fn foo(&self);
255    fn bar(&self);
256    fn baz(&self);
257}
258
259struct S;
260
261impl Foo for S {
262    fn bar(&self) {}
263$0
264}"#,
265            r#"
266trait Foo {
267    type Output;
268
269    const CONST: usize = 42;
270    const CONST_2: i32;
271
272    fn foo(&self);
273    fn bar(&self);
274    fn baz(&self);
275}
276
277struct S;
278
279impl Foo for S {
280    fn bar(&self) {}
281
282    $0type Output;
283
284    const CONST_2: i32;
285
286    fn foo(&self) {
287        todo!()
288    }
289
290    fn baz(&self) {
291        todo!()
292    }
293
294}"#,
295        );
296    }
297
298    #[test]
299    fn test_copied_overridden_members() {
300        check_assist(
301            add_missing_impl_members,
302            r#"
303trait Foo {
304    fn foo(&self);
305    fn bar(&self) -> bool { true }
306    fn baz(&self) -> u32 { 42 }
307}
308
309struct S;
310
311impl Foo for S {
312    fn bar(&self) {}
313$0
314}"#,
315            r#"
316trait Foo {
317    fn foo(&self);
318    fn bar(&self) -> bool { true }
319    fn baz(&self) -> u32 { 42 }
320}
321
322struct S;
323
324impl Foo for S {
325    fn bar(&self) {}
326
327    fn foo(&self) {
328        ${0:todo!()}
329    }
330
331}"#,
332        );
333    }
334
335    #[test]
336    fn test_empty_impl_def() {
337        check_assist(
338            add_missing_impl_members,
339            r#"
340trait Foo { fn foo(&self); }
341struct S;
342impl Foo for S { $0 }"#,
343            r#"
344trait Foo { fn foo(&self); }
345struct S;
346impl Foo for S {
347    fn foo(&self) {
348        ${0:todo!()}
349    }
350}"#,
351        );
352    }
353
354    #[test]
355    fn test_impl_def_without_braces_macro() {
356        check_assist(
357            add_missing_impl_members,
358            r#"
359trait Foo { fn foo(&self); }
360struct S;
361impl Foo for S$0"#,
362            r#"
363trait Foo { fn foo(&self); }
364struct S;
365impl Foo for S {
366    fn foo(&self) {
367        ${0:todo!()}
368    }
369}"#,
370        );
371    }
372
373    #[test]
374    fn test_impl_def_without_braces_tabstop_first_item() {
375        check_assist(
376            add_missing_impl_members,
377            r#"
378trait Foo {
379    type Output;
380    fn foo(&self);
381}
382struct S;
383impl Foo for S { $0 }"#,
384            r#"
385trait Foo {
386    type Output;
387    fn foo(&self);
388}
389struct S;
390impl Foo for S {
391    $0type Output;
392
393    fn foo(&self) {
394        todo!()
395    }
396}"#,
397        );
398    }
399
400    #[test]
401    fn fill_in_type_params_1() {
402        check_assist(
403            add_missing_impl_members,
404            r#"
405trait Foo<T> { fn foo(&self, t: T) -> &T; }
406struct S;
407impl Foo<u32> for S { $0 }"#,
408            r#"
409trait Foo<T> { fn foo(&self, t: T) -> &T; }
410struct S;
411impl Foo<u32> for S {
412    fn foo(&self, t: u32) -> &u32 {
413        ${0:todo!()}
414    }
415}"#,
416        );
417    }
418
419    #[test]
420    fn fill_in_type_params_2() {
421        check_assist(
422            add_missing_impl_members,
423            r#"
424trait Foo<T> { fn foo(&self, t: T) -> &T; }
425struct S;
426impl<U> Foo<U> for S { $0 }"#,
427            r#"
428trait Foo<T> { fn foo(&self, t: T) -> &T; }
429struct S;
430impl<U> Foo<U> for S {
431    fn foo(&self, t: U) -> &U {
432        ${0:todo!()}
433    }
434}"#,
435        );
436    }
437
438    #[test]
439    fn test_lifetime_substitution() {
440        check_assist(
441            add_missing_impl_members,
442            r#"
443pub trait Trait<'a, 'b, A, B, C> {
444    fn foo(&self, one: &'a A, another: &'b B) -> &'a C;
445}
446
447impl<'x, 'y, T, V, U> Trait<'x, 'y, T, V, U> for () {$0}"#,
448            r#"
449pub trait Trait<'a, 'b, A, B, C> {
450    fn foo(&self, one: &'a A, another: &'b B) -> &'a C;
451}
452
453impl<'x, 'y, T, V, U> Trait<'x, 'y, T, V, U> for () {
454    fn foo(&self, one: &'x T, another: &'y V) -> &'x U {
455        ${0:todo!()}
456    }
457}"#,
458        );
459    }
460
461    #[test]
462    fn test_lifetime_substitution_with_body() {
463        check_assist(
464            add_missing_default_members,
465            r#"
466pub trait Trait<'a, 'b, A, B, C: Default> {
467    fn foo(&self, _one: &'a A, _another: &'b B) -> (C, &'a i32) {
468        let value: &'a i32 = &0;
469        (C::default(), value)
470    }
471}
472
473impl<'x, 'y, T, V, U: Default> Trait<'x, 'y, T, V, U> for () {$0}"#,
474            r#"
475pub trait Trait<'a, 'b, A, B, C: Default> {
476    fn foo(&self, _one: &'a A, _another: &'b B) -> (C, &'a i32) {
477        let value: &'a i32 = &0;
478        (C::default(), value)
479    }
480}
481
482impl<'x, 'y, T, V, U: Default> Trait<'x, 'y, T, V, U> for () {
483    $0fn foo(&self, _one: &'x T, _another: &'y V) -> (U, &'x i32) {
484        let value: &'x i32 = &0;
485        (<U>::default(), value)
486    }
487}"#,
488        );
489    }
490
491    #[test]
492    fn test_const_substitution() {
493        check_assist(
494            add_missing_default_members,
495            r#"
496struct Bar<const N: usize> {
497    bar: [i32, N]
498}
499
500trait Foo<const N: usize, T> {
501    fn get_n_sq(&self, arg: &T) -> usize { N * N }
502    fn get_array(&self, arg: Bar<N>) -> [i32; N] { [1; N] }
503}
504
505struct S<T> {
506    wrapped: T
507}
508
509impl<const X: usize, Y, Z> Foo<X, Z> for S<Y> {
510    $0
511}"#,
512            r#"
513struct Bar<const N: usize> {
514    bar: [i32, N]
515}
516
517trait Foo<const N: usize, T> {
518    fn get_n_sq(&self, arg: &T) -> usize { N * N }
519    fn get_array(&self, arg: Bar<N>) -> [i32; N] { [1; N] }
520}
521
522struct S<T> {
523    wrapped: T
524}
525
526impl<const X: usize, Y, Z> Foo<X, Z> for S<Y> {
527    $0fn get_n_sq(&self, arg: &Z) -> usize { X * X }
528
529    fn get_array(&self, arg: Bar<X>) -> [i32; X] { [1; X] }
530}"#,
531        )
532    }
533
534    #[test]
535    fn test_const_substitution_2() {
536        check_assist(
537            add_missing_default_members,
538            r#"
539trait Foo<const N: usize, const M: usize, T> {
540    fn get_sum(&self, arg: &T) -> usize { N + M }
541}
542
543impl<X> Foo<42, {20 + 22}, X> for () {
544    $0
545}"#,
546            r#"
547trait Foo<const N: usize, const M: usize, T> {
548    fn get_sum(&self, arg: &T) -> usize { N + M }
549}
550
551impl<X> Foo<42, {20 + 22}, X> for () {
552    $0fn get_sum(&self, arg: &X) -> usize { 42 + {20 + 22} }
553}"#,
554        )
555    }
556
557    #[test]
558    fn test_const_substitution_with_defaults() {
559        check_assist(
560            add_missing_default_members,
561            r#"
562trait Foo<T, const N: usize = 42, const M: bool = false, const P: char = 'a'> {
563    fn get_n(&self) -> usize { N }
564    fn get_m(&self) -> bool { M }
565    fn get_p(&self) -> char { P }
566    fn get_array(&self, arg: &T) -> [bool; N] { [M; N] }
567}
568
569impl<X> Foo<X> for () {
570    $0
571}"#,
572            r#"
573trait Foo<T, const N: usize = 42, const M: bool = false, const P: char = 'a'> {
574    fn get_n(&self) -> usize { N }
575    fn get_m(&self) -> bool { M }
576    fn get_p(&self) -> char { P }
577    fn get_array(&self, arg: &T) -> [bool; N] { [M; N] }
578}
579
580impl<X> Foo<X> for () {
581    $0fn get_n(&self) -> usize { 42 }
582
583    fn get_m(&self) -> bool { false }
584
585    fn get_p(&self) -> char { 'a' }
586
587    fn get_array(&self, arg: &X) -> [bool; 42] { [false; 42] }
588}"#,
589        );
590    }
591
592    #[test]
593    fn test_const_substitution_with_defaults_2() {
594        check_assist(
595            add_missing_impl_members,
596            r#"
597mod m {
598    pub const LEN: usize = 42;
599    pub trait Foo<const M: usize = LEN, const N: usize = M, T = [bool; N]> {
600        fn get_t(&self) -> T;
601    }
602}
603
604impl m::Foo for () {
605    $0
606}"#,
607            r#"
608mod m {
609    pub const LEN: usize = 42;
610    pub trait Foo<const M: usize = LEN, const N: usize = M, T = [bool; N]> {
611        fn get_t(&self) -> T;
612    }
613}
614
615impl m::Foo for () {
616    fn get_t(&self) -> [bool; m::LEN] {
617        ${0:todo!()}
618    }
619}"#,
620        )
621    }
622
623    #[test]
624    fn test_const_substitution_with_defaults_3() {
625        check_assist(
626            add_missing_default_members,
627            r#"
628mod m {
629    pub const VAL: usize = 0;
630
631    pub trait Foo<const N: usize = {40 + 2}, const M: usize = {VAL + 1}> {
632        fn get_n(&self) -> usize { N }
633        fn get_m(&self) -> usize { M }
634    }
635}
636
637impl m::Foo for () {
638    $0
639}"#,
640            r#"
641mod m {
642    pub const VAL: usize = 0;
643
644    pub trait Foo<const N: usize = {40 + 2}, const M: usize = {VAL + 1}> {
645        fn get_n(&self) -> usize { N }
646        fn get_m(&self) -> usize { M }
647    }
648}
649
650impl m::Foo for () {
651    $0fn get_n(&self) -> usize { N }
652
653    fn get_m(&self) -> usize { M }
654}"#,
655        )
656    }
657
658    #[test]
659    fn test_cursor_after_empty_impl_def() {
660        check_assist(
661            add_missing_impl_members,
662            r#"
663trait Foo { fn foo(&self); }
664struct S;
665impl Foo for S {}$0"#,
666            r#"
667trait Foo { fn foo(&self); }
668struct S;
669impl Foo for S {
670    fn foo(&self) {
671        ${0:todo!()}
672    }
673}"#,
674        )
675    }
676
677    #[test]
678    fn test_qualify_path_1() {
679        check_assist(
680            add_missing_impl_members,
681            r#"
682mod foo {
683    pub struct Bar;
684    pub trait Foo { fn foo(&self, bar: Bar); }
685}
686struct S;
687impl foo::Foo for S { $0 }"#,
688            r#"
689mod foo {
690    pub struct Bar;
691    pub trait Foo { fn foo(&self, bar: Bar); }
692}
693struct S;
694impl foo::Foo for S {
695    fn foo(&self, bar: foo::Bar) {
696        ${0:todo!()}
697    }
698}"#,
699        );
700    }
701
702    #[test]
703    fn test_qualify_path_2() {
704        check_assist(
705            add_missing_impl_members,
706            r#"
707mod foo {
708    pub mod bar {
709        pub struct Bar;
710        pub trait Foo { fn foo(&self, bar: Bar); }
711    }
712}
713
714use foo::bar;
715
716struct S;
717impl bar::Foo for S { $0 }"#,
718            r#"
719mod foo {
720    pub mod bar {
721        pub struct Bar;
722        pub trait Foo { fn foo(&self, bar: Bar); }
723    }
724}
725
726use foo::bar;
727
728struct S;
729impl bar::Foo for S {
730    fn foo(&self, bar: bar::Bar) {
731        ${0:todo!()}
732    }
733}"#,
734        );
735    }
736
737    #[test]
738    fn test_qualify_path_generic() {
739        check_assist(
740            add_missing_impl_members,
741            r#"
742mod foo {
743    pub struct Bar<T>;
744    pub trait Foo { fn foo(&self, bar: Bar<u32>); }
745}
746struct S;
747impl foo::Foo for S { $0 }"#,
748            r#"
749mod foo {
750    pub struct Bar<T>;
751    pub trait Foo { fn foo(&self, bar: Bar<u32>); }
752}
753struct S;
754impl foo::Foo for S {
755    fn foo(&self, bar: foo::Bar<u32>) {
756        ${0:todo!()}
757    }
758}"#,
759        );
760    }
761
762    #[test]
763    fn test_qualify_path_and_substitute_param() {
764        check_assist(
765            add_missing_impl_members,
766            r#"
767mod foo {
768    pub struct Bar<T>;
769    pub trait Foo<T> { fn foo(&self, bar: Bar<T>); }
770}
771struct S;
772impl foo::Foo<u32> for S { $0 }"#,
773            r#"
774mod foo {
775    pub struct Bar<T>;
776    pub trait Foo<T> { fn foo(&self, bar: Bar<T>); }
777}
778struct S;
779impl foo::Foo<u32> for S {
780    fn foo(&self, bar: foo::Bar<u32>) {
781        ${0:todo!()}
782    }
783}"#,
784        );
785    }
786
787    #[test]
788    fn test_substitute_param_no_qualify() {
789        // when substituting params, the substituted param should not be qualified!
790        check_assist(
791            add_missing_impl_members,
792            r#"
793mod foo {
794    pub trait Foo<T> { fn foo(&self, bar: T); }
795    pub struct Param;
796}
797struct Param;
798struct S;
799impl foo::Foo<Param> for S { $0 }"#,
800            r#"
801mod foo {
802    pub trait Foo<T> { fn foo(&self, bar: T); }
803    pub struct Param;
804}
805struct Param;
806struct S;
807impl foo::Foo<Param> for S {
808    fn foo(&self, bar: Param) {
809        ${0:todo!()}
810    }
811}"#,
812        );
813    }
814
815    #[test]
816    fn test_qualify_path_associated_item() {
817        check_assist(
818            add_missing_impl_members,
819            r#"
820mod foo {
821    pub struct Bar<T>;
822    impl Bar<T> { type Assoc = u32; }
823    pub trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
824}
825struct S;
826impl foo::Foo for S { $0 }"#,
827            r#"
828mod foo {
829    pub struct Bar<T>;
830    impl Bar<T> { type Assoc = u32; }
831    pub trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
832}
833struct S;
834impl foo::Foo for S {
835    fn foo(&self, bar: foo::Bar<u32>::Assoc) {
836        ${0:todo!()}
837    }
838}"#,
839        );
840    }
841
842    #[test]
843    fn test_qualify_path_nested() {
844        check_assist(
845            add_missing_impl_members,
846            r#"
847mod foo {
848    pub struct Bar<T>;
849    pub struct Baz;
850    pub trait Foo { fn foo(&self, bar: Bar<Baz>); }
851}
852struct S;
853impl foo::Foo for S { $0 }"#,
854            r#"
855mod foo {
856    pub struct Bar<T>;
857    pub struct Baz;
858    pub trait Foo { fn foo(&self, bar: Bar<Baz>); }
859}
860struct S;
861impl foo::Foo for S {
862    fn foo(&self, bar: foo::Bar<foo::Baz>) {
863        ${0:todo!()}
864    }
865}"#,
866        );
867    }
868
869    #[test]
870    fn test_qualify_path_fn_trait_notation() {
871        check_assist(
872            add_missing_impl_members,
873            r#"
874mod foo {
875    pub trait Fn<Args> { type Output; }
876    pub trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
877}
878struct S;
879impl foo::Foo for S { $0 }"#,
880            r#"
881mod foo {
882    pub trait Fn<Args> { type Output; }
883    pub trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
884}
885struct S;
886impl foo::Foo for S {
887    fn foo(&self, bar: dyn Fn(u32) -> i32) {
888        ${0:todo!()}
889    }
890}"#,
891        );
892    }
893
894    #[test]
895    fn test_empty_trait() {
896        check_assist_not_applicable(
897            add_missing_impl_members,
898            r#"
899trait Foo;
900struct S;
901impl Foo for S { $0 }"#,
902        )
903    }
904
905    #[test]
906    fn test_ignore_unnamed_trait_members_and_default_methods() {
907        check_assist_not_applicable(
908            add_missing_impl_members,
909            r#"
910trait Foo {
911    fn (arg: u32);
912    fn valid(some: u32) -> bool { false }
913}
914struct S;
915impl Foo for S { $0 }"#,
916        )
917    }
918
919    #[test]
920    fn test_with_docstring_and_attrs() {
921        check_assist(
922            add_missing_impl_members,
923            r#"
924#[doc(alias = "test alias")]
925trait Foo {
926    /// doc string
927    type Output;
928
929    #[must_use]
930    fn foo(&self);
931}
932struct S;
933impl Foo for S {}$0"#,
934            r#"
935#[doc(alias = "test alias")]
936trait Foo {
937    /// doc string
938    type Output;
939
940    #[must_use]
941    fn foo(&self);
942}
943struct S;
944impl Foo for S {
945    $0type Output;
946
947    fn foo(&self) {
948        todo!()
949    }
950}"#,
951        )
952    }
953
954    #[test]
955    fn test_default_methods() {
956        check_assist(
957            add_missing_default_members,
958            r#"
959trait Foo {
960    type Output;
961
962    const CONST: usize = 42;
963    const CONST_2: i32;
964
965    fn valid(some: u32) -> bool { false }
966    fn foo(some: u32) -> bool;
967}
968struct S;
969impl Foo for S { $0 }"#,
970            r#"
971trait Foo {
972    type Output;
973
974    const CONST: usize = 42;
975    const CONST_2: i32;
976
977    fn valid(some: u32) -> bool { false }
978    fn foo(some: u32) -> bool;
979}
980struct S;
981impl Foo for S {
982    $0const CONST: usize = 42;
983
984    fn valid(some: u32) -> bool { false }
985}"#,
986        )
987    }
988
989    #[test]
990    fn test_generic_single_default_parameter() {
991        check_assist(
992            add_missing_impl_members,
993            r#"
994trait Foo<T = Self> {
995    fn bar(&self, other: &T);
996}
997
998struct S;
999impl Foo for S { $0 }"#,
1000            r#"
1001trait Foo<T = Self> {
1002    fn bar(&self, other: &T);
1003}
1004
1005struct S;
1006impl Foo for S {
1007    fn bar(&self, other: &Self) {
1008        ${0:todo!()}
1009    }
1010}"#,
1011        )
1012    }
1013
1014    #[test]
1015    fn test_generic_default_parameter_is_second() {
1016        check_assist(
1017            add_missing_impl_members,
1018            r#"
1019trait Foo<T1, T2 = Self> {
1020    fn bar(&self, this: &T1, that: &T2);
1021}
1022
1023struct S<T>;
1024impl Foo<T> for S<T> { $0 }"#,
1025            r#"
1026trait Foo<T1, T2 = Self> {
1027    fn bar(&self, this: &T1, that: &T2);
1028}
1029
1030struct S<T>;
1031impl Foo<T> for S<T> {
1032    fn bar(&self, this: &T, that: &Self) {
1033        ${0:todo!()}
1034    }
1035}"#,
1036        )
1037    }
1038
1039    #[test]
1040    fn test_qualify_generic_default_parameter() {
1041        check_assist(
1042            add_missing_impl_members,
1043            r#"
1044mod m {
1045    pub struct S;
1046    pub trait Foo<T = S> {
1047        fn bar(&self, other: &T);
1048    }
1049}
1050
1051struct S;
1052impl m::Foo for S { $0 }"#,
1053            r#"
1054mod m {
1055    pub struct S;
1056    pub trait Foo<T = S> {
1057        fn bar(&self, other: &T);
1058    }
1059}
1060
1061struct S;
1062impl m::Foo for S {
1063    fn bar(&self, other: &m::S) {
1064        ${0:todo!()}
1065    }
1066}"#,
1067        )
1068    }
1069
1070    #[test]
1071    fn test_qualify_generic_default_parameter_2() {
1072        check_assist(
1073            add_missing_impl_members,
1074            r#"
1075mod m {
1076    pub struct Wrapper<T, V> {
1077        one: T,
1078        another: V
1079    };
1080    pub struct S;
1081    pub trait Foo<T = Wrapper<S, bool>> {
1082        fn bar(&self, other: &T);
1083    }
1084}
1085
1086struct S;
1087impl m::Foo for S { $0 }"#,
1088            r#"
1089mod m {
1090    pub struct Wrapper<T, V> {
1091        one: T,
1092        another: V
1093    };
1094    pub struct S;
1095    pub trait Foo<T = Wrapper<S, bool>> {
1096        fn bar(&self, other: &T);
1097    }
1098}
1099
1100struct S;
1101impl m::Foo for S {
1102    fn bar(&self, other: &m::Wrapper<m::S, bool>) {
1103        ${0:todo!()}
1104    }
1105}"#,
1106        );
1107    }
1108
1109    #[test]
1110    fn test_qualify_generic_default_parameter_3() {
1111        check_assist(
1112            add_missing_impl_members,
1113            r#"
1114mod m {
1115    pub struct Wrapper<T, V> {
1116        one: T,
1117        another: V
1118    };
1119    pub struct S;
1120    pub trait Foo<T = S, V = Wrapper<T, S>> {
1121        fn bar(&self, other: &V);
1122    }
1123}
1124
1125struct S;
1126impl m::Foo for S { $0 }"#,
1127            r#"
1128mod m {
1129    pub struct Wrapper<T, V> {
1130        one: T,
1131        another: V
1132    };
1133    pub struct S;
1134    pub trait Foo<T = S, V = Wrapper<T, S>> {
1135        fn bar(&self, other: &V);
1136    }
1137}
1138
1139struct S;
1140impl m::Foo for S {
1141    fn bar(&self, other: &m::Wrapper<m::S, m::S>) {
1142        ${0:todo!()}
1143    }
1144}"#,
1145        );
1146    }
1147
1148    #[test]
1149    fn test_assoc_type_bounds_are_removed() {
1150        check_assist(
1151            add_missing_impl_members,
1152            r#"
1153trait Tr {
1154    type Ty: Copy + 'static;
1155}
1156
1157impl Tr for ()$0 {
1158}"#,
1159            r#"
1160trait Tr {
1161    type Ty: Copy + 'static;
1162}
1163
1164impl Tr for () {
1165    $0type Ty;
1166}"#,
1167        )
1168    }
1169
1170    #[test]
1171    fn test_whitespace_fixup_preserves_bad_tokens() {
1172        check_assist(
1173            add_missing_impl_members,
1174            r#"
1175trait Tr {
1176    fn foo();
1177}
1178
1179impl Tr for ()$0 {
1180    +++
1181}"#,
1182            r#"
1183trait Tr {
1184    fn foo();
1185}
1186
1187impl Tr for () {
1188    fn foo() {
1189        ${0:todo!()}
1190    }
1191    +++
1192}"#,
1193        )
1194    }
1195
1196    #[test]
1197    fn test_whitespace_fixup_preserves_comments() {
1198        check_assist(
1199            add_missing_impl_members,
1200            r#"
1201trait Tr {
1202    fn foo();
1203}
1204
1205impl Tr for ()$0 {
1206    // very important
1207}"#,
1208            r#"
1209trait Tr {
1210    fn foo();
1211}
1212
1213impl Tr for () {
1214    fn foo() {
1215        ${0:todo!()}
1216    }
1217    // very important
1218}"#,
1219        )
1220    }
1221
1222    #[test]
1223    fn weird_path() {
1224        check_assist(
1225            add_missing_impl_members,
1226            r#"
1227trait Test {
1228    fn foo(&self, x: crate)
1229}
1230impl Test for () {
1231    $0
1232}
1233"#,
1234            r#"
1235trait Test {
1236    fn foo(&self, x: crate)
1237}
1238impl Test for () {
1239    fn foo(&self, x: crate) {
1240        ${0:todo!()}
1241    }
1242}
1243"#,
1244        )
1245    }
1246
1247    #[test]
1248    fn missing_generic_type() {
1249        check_assist(
1250            add_missing_impl_members,
1251            r#"
1252trait Foo<BAR> {
1253    fn foo(&self, bar: BAR);
1254}
1255impl Foo for () {
1256    $0
1257}
1258"#,
1259            r#"
1260trait Foo<BAR> {
1261    fn foo(&self, bar: BAR);
1262}
1263impl Foo for () {
1264    fn foo(&self, bar: BAR) {
1265        ${0:todo!()}
1266    }
1267}
1268"#,
1269        )
1270    }
1271
1272    #[test]
1273    fn does_not_requalify_self_as_crate() {
1274        check_assist(
1275            add_missing_default_members,
1276            r"
1277struct Wrapper<T>(T);
1278
1279trait T {
1280    fn f(self) -> Wrapper<Self> {
1281        Wrapper(self)
1282    }
1283}
1284
1285impl T for () {
1286    $0
1287}
1288",
1289            r"
1290struct Wrapper<T>(T);
1291
1292trait T {
1293    fn f(self) -> Wrapper<Self> {
1294        Wrapper(self)
1295    }
1296}
1297
1298impl T for () {
1299    $0fn f(self) -> Wrapper<Self> {
1300        Wrapper(self)
1301    }
1302}
1303",
1304        );
1305    }
1306
1307    #[test]
1308    fn test_default_body_generation() {
1309        check_assist(
1310            add_missing_impl_members,
1311            r#"
1312//- minicore: default
1313struct Foo(usize);
1314
1315impl Default for Foo {
1316    $0
1317}
1318"#,
1319            r#"
1320struct Foo(usize);
1321
1322impl Default for Foo {
1323    $0fn default() -> Self {
1324        Self(Default::default())
1325    }
1326}
1327"#,
1328        )
1329    }
1330
1331    #[test]
1332    fn test_from_macro() {
1333        check_assist(
1334            add_missing_default_members,
1335            r#"
1336macro_rules! foo {
1337    () => {
1338        trait FooB {
1339            fn foo<'lt>(&'lt self) {}
1340        }
1341    }
1342}
1343foo!();
1344struct Foo(usize);
1345
1346impl FooB for Foo {
1347    $0
1348}
1349"#,
1350            r#"
1351macro_rules! foo {
1352    () => {
1353        trait FooB {
1354            fn foo<'lt>(&'lt self) {}
1355        }
1356    }
1357}
1358foo!();
1359struct Foo(usize);
1360
1361impl FooB for Foo {
1362    $0fn foo<'lt>(&'lt self){}
1363}
1364"#,
1365        )
1366    }
1367
1368    #[test]
1369    fn test_assoc_type_when_trait_with_same_name_in_scope() {
1370        check_assist(
1371            add_missing_impl_members,
1372            r#"
1373pub trait Foo {}
1374
1375pub trait Types {
1376    type Foo;
1377}
1378
1379pub trait Behavior<T: Types> {
1380    fn reproduce(&self, foo: T::Foo);
1381}
1382
1383pub struct Impl;
1384
1385impl<T: Types> Behavior<T> for Impl { $0 }"#,
1386            r#"
1387pub trait Foo {}
1388
1389pub trait Types {
1390    type Foo;
1391}
1392
1393pub trait Behavior<T: Types> {
1394    fn reproduce(&self, foo: T::Foo);
1395}
1396
1397pub struct Impl;
1398
1399impl<T: Types> Behavior<T> for Impl {
1400    fn reproduce(&self, foo: <T as Types>::Foo) {
1401        ${0:todo!()}
1402    }
1403}"#,
1404        );
1405    }
1406
1407    #[test]
1408    fn test_assoc_type_on_concrete_type() {
1409        check_assist(
1410            add_missing_impl_members,
1411            r#"
1412pub trait Types {
1413    type Foo;
1414}
1415
1416impl Types for u32 {
1417    type Foo = bool;
1418}
1419
1420pub trait Behavior<T: Types> {
1421    fn reproduce(&self, foo: T::Foo);
1422}
1423
1424pub struct Impl;
1425
1426impl Behavior<u32> for Impl { $0 }"#,
1427            r#"
1428pub trait Types {
1429    type Foo;
1430}
1431
1432impl Types for u32 {
1433    type Foo = bool;
1434}
1435
1436pub trait Behavior<T: Types> {
1437    fn reproduce(&self, foo: T::Foo);
1438}
1439
1440pub struct Impl;
1441
1442impl Behavior<u32> for Impl {
1443    fn reproduce(&self, foo: <u32 as Types>::Foo) {
1444        ${0:todo!()}
1445    }
1446}"#,
1447        );
1448    }
1449
1450    #[test]
1451    fn test_assoc_type_on_concrete_type_qualified() {
1452        check_assist(
1453            add_missing_impl_members,
1454            r#"
1455pub trait Types {
1456    type Foo;
1457}
1458
1459impl Types for std::string::String {
1460    type Foo = bool;
1461}
1462
1463pub trait Behavior<T: Types> {
1464    fn reproduce(&self, foo: T::Foo);
1465}
1466
1467pub struct Impl;
1468
1469impl Behavior<std::string::String> for Impl { $0 }"#,
1470            r#"
1471pub trait Types {
1472    type Foo;
1473}
1474
1475impl Types for std::string::String {
1476    type Foo = bool;
1477}
1478
1479pub trait Behavior<T: Types> {
1480    fn reproduce(&self, foo: T::Foo);
1481}
1482
1483pub struct Impl;
1484
1485impl Behavior<std::string::String> for Impl {
1486    fn reproduce(&self, foo: <std::string::String as Types>::Foo) {
1487        ${0:todo!()}
1488    }
1489}"#,
1490        );
1491    }
1492
1493    #[test]
1494    fn test_assoc_type_on_concrete_type_multi_option_ambiguous() {
1495        check_assist(
1496            add_missing_impl_members,
1497            r#"
1498pub trait Types {
1499    type Foo;
1500}
1501
1502pub trait Types2 {
1503    type Foo;
1504}
1505
1506impl Types for u32 {
1507    type Foo = bool;
1508}
1509
1510impl Types2 for u32 {
1511    type Foo = String;
1512}
1513
1514pub trait Behavior<T: Types + Types2> {
1515    fn reproduce(&self, foo: <T as Types2>::Foo);
1516}
1517
1518pub struct Impl;
1519
1520impl Behavior<u32> for Impl { $0 }"#,
1521            r#"
1522pub trait Types {
1523    type Foo;
1524}
1525
1526pub trait Types2 {
1527    type Foo;
1528}
1529
1530impl Types for u32 {
1531    type Foo = bool;
1532}
1533
1534impl Types2 for u32 {
1535    type Foo = String;
1536}
1537
1538pub trait Behavior<T: Types + Types2> {
1539    fn reproduce(&self, foo: <T as Types2>::Foo);
1540}
1541
1542pub struct Impl;
1543
1544impl Behavior<u32> for Impl {
1545    fn reproduce(&self, foo: <u32 as Types2>::Foo) {
1546        ${0:todo!()}
1547    }
1548}"#,
1549        );
1550    }
1551
1552    #[test]
1553    fn test_assoc_type_on_concrete_type_multi_option() {
1554        check_assist(
1555            add_missing_impl_members,
1556            r#"
1557pub trait Types {
1558    type Foo;
1559}
1560
1561pub trait Types2 {
1562    type Bar;
1563}
1564
1565impl Types for u32 {
1566    type Foo = bool;
1567}
1568
1569impl Types2 for u32 {
1570    type Bar = String;
1571}
1572
1573pub trait Behavior<T: Types + Types2> {
1574    fn reproduce(&self, foo: T::Bar);
1575}
1576
1577pub struct Impl;
1578
1579impl Behavior<u32> for Impl { $0 }"#,
1580            r#"
1581pub trait Types {
1582    type Foo;
1583}
1584
1585pub trait Types2 {
1586    type Bar;
1587}
1588
1589impl Types for u32 {
1590    type Foo = bool;
1591}
1592
1593impl Types2 for u32 {
1594    type Bar = String;
1595}
1596
1597pub trait Behavior<T: Types + Types2> {
1598    fn reproduce(&self, foo: T::Bar);
1599}
1600
1601pub struct Impl;
1602
1603impl Behavior<u32> for Impl {
1604    fn reproduce(&self, foo: <u32 as Types2>::Bar) {
1605        ${0:todo!()}
1606    }
1607}"#,
1608        );
1609    }
1610
1611    #[test]
1612    fn test_assoc_type_on_concrete_type_multi_option_foreign() {
1613        check_assist(
1614            add_missing_impl_members,
1615            r#"
1616mod bar {
1617    pub trait Types2 {
1618        type Bar;
1619    }
1620}
1621
1622pub trait Types {
1623    type Foo;
1624}
1625
1626impl Types for u32 {
1627    type Foo = bool;
1628}
1629
1630impl bar::Types2 for u32 {
1631    type Bar = String;
1632}
1633
1634pub trait Behavior<T: Types + bar::Types2> {
1635    fn reproduce(&self, foo: T::Bar);
1636}
1637
1638pub struct Impl;
1639
1640impl Behavior<u32> for Impl { $0 }"#,
1641            r#"
1642mod bar {
1643    pub trait Types2 {
1644        type Bar;
1645    }
1646}
1647
1648pub trait Types {
1649    type Foo;
1650}
1651
1652impl Types for u32 {
1653    type Foo = bool;
1654}
1655
1656impl bar::Types2 for u32 {
1657    type Bar = String;
1658}
1659
1660pub trait Behavior<T: Types + bar::Types2> {
1661    fn reproduce(&self, foo: T::Bar);
1662}
1663
1664pub struct Impl;
1665
1666impl Behavior<u32> for Impl {
1667    fn reproduce(&self, foo: <u32 as bar::Types2>::Bar) {
1668        ${0:todo!()}
1669    }
1670}"#,
1671        );
1672    }
1673
1674    #[test]
1675    fn test_transform_path_in_path_expr() {
1676        check_assist(
1677            add_missing_default_members,
1678            r#"
1679pub trait Const {
1680    const FOO: u32;
1681}
1682
1683pub trait Trait<T: Const> {
1684    fn foo() -> bool {
1685        match T::FOO {
1686            0 => true,
1687            _ => false,
1688        }
1689    }
1690}
1691
1692impl Const for u32 {
1693    const FOO: u32 = 1;
1694}
1695
1696struct Impl;
1697
1698impl Trait<u32> for Impl { $0 }"#,
1699            r#"
1700pub trait Const {
1701    const FOO: u32;
1702}
1703
1704pub trait Trait<T: Const> {
1705    fn foo() -> bool {
1706        match T::FOO {
1707            0 => true,
1708            _ => false,
1709        }
1710    }
1711}
1712
1713impl Const for u32 {
1714    const FOO: u32 = 1;
1715}
1716
1717struct Impl;
1718
1719impl Trait<u32> for Impl {
1720    $0fn foo() -> bool {
1721        match <u32 as Const>::FOO {
1722            0 => true,
1723            _ => false,
1724        }
1725    }
1726}"#,
1727        );
1728    }
1729
1730    #[test]
1731    fn test_default_partial_eq() {
1732        check_assist(
1733            add_missing_default_members,
1734            r#"
1735//- minicore: eq
1736struct SomeStruct {
1737    data: usize,
1738    field: (usize, usize),
1739}
1740impl PartialEq for SomeStruct {$0}
1741"#,
1742            r#"
1743struct SomeStruct {
1744    data: usize,
1745    field: (usize, usize),
1746}
1747impl PartialEq for SomeStruct {
1748    $0fn ne(&self, other: &Self) -> bool {
1749        !self.eq(other)
1750    }
1751}
1752"#,
1753        );
1754    }
1755
1756    #[test]
1757    fn test_partial_eq_body_when_types_semantically_match() {
1758        check_assist(
1759            add_missing_impl_members,
1760            r#"
1761//- minicore: eq
1762struct S<T, U>(T, U);
1763type Alias<T> = S<T, T>;
1764impl<T> PartialEq<Alias<T>> for S<T, T> {$0}
1765"#,
1766            r#"
1767struct S<T, U>(T, U);
1768type Alias<T> = S<T, T>;
1769impl<T> PartialEq<Alias<T>> for S<T, T> {
1770    $0fn eq(&self, other: &Alias<T>) -> bool {
1771        self.0 == other.0 && self.1 == other.1
1772    }
1773}
1774"#,
1775        );
1776    }
1777
1778    #[test]
1779    fn test_partial_eq_body_when_types_dont_match() {
1780        check_assist(
1781            add_missing_impl_members,
1782            r#"
1783//- minicore: eq
1784struct S<T, U>(T, U);
1785type Alias<T> = S<T, T>;
1786impl<T> PartialEq<Alias<T>> for S<T, i32> {$0}
1787"#,
1788            r#"
1789struct S<T, U>(T, U);
1790type Alias<T> = S<T, T>;
1791impl<T> PartialEq<Alias<T>> for S<T, i32> {
1792    fn eq(&self, other: &Alias<T>) -> bool {
1793        ${0:todo!()}
1794    }
1795}
1796"#,
1797        );
1798    }
1799
1800    #[test]
1801    fn test_ignore_function_body() {
1802        check_assist_not_applicable(
1803            add_missing_default_members,
1804            r#"
1805trait Trait {
1806    type X;
1807    fn foo(&self);
1808    fn bar(&self) {}
1809}
1810
1811impl Trait for () {
1812    type X = u8;
1813    fn foo(&self) {$0
1814        let x = 5;
1815    }
1816}"#,
1817        )
1818    }
1819
1820    #[test]
1821    fn test_ignore_param_list() {
1822        check_assist_not_applicable(
1823            add_missing_impl_members,
1824            r#"
1825trait Trait {
1826    type X;
1827    fn foo(&self);
1828    fn bar(&self);
1829}
1830
1831impl Trait for () {
1832    type X = u8;
1833    fn foo(&self$0) {
1834        let x = 5;
1835    }
1836}"#,
1837        )
1838    }
1839
1840    #[test]
1841    fn test_ignore_scope_inside_function() {
1842        check_assist_not_applicable(
1843            add_missing_impl_members,
1844            r#"
1845trait Trait {
1846    type X;
1847    fn foo(&self);
1848    fn bar(&self);
1849}
1850
1851impl Trait for () {
1852    type X = u8;
1853    fn foo(&self) {
1854        let x = async {$0 5 };
1855    }
1856}"#,
1857        )
1858    }
1859
1860    #[test]
1861    fn test_apply_outside_function() {
1862        check_assist(
1863            add_missing_default_members,
1864            r#"
1865trait Trait {
1866    type X;
1867    fn foo(&self);
1868    fn bar(&self) {}
1869}
1870
1871impl Trait for () {
1872    type X = u8;
1873    fn foo(&self)$0 {}
1874}"#,
1875            r#"
1876trait Trait {
1877    type X;
1878    fn foo(&self);
1879    fn bar(&self) {}
1880}
1881
1882impl Trait for () {
1883    type X = u8;
1884    fn foo(&self) {}
1885
1886    $0fn bar(&self) {}
1887}"#,
1888        )
1889    }
1890
1891    #[test]
1892    fn test_works_inside_function() {
1893        check_assist(
1894            add_missing_impl_members,
1895            r#"
1896trait Tr {
1897    fn method();
1898}
1899fn main() {
1900    struct S;
1901    impl Tr for S {
1902        $0
1903    }
1904}
1905"#,
1906            r#"
1907trait Tr {
1908    fn method();
1909}
1910fn main() {
1911    struct S;
1912    impl Tr for S {
1913        fn method() {
1914            ${0:todo!()}
1915        }
1916    }
1917}
1918"#,
1919        );
1920    }
1921
1922    #[test]
1923    fn test_add_missing_preserves_indentation() {
1924        // in different modules
1925        check_assist(
1926            add_missing_impl_members,
1927            r#"
1928mod m {
1929    pub trait Foo {
1930        const CONST_MULTILINE: (
1931            i32,
1932            i32
1933        );
1934
1935        fn foo(&self);
1936    }
1937}
1938struct S;
1939impl m::Foo for S { $0 }"#,
1940            r#"
1941mod m {
1942    pub trait Foo {
1943        const CONST_MULTILINE: (
1944            i32,
1945            i32
1946        );
1947
1948        fn foo(&self);
1949    }
1950}
1951struct S;
1952impl m::Foo for S {
1953    $0const CONST_MULTILINE: (
1954        i32,
1955        i32
1956    );
1957
1958    fn foo(&self) {
1959        todo!()
1960    }
1961}"#,
1962        );
1963        // in the same module
1964        check_assist(
1965            add_missing_impl_members,
1966            r#"
1967mod m {
1968    trait Foo {
1969        type Output;
1970
1971        const CONST: usize = 42;
1972        const CONST_2: i32;
1973        const CONST_MULTILINE: (
1974            i32,
1975            i32
1976        );
1977
1978        fn foo(&self);
1979        fn bar(&self);
1980        fn baz(&self);
1981    }
1982
1983    struct S;
1984
1985    impl Foo for S {
1986        fn bar(&self) {}
1987$0
1988    }
1989}"#,
1990            r#"
1991mod m {
1992    trait Foo {
1993        type Output;
1994
1995        const CONST: usize = 42;
1996        const CONST_2: i32;
1997        const CONST_MULTILINE: (
1998            i32,
1999            i32
2000        );
2001
2002        fn foo(&self);
2003        fn bar(&self);
2004        fn baz(&self);
2005    }
2006
2007    struct S;
2008
2009    impl Foo for S {
2010        fn bar(&self) {}
2011
2012        $0type Output;
2013
2014        const CONST_2: i32;
2015
2016        const CONST_MULTILINE: (
2017            i32,
2018            i32
2019        );
2020
2021        fn foo(&self) {
2022            todo!()
2023        }
2024
2025        fn baz(&self) {
2026            todo!()
2027        }
2028
2029    }
2030}"#,
2031        );
2032    }
2033
2034    #[test]
2035    fn test_add_default_preserves_indentation() {
2036        check_assist(
2037            add_missing_default_members,
2038            r#"
2039mod m {
2040    pub trait Foo {
2041        type Output;
2042
2043        const CONST: usize = 42;
2044        const CONST_2: i32;
2045        const CONST_MULTILINE: = (
2046            i32,
2047            i32,
2048        ) = (3, 14);
2049
2050        fn valid(some: u32) -> bool { false }
2051        fn foo(some: u32) -> bool;
2052    }
2053}
2054struct S;
2055impl m::Foo for S { $0 }"#,
2056            r#"
2057mod m {
2058    pub trait Foo {
2059        type Output;
2060
2061        const CONST: usize = 42;
2062        const CONST_2: i32;
2063        const CONST_MULTILINE: = (
2064            i32,
2065            i32,
2066        ) = (3, 14);
2067
2068        fn valid(some: u32) -> bool { false }
2069        fn foo(some: u32) -> bool;
2070    }
2071}
2072struct S;
2073impl m::Foo for S {
2074    $0const CONST: usize = 42;
2075
2076    const CONST_MULTILINE: = (
2077        i32,
2078        i32,
2079    ) = (3, 14);
2080
2081    fn valid(some: u32) -> bool { false }
2082}"#,
2083        )
2084    }
2085
2086    #[test]
2087    fn nested_macro_should_not_cause_crash() {
2088        check_assist(
2089            add_missing_impl_members,
2090            r#"
2091macro_rules! ty { () => { i32 } }
2092trait SomeTrait { type Output; }
2093impl SomeTrait for i32 { type Output = i64; }
2094macro_rules! define_method {
2095    () => {
2096        fn method(&mut self, params: <ty!() as SomeTrait>::Output);
2097    };
2098}
2099trait AnotherTrait { define_method!(); }
2100impl $0AnotherTrait for () {
2101}
2102"#,
2103            r#"
2104macro_rules! ty { () => { i32 } }
2105trait SomeTrait { type Output; }
2106impl SomeTrait for i32 { type Output = i64; }
2107macro_rules! define_method {
2108    () => {
2109        fn method(&mut self, params: <ty!() as SomeTrait>::Output);
2110    };
2111}
2112trait AnotherTrait { define_method!(); }
2113impl AnotherTrait for () {
2114    $0fn method(&mut self,params: <ty!()as SomeTrait>::Output) {
2115        todo!()
2116    }
2117}
2118"#,
2119        );
2120    }
2121
2122    // FIXME: `T` in `ty!(T)` should be replaced by `PathTransform`.
2123    #[test]
2124    fn paths_in_nested_macro_should_get_transformed() {
2125        check_assist(
2126            add_missing_impl_members,
2127            r#"
2128macro_rules! ty { ($me:ty) => { $me } }
2129trait SomeTrait { type Output; }
2130impl SomeTrait for i32 { type Output = i64; }
2131macro_rules! define_method {
2132    ($t:ty) => {
2133        fn method(&mut self, params: <ty!($t) as SomeTrait>::Output);
2134    };
2135}
2136trait AnotherTrait<T: SomeTrait> { define_method!(T); }
2137impl $0AnotherTrait<i32> for () {
2138}
2139"#,
2140            r#"
2141macro_rules! ty { ($me:ty) => { $me } }
2142trait SomeTrait { type Output; }
2143impl SomeTrait for i32 { type Output = i64; }
2144macro_rules! define_method {
2145    ($t:ty) => {
2146        fn method(&mut self, params: <ty!($t) as SomeTrait>::Output);
2147    };
2148}
2149trait AnotherTrait<T: SomeTrait> { define_method!(T); }
2150impl AnotherTrait<i32> for () {
2151    $0fn method(&mut self,params: <ty!(T)as SomeTrait>::Output) {
2152        todo!()
2153    }
2154}
2155"#,
2156        );
2157    }
2158
2159    #[test]
2160    fn doc_hidden_default_impls_ignored() {
2161        // doc(hidden) attr is ignored trait and impl both belong to the local crate.
2162        check_assist(
2163            add_missing_default_members,
2164            r#"
2165struct Foo;
2166trait Trait {
2167    #[doc(hidden)]
2168    fn func_with_default_impl() -> u32 {
2169        42
2170    }
2171    fn another_default_impl() -> u32 {
2172        43
2173    }
2174}
2175impl Tra$0it for Foo {}"#,
2176            r#"
2177struct Foo;
2178trait Trait {
2179    #[doc(hidden)]
2180    fn func_with_default_impl() -> u32 {
2181        42
2182    }
2183    fn another_default_impl() -> u32 {
2184        43
2185    }
2186}
2187impl Trait for Foo {
2188    $0fn func_with_default_impl() -> u32 {
2189        42
2190    }
2191
2192    fn another_default_impl() -> u32 {
2193        43
2194    }
2195}"#,
2196        )
2197    }
2198
2199    #[test]
2200    fn doc_hidden_default_impls_lang_crates() {
2201        // Not applicable because Eq has a single method and this has a #[doc(hidden)] attr set.
2202        check_assist_not_applicable(
2203            add_missing_default_members,
2204            r#"
2205//- minicore: eq
2206use core::cmp::Eq;
2207struct Foo;
2208impl E$0q for Foo { /* $0 */ }
2209"#,
2210        )
2211    }
2212
2213    #[test]
2214    fn doc_hidden_default_impls_lib_crates() {
2215        check_assist(
2216            add_missing_default_members,
2217            r#"
2218    //- /main.rs crate:a deps:b
2219    struct B;
2220    impl b::Exte$0rnTrait for B {}
2221    //- /lib.rs crate:b new_source_root:library
2222    pub trait ExternTrait {
2223        #[doc(hidden)]
2224        fn hidden_default() -> Option<()> {
2225            todo!()
2226        }
2227
2228        fn unhidden_default() -> Option<()> {
2229            todo!()
2230        }
2231
2232        fn unhidden_nondefault() -> Option<()>;
2233    }
2234                "#,
2235            r#"
2236    struct B;
2237    impl b::ExternTrait for B {
2238        $0fn unhidden_default() -> Option<()> {
2239            todo!()
2240        }
2241    }
2242    "#,
2243        )
2244    }
2245
2246    #[test]
2247    fn doc_hidden_default_impls_local_crates() {
2248        check_assist(
2249            add_missing_default_members,
2250            r#"
2251trait LocalTrait {
2252    #[doc(hidden)]
2253    fn no_skip_default() -> Option<()> {
2254        todo!()
2255    }
2256    fn no_skip_default_2() -> Option<()> {
2257        todo!()
2258    }
2259}
2260
2261struct B;
2262impl Loc$0alTrait for B {}
2263            "#,
2264            r#"
2265trait LocalTrait {
2266    #[doc(hidden)]
2267    fn no_skip_default() -> Option<()> {
2268        todo!()
2269    }
2270    fn no_skip_default_2() -> Option<()> {
2271        todo!()
2272    }
2273}
2274
2275struct B;
2276impl LocalTrait for B {
2277    $0fn no_skip_default() -> Option<()> {
2278        todo!()
2279    }
2280
2281    fn no_skip_default_2() -> Option<()> {
2282        todo!()
2283    }
2284}
2285            "#,
2286        )
2287    }
2288
2289    #[test]
2290    fn doc_hidden_default_impls_workspace_crates() {
2291        check_assist(
2292            add_missing_default_members,
2293            r#"
2294//- /lib.rs crate:b new_source_root:local
2295trait LocalTrait {
2296    #[doc(hidden)]
2297    fn no_skip_default() -> Option<()> {
2298        todo!()
2299    }
2300    fn no_skip_default_2() -> Option<()> {
2301        todo!()
2302    }
2303}
2304
2305//- /main.rs crate:a deps:b
2306struct B;
2307impl b::Loc$0alTrait for B {}
2308            "#,
2309            r#"
2310struct B;
2311impl b::LocalTrait for B {
2312    $0fn no_skip_default() -> Option<()> {
2313        todo!()
2314    }
2315
2316    fn no_skip_default_2() -> Option<()> {
2317        todo!()
2318    }
2319}
2320            "#,
2321        )
2322    }
2323
2324    #[test]
2325    fn doc_hidden_nondefault_member() {
2326        check_assist(
2327            add_missing_impl_members,
2328            r#"
2329//- /lib.rs crate:b new_source_root:local
2330trait LocalTrait {
2331    #[doc(hidden)]
2332    fn no_skip_non_default() -> Option<()>;
2333
2334    #[doc(hidden)]
2335    fn skip_default() -> Option<()> {
2336        todo!()
2337    }
2338}
2339
2340//- /main.rs crate:a deps:b
2341struct B;
2342impl b::Loc$0alTrait for B {}
2343            "#,
2344            r#"
2345struct B;
2346impl b::LocalTrait for B {
2347    fn no_skip_non_default() -> Option<()> {
2348        ${0:todo!()}
2349    }
2350}
2351            "#,
2352        )
2353    }
2354
2355    #[test]
2356    fn impl_with_type_param_with_former_param_as_default() {
2357        check_assist(
2358            add_missing_impl_members,
2359            r#"
2360pub trait Test<'a, T, U = T> {
2361    fn test(item: &'a T) -> U;
2362}
2363impl<'a> Test<'a, i32> for bool {
2364    $0
2365}
2366"#,
2367            r#"
2368pub trait Test<'a, T, U = T> {
2369    fn test(item: &'a T) -> U;
2370}
2371impl<'a> Test<'a, i32> for bool {
2372    fn test(item: &'a i32) -> i32 {
2373        ${0:todo!()}
2374    }
2375}
2376"#,
2377        );
2378    }
2379
2380    #[test]
2381    fn issue_17321() {
2382        check_assist(
2383            add_missing_impl_members,
2384            r#"
2385fn main() {}
2386
2387mod other_file_1 {
2388    pub const SOME_CONSTANT: usize = 8;
2389}
2390
2391mod other_file_2 {
2392    use crate::other_file_1::SOME_CONSTANT;
2393
2394    pub trait Trait {
2395        type Iter: Iterator<Item = [u8; SOME_CONSTANT]>;
2396    }
2397}
2398
2399pub struct MyStruct;
2400
2401impl other_file_2::Trait for MyStruct$0 {}"#,
2402            r#"
2403fn main() {}
2404
2405mod other_file_1 {
2406    pub const SOME_CONSTANT: usize = 8;
2407}
2408
2409mod other_file_2 {
2410    use crate::other_file_1::SOME_CONSTANT;
2411
2412    pub trait Trait {
2413        type Iter: Iterator<Item = [u8; SOME_CONSTANT]>;
2414    }
2415}
2416
2417pub struct MyStruct;
2418
2419impl other_file_2::Trait for MyStruct {
2420    $0type Iter;
2421}"#,
2422        );
2423    }
2424
2425    #[test]
2426    fn test_qualify_ident_pat_in_default_members() {
2427        check_assist(
2428            add_missing_default_members,
2429            r#"
2430//- /lib.rs crate:b new_source_root:library
2431pub enum State {
2432    Active,
2433    Inactive,
2434}
2435
2436use State::*;
2437
2438pub trait Checker {
2439    fn check(&self) -> State;
2440
2441    fn is_active(&self) -> bool {
2442        match self.check() {
2443            Active => true,
2444            Inactive => false,
2445        }
2446    }
2447}
2448//- /main.rs crate:a deps:b
2449struct MyChecker;
2450
2451impl b::Checker for MyChecker {
2452    fn check(&self) -> b::State {
2453        todo!();
2454    }$0
2455}"#,
2456            r#"
2457struct MyChecker;
2458
2459impl b::Checker for MyChecker {
2460    fn check(&self) -> b::State {
2461        todo!();
2462    }
2463
2464    $0fn is_active(&self) -> bool {
2465        match self.check() {
2466            b::State::Active => true,
2467            b::State::Inactive => false,
2468        }
2469    }
2470}"#,
2471        );
2472    }
2473
2474    #[test]
2475    fn test_parameter_names_matching_macros_not_qualified() {
2476        // Parameter names that match macro names should not be qualified
2477        check_assist(
2478            add_missing_impl_members,
2479            r#"
2480//- /lib.rs crate:dep
2481#[macro_export]
2482macro_rules! my_macro {
2483    () => {}
2484}
2485
2486pub trait Foo {
2487    fn foo(&self, my_macro: usize);
2488}
2489
2490//- /main.rs crate:main deps:dep
2491struct Bar;
2492
2493impl dep::Foo for Bar {$0}
2494"#,
2495            r#"
2496struct Bar;
2497
2498impl dep::Foo for Bar {
2499    fn foo(&self, my_macro: usize) {
2500        ${0:todo!()}
2501    }
2502}
2503"#,
2504        );
2505    }
2506
2507    #[test]
2508    fn regression_test_for_when_impl_for_unit() {
2509        check_assist(
2510            add_missing_impl_members,
2511            r#"
2512trait Test {
2513    fn f<B>()
2514    where
2515        B: IntoIterator,
2516        <B as IntoIterator>::Item: Copy;
2517}
2518impl Test for () {
2519    $0
2520}
2521"#,
2522            r#"
2523trait Test {
2524    fn f<B>()
2525    where
2526        B: IntoIterator,
2527        <B as IntoIterator>::Item: Copy;
2528}
2529impl Test for () {
2530    fn f<B>()
2531    where
2532        B: IntoIterator,
2533        <B as IntoIterator>::Item: Copy {
2534        ${0:todo!()}
2535    }
2536}
2537"#,
2538        );
2539    }
2540}