Skip to content

Commit

Permalink
Merge #9223
Browse files Browse the repository at this point in the history
9223: Complete associated types in dyn and impl trait r=Veykril a=Veykril

Fixes #9222
bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
  • Loading branch information
bors[bot] and Veykril committed Jun 11, 2021
2 parents 187d55a + ec9ef9c commit 72ea028
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 10 deletions.
10 changes: 9 additions & 1 deletion crates/ide_completion/src/completions.rs
Expand Up @@ -29,7 +29,7 @@ use crate::{
macro_::render_macro,
pattern::{render_struct_pat, render_variant_pat},
render_field, render_resolution, render_tuple_field,
type_alias::render_type_alias,
type_alias::{render_type_alias, render_type_alias_with_eq},
RenderContext,
},
CompletionContext, CompletionItem, CompletionItemKind,
Expand Down Expand Up @@ -188,6 +188,14 @@ impl Completions {
self.add_opt(render_type_alias(RenderContext::new(ctx), type_alias));
}

pub(crate) fn add_type_alias_with_eq(
&mut self,
ctx: &CompletionContext,
type_alias: hir::TypeAlias,
) {
self.add_opt(render_type_alias_with_eq(RenderContext::new(ctx), type_alias));
}

pub(crate) fn add_qualified_enum_variant(
&mut self,
ctx: &CompletionContext,
Expand Down
34 changes: 33 additions & 1 deletion crates/ide_completion/src/completions/unqualified_path.rs
@@ -1,8 +1,9 @@
//! Completion of names from the current scope, e.g. locals and imported items.

use hir::ScopeDef;
use syntax::{ast, AstNode};

use crate::{CompletionContext, Completions};
use crate::{patterns::ImmediateLocation, CompletionContext, Completions};

pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
if ctx.is_path_disallowed() || !ctx.is_trivial_path() {
Expand Down Expand Up @@ -43,6 +44,20 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
});
}

if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast) {
if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
ctx.sema.resolve_path(&path_seg.parent_path())
{
trait_.items(ctx.sema.db).into_iter().for_each(|it| {
if let hir::AssocItem::TypeAlias(alias) = it {
acc.add_type_alias_with_eq(ctx, alias)
}
});
}
}
}

ctx.scope.process_all_names(&mut |name, res| {
if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
cov_mark::hit!(skip_lifetime_completion);
Expand Down Expand Up @@ -777,4 +792,21 @@ $0
"#]],
)
}

#[test]
fn completes_assoc_types_in_dynimpl_trait() {
check(
r#"
trait Foo {
type Bar;
}
fn foo(_: impl Foo<B$0>) {}
"#,
expect![[r#"
ta Bar = type Bar;
tt Foo
"#]],
);
}
}
7 changes: 6 additions & 1 deletion crates/ide_completion/src/patterns.rs
Expand Up @@ -47,6 +47,9 @@ pub(crate) enum ImmediateLocation {
receiver_is_ambiguous_float_literal: bool,
},
// Original file ast node
// Only set from a type arg
GenericArgList(ast::GenericArgList),
// Original file ast node
/// The record expr of the field name we are completing
RecordExpr(ast::RecordExpr),
// Original file ast node
Expand Down Expand Up @@ -159,7 +162,6 @@ pub(crate) fn determine_location(
}
}
};

let res = match_ast! {
match parent {
ast::IdentPat(_it) => ImmediateLocation::IdentPat,
Expand All @@ -174,6 +176,9 @@ pub(crate) fn determine_location(
Some(TRAIT) => ImmediateLocation::Trait,
_ => return None,
},
ast::GenericArgList(_it) => sema
.find_node_at_offset_with_macros(original_file, offset)
.map(ImmediateLocation::GenericArgList)?,
ast::Module(it) => {
if it.item_list().is_none() {
ImmediateLocation::ModDeclaration(it)
Expand Down
23 changes: 16 additions & 7 deletions crates/ide_completion/src/render/type_alias.rs
Expand Up @@ -16,7 +16,14 @@ pub(crate) fn render_type_alias<'a>(
ctx: RenderContext<'a>,
type_alias: hir::TypeAlias,
) -> Option<CompletionItem> {
TypeAliasRender::new(ctx, type_alias)?.render()
TypeAliasRender::new(ctx, type_alias)?.render(false)
}

pub(crate) fn render_type_alias_with_eq<'a>(
ctx: RenderContext<'a>,
type_alias: hir::TypeAlias,
) -> Option<CompletionItem> {
TypeAliasRender::new(ctx, type_alias)?.render(true)
}

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

fn render(self) -> Option<CompletionItem> {
let name = self.name()?;
fn render(self, with_eq: bool) -> Option<CompletionItem> {
let name = self.ast_node.name().map(|name| {
if with_eq {
format!("{} = ", name.text())
} else {
name.text().to_string()
}
})?;
let detail = self.detail();

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

fn name(&self) -> Option<String> {
self.ast_node.name().map(|name| name.text().to_string())
}

fn detail(&self) -> String {
type_label(&self.ast_node)
}
Expand Down

0 comments on commit 72ea028

Please sign in to comment.