mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
lifetime transformation: refactoring & a new test
This commit is contained in:
parent
fe8f862757
commit
7f45cccda4
3 changed files with 45 additions and 10 deletions
|
@ -2637,10 +2637,14 @@ impl GenericDef {
|
||||||
Either::Right(x) => GenericParam::TypeParam(x),
|
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());
|
let generics = db.generic_params(self.into());
|
||||||
generics
|
generics
|
||||||
.lifetimes
|
.lifetimes
|
||||||
|
@ -2648,7 +2652,6 @@ impl GenericDef {
|
||||||
.map(|(local_id, _)| LifetimeParam {
|
.map(|(local_id, _)| LifetimeParam {
|
||||||
id: LifetimeParamId { parent: self.into(), local_id },
|
id: LifetimeParamId { parent: self.into(), local_id },
|
||||||
})
|
})
|
||||||
.map(GenericParam::LifetimeParam)
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -833,6 +833,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]
|
#[test]
|
||||||
fn complete_without_name() {
|
fn complete_without_name() {
|
||||||
let test = |completion: &str, hint: &str, completed: &str, next_sibling: &str| {
|
let test = |completion: &str, hint: &str, completed: &str, next_sibling: &str| {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Substs {
|
struct AstSubsts {
|
||||||
types: Vec<ast::TypeArg>,
|
types: Vec<ast::TypeArg>,
|
||||||
lifetimes: Vec<ast::LifetimeArg>,
|
lifetimes: Vec<ast::LifetimeArg>,
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ type LifetimeName = String;
|
||||||
/// ```
|
/// ```
|
||||||
pub struct PathTransform<'a> {
|
pub struct PathTransform<'a> {
|
||||||
generic_def: Option<hir::GenericDef>,
|
generic_def: Option<hir::GenericDef>,
|
||||||
substs: Substs,
|
substs: AstSubsts,
|
||||||
target_scope: &'a SemanticsScope<'a>,
|
target_scope: &'a SemanticsScope<'a>,
|
||||||
source_scope: &'a SemanticsScope<'a>,
|
source_scope: &'a SemanticsScope<'a>,
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,12 @@ impl<'a> PathTransform<'a> {
|
||||||
target_scope: &'a SemanticsScope<'a>,
|
target_scope: &'a SemanticsScope<'a>,
|
||||||
source_scope: &'a SemanticsScope<'a>,
|
source_scope: &'a SemanticsScope<'a>,
|
||||||
) -> PathTransform<'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) {
|
pub fn apply(&self, syntax: &SyntaxNode) {
|
||||||
|
@ -134,7 +139,7 @@ impl<'a> PathTransform<'a> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|it| it.lifetime_params(db))
|
.flat_map(|it| it.lifetime_params(db))
|
||||||
.zip(self.substs.lifetimes.clone())
|
.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();
|
.collect();
|
||||||
Ctx { type_substs, lifetime_substs, target_module, source_scope: self.source_scope }
|
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
|
// 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).
|
// 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 target_trait = impl_def.trait_()?;
|
||||||
let path_type = match target_trait {
|
let path_type = match target_trait {
|
||||||
ast::Type::PathType(path) => path,
|
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)
|
get_type_args_from_arg_list(generic_arg_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_args_from_arg_list(generic_arg_list: ast::GenericArgList) -> Option<Substs> {
|
fn get_type_args_from_arg_list(generic_arg_list: ast::GenericArgList) -> Option<AstSubsts> {
|
||||||
let mut result = Substs::default();
|
let mut result = AstSubsts::default();
|
||||||
generic_arg_list.generic_args().for_each(|generic_arg| match generic_arg {
|
generic_arg_list.generic_args().for_each(|generic_arg| match generic_arg {
|
||||||
ast::GenericArg::TypeArg(type_arg) => result.types.push(type_arg),
|
ast::GenericArg::TypeArg(type_arg) => result.types.push(type_arg),
|
||||||
ast::GenericArg::LifetimeArg(l_arg) => result.lifetimes.push(l_arg),
|
ast::GenericArg::LifetimeArg(l_arg) => result.lifetimes.push(l_arg),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue