Skip to content

Commit 72ea028

Browse files
bors[bot]Veykril
andauthored
9223: Complete associated types in dyn and impl trait r=Veykril a=Veykril Fixes rust-lang#9222 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 187d55a + ec9ef9c commit 72ea028

File tree

4 files changed

+64
-10
lines changed

4 files changed

+64
-10
lines changed

crates/ide_completion/src/completions.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::{
2929
macro_::render_macro,
3030
pattern::{render_struct_pat, render_variant_pat},
3131
render_field, render_resolution, render_tuple_field,
32-
type_alias::render_type_alias,
32+
type_alias::{render_type_alias, render_type_alias_with_eq},
3333
RenderContext,
3434
},
3535
CompletionContext, CompletionItem, CompletionItemKind,
@@ -188,6 +188,14 @@ impl Completions {
188188
self.add_opt(render_type_alias(RenderContext::new(ctx), type_alias));
189189
}
190190

191+
pub(crate) fn add_type_alias_with_eq(
192+
&mut self,
193+
ctx: &CompletionContext,
194+
type_alias: hir::TypeAlias,
195+
) {
196+
self.add_opt(render_type_alias_with_eq(RenderContext::new(ctx), type_alias));
197+
}
198+
191199
pub(crate) fn add_qualified_enum_variant(
192200
&mut self,
193201
ctx: &CompletionContext,

crates/ide_completion/src/completions/unqualified_path.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
//! Completion of names from the current scope, e.g. locals and imported items.
22
33
use hir::ScopeDef;
4+
use syntax::{ast, AstNode};
45

5-
use crate::{CompletionContext, Completions};
6+
use crate::{patterns::ImmediateLocation, CompletionContext, Completions};
67

78
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
89
if ctx.is_path_disallowed() || !ctx.is_trivial_path() {
@@ -43,6 +44,20 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
4344
});
4445
}
4546

47+
if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
48+
if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast) {
49+
if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
50+
ctx.sema.resolve_path(&path_seg.parent_path())
51+
{
52+
trait_.items(ctx.sema.db).into_iter().for_each(|it| {
53+
if let hir::AssocItem::TypeAlias(alias) = it {
54+
acc.add_type_alias_with_eq(ctx, alias)
55+
}
56+
});
57+
}
58+
}
59+
}
60+
4661
ctx.scope.process_all_names(&mut |name, res| {
4762
if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
4863
cov_mark::hit!(skip_lifetime_completion);
@@ -777,4 +792,21 @@ $0
777792
"#]],
778793
)
779794
}
795+
796+
#[test]
797+
fn completes_assoc_types_in_dynimpl_trait() {
798+
check(
799+
r#"
800+
trait Foo {
801+
type Bar;
802+
}
803+
804+
fn foo(_: impl Foo<B$0>) {}
805+
"#,
806+
expect![[r#"
807+
ta Bar = type Bar;
808+
tt Foo
809+
"#]],
810+
);
811+
}
780812
}

crates/ide_completion/src/patterns.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ pub(crate) enum ImmediateLocation {
4747
receiver_is_ambiguous_float_literal: bool,
4848
},
4949
// Original file ast node
50+
// Only set from a type arg
51+
GenericArgList(ast::GenericArgList),
52+
// Original file ast node
5053
/// The record expr of the field name we are completing
5154
RecordExpr(ast::RecordExpr),
5255
// Original file ast node
@@ -159,7 +162,6 @@ pub(crate) fn determine_location(
159162
}
160163
}
161164
};
162-
163165
let res = match_ast! {
164166
match parent {
165167
ast::IdentPat(_it) => ImmediateLocation::IdentPat,
@@ -174,6 +176,9 @@ pub(crate) fn determine_location(
174176
Some(TRAIT) => ImmediateLocation::Trait,
175177
_ => return None,
176178
},
179+
ast::GenericArgList(_it) => sema
180+
.find_node_at_offset_with_macros(original_file, offset)
181+
.map(ImmediateLocation::GenericArgList)?,
177182
ast::Module(it) => {
178183
if it.item_list().is_none() {
179184
ImmediateLocation::ModDeclaration(it)

crates/ide_completion/src/render/type_alias.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ pub(crate) fn render_type_alias<'a>(
1616
ctx: RenderContext<'a>,
1717
type_alias: hir::TypeAlias,
1818
) -> Option<CompletionItem> {
19-
TypeAliasRender::new(ctx, type_alias)?.render()
19+
TypeAliasRender::new(ctx, type_alias)?.render(false)
20+
}
21+
22+
pub(crate) fn render_type_alias_with_eq<'a>(
23+
ctx: RenderContext<'a>,
24+
type_alias: hir::TypeAlias,
25+
) -> Option<CompletionItem> {
26+
TypeAliasRender::new(ctx, type_alias)?.render(true)
2027
}
2128

2229
#[derive(Debug)]
@@ -32,8 +39,14 @@ impl<'a> TypeAliasRender<'a> {
3239
Some(TypeAliasRender { ctx, type_alias, ast_node })
3340
}
3441

35-
fn render(self) -> Option<CompletionItem> {
36-
let name = self.name()?;
42+
fn render(self, with_eq: bool) -> Option<CompletionItem> {
43+
let name = self.ast_node.name().map(|name| {
44+
if with_eq {
45+
format!("{} = ", name.text())
46+
} else {
47+
name.text().to_string()
48+
}
49+
})?;
3750
let detail = self.detail();
3851

3952
let mut item =
@@ -49,10 +62,6 @@ impl<'a> TypeAliasRender<'a> {
4962
Some(item.build())
5063
}
5164

52-
fn name(&self) -> Option<String> {
53-
self.ast_node.name().map(|name| name.text().to_string())
54-
}
55-
5665
fn detail(&self) -> String {
5766
type_label(&self.ast_node)
5867
}

0 commit comments

Comments
 (0)