Skip to main content

ide_assists/handlers/
add_missing_impl_members.rs

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