aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-05-14 12:20:42 +0100
committerGitHub <[email protected]>2020-05-14 12:20:42 +0100
commitf1587ac26332c3378c41d3cc552b270ee6a45cc4 (patch)
treea3a0d688da9315f72cad557af7598779e3937f19 /crates/ra_assists
parent5148d6dc66d80b375a98143dfbb556ec675bbffc (diff)
parentccd526837459724211c8281926aa86522b2506d5 (diff)
Merge #4445
4445: Correctly fill default type parameters r=flodiebold a=montekki Fixes #3877 So, basically even if the parameters are omitted from the `impl` block, check the parameters in `trait` if they have a default type, and if they do go from `hir` to `ast::TypeArg`. I've added a helper for that but I am not sure that it's a proper way to go from `hir` to `ast` here. Co-authored-by: Fedor Sakharov <[email protected]>
Diffstat (limited to 'crates/ra_assists')
-rw-r--r--crates/ra_assists/src/ast_transform.rs24
-rw-r--r--crates/ra_assists/src/handlers/add_missing_impl_members.rs50
2 files changed, 72 insertions, 2 deletions
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs
index 9ac65ab39..3079a02a2 100644
--- a/crates/ra_assists/src/ast_transform.rs
+++ b/crates/ra_assists/src/ast_transform.rs
@@ -1,7 +1,7 @@
1//! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. 1//! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined.
2use rustc_hash::FxHashMap; 2use rustc_hash::FxHashMap;
3 3
4use hir::{PathResolution, SemanticsScope}; 4use hir::{HirDisplay, PathResolution, SemanticsScope};
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_syntax::{ 6use ra_syntax::{
7 algo::SyntaxRewriter, 7 algo::SyntaxRewriter,
@@ -51,7 +51,27 @@ impl<'a> SubstituteTypeParams<'a> {
51 .into_iter() 51 .into_iter()
52 // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky 52 // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky
53 .skip(1) 53 .skip(1)
54 .zip(substs.into_iter()) 54 // The actual list of trait type parameters may be longer than the one
55 // used in the `impl` block due to trailing default type parametrs.
56 // For that case we extend the `substs` with an empty iterator so we
57 // can still hit those trailing values and check if they actually have
58 // a default type. If they do, go for that type from `hir` to `ast` so
59 // the resulting change can be applied correctly.
60 .zip(substs.into_iter().map(Some).chain(std::iter::repeat(None)))
61 .filter_map(|(k, v)| match v {
62 Some(v) => Some((k, v)),
63 None => {
64 let default = k.default(source_scope.db)?;
65 Some((
66 k,
67 ast::make::type_ref(
68 &default
69 .display_source_code(source_scope.db, source_scope.module()?.into())
70 .ok()?,
71 ),
72 ))
73 }
74 })
55 .collect(); 75 .collect();
56 return SubstituteTypeParams { 76 return SubstituteTypeParams {
57 source_scope, 77 source_scope,
diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs
index c1ce87914..22e1156d2 100644
--- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs
@@ -618,4 +618,54 @@ impl Foo for S {
618}"#, 618}"#,
619 ) 619 )
620 } 620 }
621
622 #[test]
623 fn test_generic_single_default_parameter() {
624 check_assist(
625 add_missing_impl_members,
626 r#"
627trait Foo<T = Self> {
628 fn bar(&self, other: &T);
629}
630
631struct S;
632impl Foo for S { <|> }"#,
633 r#"
634trait Foo<T = Self> {
635 fn bar(&self, other: &T);
636}
637
638struct S;
639impl Foo for S {
640 <|>fn bar(&self, other: &Self) {
641 todo!()
642 }
643}"#,
644 )
645 }
646
647 #[test]
648 fn test_generic_default_parameter_is_second() {
649 check_assist(
650 add_missing_impl_members,
651 r#"
652trait Foo<T1, T2 = Self> {
653 fn bar(&self, this: &T1, that: &T2);
654}
655
656struct S<T>;
657impl Foo<T> for S<T> { <|> }"#,
658 r#"
659trait Foo<T1, T2 = Self> {
660 fn bar(&self, this: &T1, that: &T2);
661}
662
663struct S<T>;
664impl Foo<T> for S<T> {
665 <|>fn bar(&self, this: &T, that: &Self) {
666 todo!()
667 }
668}"#,
669 )
670 }
621} 671}