Auto merge of #13622 - jonas-schievink:fix-gat-completions, r=jonas-schievink
fix: include generic parameter in GAT completions Fixes https://github.com/rust-lang/rust-analyzer/issues/13586
This commit is contained in:
commit
a516b90dee
@ -157,7 +157,7 @@ fn complete_trait_impl(
|
|||||||
add_function_impl(acc, ctx, replacement_range, func, hir_impl)
|
add_function_impl(acc, ctx, replacement_range, func, hir_impl)
|
||||||
}
|
}
|
||||||
(hir::AssocItem::TypeAlias(type_alias), All | TypeAlias) => {
|
(hir::AssocItem::TypeAlias(type_alias), All | TypeAlias) => {
|
||||||
add_type_alias_impl(acc, ctx, replacement_range, type_alias)
|
add_type_alias_impl(acc, ctx, replacement_range, type_alias, hir_impl)
|
||||||
}
|
}
|
||||||
(hir::AssocItem::Const(const_), All | Const) => {
|
(hir::AssocItem::Const(const_), All | Const) => {
|
||||||
add_const_impl(acc, ctx, replacement_range, const_, hir_impl)
|
add_const_impl(acc, ctx, replacement_range, const_, hir_impl)
|
||||||
@ -247,25 +247,51 @@ fn add_type_alias_impl(
|
|||||||
ctx: &CompletionContext<'_>,
|
ctx: &CompletionContext<'_>,
|
||||||
replacement_range: TextRange,
|
replacement_range: TextRange,
|
||||||
type_alias: hir::TypeAlias,
|
type_alias: hir::TypeAlias,
|
||||||
|
impl_def: hir::Impl,
|
||||||
) {
|
) {
|
||||||
let alias_name = type_alias.name(ctx.db);
|
let alias_name = type_alias.name(ctx.db).unescaped().to_smol_str();
|
||||||
let (alias_name, escaped_name) =
|
|
||||||
(alias_name.unescaped().to_smol_str(), alias_name.to_smol_str());
|
|
||||||
|
|
||||||
let label = format!("type {} =", alias_name);
|
let label = format!("type {} =", alias_name);
|
||||||
let replacement = format!("type {} = ", escaped_name);
|
|
||||||
|
|
||||||
let mut item = CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label);
|
let mut item = CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label);
|
||||||
item.lookup_by(format!("type {}", alias_name))
|
item.lookup_by(format!("type {}", alias_name))
|
||||||
.set_documentation(type_alias.docs(ctx.db))
|
.set_documentation(type_alias.docs(ctx.db))
|
||||||
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
|
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
|
||||||
|
|
||||||
|
if let Some(source) = ctx.sema.source(type_alias) {
|
||||||
|
let assoc_item = ast::AssocItem::TypeAlias(source.value);
|
||||||
|
if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
|
||||||
|
let transformed_ty = match transformed_item {
|
||||||
|
ast::AssocItem::TypeAlias(ty) => ty,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let start = transformed_ty.syntax().text_range().start();
|
||||||
|
let Some(end) = transformed_ty
|
||||||
|
.eq_token()
|
||||||
|
.map(|tok| tok.text_range().start())
|
||||||
|
.or(transformed_ty.semicolon_token().map(|tok| tok.text_range().start())) else { return };
|
||||||
|
|
||||||
|
let len = end - start;
|
||||||
|
let mut decl = transformed_ty.syntax().text().slice(..len).to_string();
|
||||||
|
if !decl.ends_with(' ') {
|
||||||
|
decl.push(' ');
|
||||||
|
}
|
||||||
|
decl.push_str("= ");
|
||||||
|
|
||||||
match ctx.config.snippet_cap {
|
match ctx.config.snippet_cap {
|
||||||
Some(cap) => item
|
Some(cap) => {
|
||||||
.snippet_edit(cap, TextEdit::replace(replacement_range, format!("{}$0;", replacement))),
|
let snippet = format!("{}$0;", decl);
|
||||||
None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
|
item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet));
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
item.text_edit(TextEdit::replace(replacement_range, decl));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
item.add_to(acc);
|
item.add_to(acc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add_const_impl(
|
fn add_const_impl(
|
||||||
acc: &mut Completions,
|
acc: &mut Completions,
|
||||||
@ -350,9 +376,7 @@ fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
|
|||||||
.map_or(end, |f| f.text_range().start());
|
.map_or(end, |f| f.text_range().start());
|
||||||
|
|
||||||
let len = end - start;
|
let len = end - start;
|
||||||
let range = TextRange::new(0.into(), len);
|
let syntax = node.text().slice(..len).to_string();
|
||||||
|
|
||||||
let syntax = node.text().slice(range).to_string();
|
|
||||||
|
|
||||||
syntax.trim_end().to_owned()
|
syntax.trim_end().to_owned()
|
||||||
}
|
}
|
||||||
@ -1160,6 +1184,31 @@ impl Foo for Test {
|
|||||||
$0
|
$0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn includes_gat_generics() {
|
||||||
|
check_edit(
|
||||||
|
"type Ty",
|
||||||
|
r#"
|
||||||
|
trait Tr<'b> {
|
||||||
|
type Ty<'a: 'b, T: Copy, const C: usize>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Tr<'b> for () {
|
||||||
|
$0
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
trait Tr<'b> {
|
||||||
|
type Ty<'a: 'b, T: Copy, const C: usize>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Tr<'b> for () {
|
||||||
|
type Ty<'a: 'b, T: Copy, const C: usize> = $0;
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user