about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/lib.rs9
-rw-r--r--crates/ide-completion/src/completions/item_list/trait_impl.rs27
-rw-r--r--crates/ide-db/src/path_transform.rs19
3 files changed, 45 insertions, 10 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 1fc18767d6c..604b1cb5228 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2637,10 +2637,14 @@ impl GenericDef {
                 Either::Right(x) => GenericParam::TypeParam(x),
             }
         });
-        self.lifetime_params(db).into_iter().chain(ty_params).collect()
+        self.lifetime_params(db)
+            .into_iter()
+            .map(GenericParam::LifetimeParam)
+            .chain(ty_params)
+            .collect()
     }
 
-    pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
+    pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec<LifetimeParam> {
         let generics = db.generic_params(self.into());
         generics
             .lifetimes
@@ -2648,7 +2652,6 @@ impl GenericDef {
             .map(|(local_id, _)| LifetimeParam {
                 id: LifetimeParamId { parent: self.into(), local_id },
             })
-            .map(GenericParam::LifetimeParam)
             .collect()
     }
 
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs
index 7de1bf2dc13..664aa7b8397 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -834,6 +834,33 @@ impl Test for () {
     }
 
     #[test]
+    fn fn_with_lifetimes() {
+        check_edit(
+            "fn foo",
+            r#"
+trait Test<'a, 'b, T> {
+    fn foo(&self, a: &'a T, b: &'b T) -> &'a T;
+}
+
+impl<'x, 'y, A> Test<'x, 'y, A> for () {
+    t$0
+}
+"#,
+            r#"
+trait Test<'a, 'b, T> {
+    fn foo(&self, a: &'a T, b: &'b T) -> &'a T;
+}
+
+impl<'x, 'y, A> Test<'x, 'y, A> for () {
+    fn foo(&self, a: &'x A, b: &'y A) -> &'x A {
+    $0
+}
+}
+"#,
+        );
+    }
+
+    #[test]
     fn complete_without_name() {
         let test = |completion: &str, hint: &str, completed: &str, next_sibling: &str| {
             check_edit(
diff --git a/crates/ide-db/src/path_transform.rs b/crates/ide-db/src/path_transform.rs
index fe8ffc4354a..6afd61e84dc 100644
--- a/crates/ide-db/src/path_transform.rs
+++ b/crates/ide-db/src/path_transform.rs
@@ -10,7 +10,7 @@ use syntax::{
 };
 
 #[derive(Default)]
-struct Substs {
+struct AstSubsts {
     types: Vec<ast::TypeArg>,
     lifetimes: Vec<ast::LifetimeArg>,
 }
@@ -42,7 +42,7 @@ type LifetimeName = String;
 /// ```
 pub struct PathTransform<'a> {
     generic_def: Option<hir::GenericDef>,
-    substs: Substs,
+    substs: AstSubsts,
     target_scope: &'a SemanticsScope<'a>,
     source_scope: &'a SemanticsScope<'a>,
 }
@@ -80,7 +80,12 @@ impl<'a> PathTransform<'a> {
         target_scope: &'a SemanticsScope<'a>,
         source_scope: &'a SemanticsScope<'a>,
     ) -> PathTransform<'a> {
-        PathTransform { source_scope, target_scope, generic_def: None, substs: Substs::default() }
+        PathTransform {
+            source_scope,
+            target_scope,
+            generic_def: None,
+            substs: AstSubsts::default(),
+        }
     }
 
     pub fn apply(&self, syntax: &SyntaxNode) {
@@ -134,7 +139,7 @@ impl<'a> PathTransform<'a> {
             .into_iter()
             .flat_map(|it| it.lifetime_params(db))
             .zip(self.substs.lifetimes.clone())
-            .filter_map(|(k, v)| Some((k.name(db).to_string(), v.lifetime()?)))
+            .filter_map(|(k, v)| Some((k.name(db).display(db.upcast()).to_string(), v.lifetime()?)))
             .collect();
         Ctx { type_substs, lifetime_substs, target_module, source_scope: self.source_scope }
     }
@@ -279,7 +284,7 @@ impl<'a> Ctx<'a> {
 
 // FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
 // trait ref, and then go from the types in the substs back to the syntax).
-fn get_syntactic_substs(impl_def: ast::Impl) -> Option<Substs> {
+fn get_syntactic_substs(impl_def: ast::Impl) -> Option<AstSubsts> {
     let target_trait = impl_def.trait_()?;
     let path_type = match target_trait {
         ast::Type::PathType(path) => path,
@@ -290,8 +295,8 @@ fn get_syntactic_substs(impl_def: ast::Impl) -> Option<Substs> {
     get_type_args_from_arg_list(generic_arg_list)
 }
 
-fn get_type_args_from_arg_list(generic_arg_list: ast::GenericArgList) -> Option<Substs> {
-    let mut result = Substs::default();
+fn get_type_args_from_arg_list(generic_arg_list: ast::GenericArgList) -> Option<AstSubsts> {
+    let mut result = AstSubsts::default();
     generic_arg_list.generic_args().for_each(|generic_arg| match generic_arg {
         ast::GenericArg::TypeArg(type_arg) => result.types.push(type_arg),
         ast::GenericArg::LifetimeArg(l_arg) => result.lifetimes.push(l_arg),