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
17pub(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
59pub(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 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 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 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 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 #[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 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 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 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}