Merge #9223
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>
This commit is contained in:
commit
72ea02869b
@ -29,7 +29,7 @@
|
||||
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,
|
||||
@ -188,6 +188,14 @@ pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir
|
||||
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,
|
||||
|
@ -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() {
|
||||
@ -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);
|
||||
@ -777,4 +792,21 @@ mod bar {}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[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
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -159,7 +162,6 @@ pub(crate) fn determine_location(
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let res = match_ast! {
|
||||
match parent {
|
||||
ast::IdentPat(_it) => ImmediateLocation::IdentPat,
|
||||
@ -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)
|
||||
|
@ -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)]
|
||||
@ -32,8 +39,14 @@ fn new(ctx: RenderContext<'a>, type_alias: hir::TypeAlias) -> Option<TypeAliasRe
|
||||
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 =
|
||||
@ -49,10 +62,6 @@ fn render(self) -> Option<CompletionItem> {
|
||||
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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user