Merge #11879
11879: Suggest infered type in auto complete r=HKalbasi a=HKalbasi fix #11855 It doesn't work for return types and consts (so their tests are failing) because I can't find their body node in the original file. (Are these original and fake file documented somewhere?) Also it currently needs to type first character of the type (or manual ctrl+space) to open the auto complete panel, is it possible to open it automatically on typing `:` and `->`? Co-authored-by: hkalbasi <hamidrezakalbasi@protonmail.com>
This commit is contained in:
commit
4204e35563
@ -302,9 +302,13 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>>
|
|||||||
let end_param = self.next_param_idx();
|
let end_param = self.next_param_idx();
|
||||||
let params = IdxRange::new(start_param..end_param);
|
let params = IdxRange::new(start_param..end_param);
|
||||||
|
|
||||||
let ret_type = match func.ret_type().and_then(|rt| rt.ty()) {
|
let ret_type = match func.ret_type() {
|
||||||
|
Some(rt) => match rt.ty() {
|
||||||
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
|
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
|
||||||
_ => TypeRef::unit(),
|
None if rt.thin_arrow_token().is_some() => TypeRef::Error,
|
||||||
|
None => TypeRef::unit(),
|
||||||
|
},
|
||||||
|
None => TypeRef::unit(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (ret_type, async_ret_type) = if func.async_token().is_some() {
|
let (ret_type, async_ret_type) = if func.async_token().is_some() {
|
||||||
|
@ -21,12 +21,13 @@
|
|||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use hir::{db::HirDatabase, known, ScopeDef};
|
use hir::{db::HirDatabase, known, HirDisplay, ScopeDef};
|
||||||
use ide_db::SymbolKind;
|
use ide_db::SymbolKind;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Visible,
|
context::Visible,
|
||||||
item::Builder,
|
item::Builder,
|
||||||
|
patterns::{ImmediateLocation, TypeAnnotation},
|
||||||
render::{
|
render::{
|
||||||
const_::render_const,
|
const_::render_const,
|
||||||
function::{render_fn, render_method},
|
function::{render_fn, render_method},
|
||||||
@ -34,6 +35,7 @@
|
|||||||
macro_::render_macro,
|
macro_::render_macro,
|
||||||
pattern::{render_struct_pat, render_variant_pat},
|
pattern::{render_struct_pat, render_variant_pat},
|
||||||
render_field, render_resolution, render_resolution_simple, render_tuple_field,
|
render_field, render_resolution, render_resolution_simple, render_tuple_field,
|
||||||
|
render_type_inference,
|
||||||
type_alias::{render_type_alias, render_type_alias_with_eq},
|
type_alias::{render_type_alias, render_type_alias_with_eq},
|
||||||
union_literal::render_union_literal,
|
union_literal::render_union_literal,
|
||||||
RenderContext,
|
RenderContext,
|
||||||
@ -374,3 +376,19 @@ fn enum_variants_with_paths(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn inferred_type(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
||||||
|
use TypeAnnotation::*;
|
||||||
|
let pat = match &ctx.completion_location {
|
||||||
|
Some(ImmediateLocation::TypeAnnotation(t)) => t,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
let x = match pat {
|
||||||
|
Let(pat) | FnParam(pat) => ctx.sema.type_of_pat(pat.as_ref()?),
|
||||||
|
Const(exp) | RetType(exp) => ctx.sema.type_of_expr(exp.as_ref()?),
|
||||||
|
}?
|
||||||
|
.adjusted();
|
||||||
|
let ty_string = x.display_source_code(ctx.db, ctx.module.into()).ok()?;
|
||||||
|
acc.add(render_type_inference(ty_string, ctx));
|
||||||
|
None
|
||||||
|
}
|
||||||
|
@ -138,6 +138,8 @@ pub struct CompletionRelevance {
|
|||||||
pub is_private_editable: bool,
|
pub is_private_editable: bool,
|
||||||
/// Set for postfix snippet item completions
|
/// Set for postfix snippet item completions
|
||||||
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
|
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
|
||||||
|
/// This is setted for type inference results
|
||||||
|
pub is_definite: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
@ -198,6 +200,7 @@ pub fn score(self) -> u32 {
|
|||||||
is_op_method,
|
is_op_method,
|
||||||
is_private_editable,
|
is_private_editable,
|
||||||
postfix_match,
|
postfix_match,
|
||||||
|
is_definite,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
// lower rank private things
|
// lower rank private things
|
||||||
@ -225,7 +228,9 @@ pub fn score(self) -> u32 {
|
|||||||
if is_local {
|
if is_local {
|
||||||
score += 1;
|
score += 1;
|
||||||
}
|
}
|
||||||
|
if is_definite {
|
||||||
|
score += 10;
|
||||||
|
}
|
||||||
score
|
score
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +248,7 @@ pub enum CompletionItemKind {
|
|||||||
SymbolKind(SymbolKind),
|
SymbolKind(SymbolKind),
|
||||||
Binding,
|
Binding,
|
||||||
BuiltinType,
|
BuiltinType,
|
||||||
|
InferredType,
|
||||||
Keyword,
|
Keyword,
|
||||||
Method,
|
Method,
|
||||||
Snippet,
|
Snippet,
|
||||||
@ -284,6 +290,7 @@ pub(crate) fn tag(&self) -> &'static str {
|
|||||||
},
|
},
|
||||||
CompletionItemKind::Binding => "bn",
|
CompletionItemKind::Binding => "bn",
|
||||||
CompletionItemKind::BuiltinType => "bt",
|
CompletionItemKind::BuiltinType => "bt",
|
||||||
|
CompletionItemKind::InferredType => "it",
|
||||||
CompletionItemKind::Keyword => "kw",
|
CompletionItemKind::Keyword => "kw",
|
||||||
CompletionItemKind::Method => "me",
|
CompletionItemKind::Method => "me",
|
||||||
CompletionItemKind::Snippet => "sn",
|
CompletionItemKind::Snippet => "sn",
|
||||||
|
@ -155,6 +155,7 @@ pub fn completions(
|
|||||||
completions::flyimport::import_on_the_fly(&mut acc, &ctx);
|
completions::flyimport::import_on_the_fly(&mut acc, &ctx);
|
||||||
completions::fn_param::complete_fn_param(&mut acc, &ctx);
|
completions::fn_param::complete_fn_param(&mut acc, &ctx);
|
||||||
completions::format_string::format_string(&mut acc, &ctx);
|
completions::format_string::format_string(&mut acc, &ctx);
|
||||||
|
completions::inferred_type(&mut acc, &ctx);
|
||||||
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
|
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
|
||||||
completions::lifetime::complete_label(&mut acc, &ctx);
|
completions::lifetime::complete_label(&mut acc, &ctx);
|
||||||
completions::lifetime::complete_lifetime(&mut acc, &ctx);
|
completions::lifetime::complete_lifetime(&mut acc, &ctx);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
use ide_db::RootDatabase;
|
use ide_db::RootDatabase;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo::non_trivia_sibling,
|
algo::non_trivia_sibling,
|
||||||
ast::{self, HasArgList, HasLoopBody},
|
ast::{self, HasArgList, HasLoopBody, HasName},
|
||||||
match_ast, AstNode, Direction, SyntaxElement,
|
match_ast, AstNode, Direction, SyntaxElement,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
SyntaxNode, SyntaxToken, TextRange, TextSize,
|
SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||||
@ -27,6 +27,14 @@ pub(crate) enum ImmediatePrevSibling {
|
|||||||
Attribute,
|
Attribute,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub(crate) enum TypeAnnotation {
|
||||||
|
Let(Option<ast::Pat>),
|
||||||
|
FnParam(Option<ast::Pat>),
|
||||||
|
RetType(Option<ast::Expr>),
|
||||||
|
Const(Option<ast::Expr>),
|
||||||
|
}
|
||||||
|
|
||||||
/// Direct parent "thing" of what we are currently completing.
|
/// Direct parent "thing" of what we are currently completing.
|
||||||
///
|
///
|
||||||
/// This may contain nodes of the fake file as well as the original, comments on the variants specify
|
/// This may contain nodes of the fake file as well as the original, comments on the variants specify
|
||||||
@ -44,6 +52,8 @@ pub(crate) enum ImmediateLocation {
|
|||||||
ItemList,
|
ItemList,
|
||||||
TypeBound,
|
TypeBound,
|
||||||
Variant,
|
Variant,
|
||||||
|
/// Original file ast node
|
||||||
|
TypeAnnotation(TypeAnnotation),
|
||||||
/// Fake file ast node
|
/// Fake file ast node
|
||||||
ModDeclaration(ast::Module),
|
ModDeclaration(ast::Module),
|
||||||
/// Original file ast node
|
/// Original file ast node
|
||||||
@ -235,10 +245,7 @@ pub(crate) fn determine_location(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::FieldExpr(it) => {
|
ast::FieldExpr(it) => {
|
||||||
let receiver = it
|
let receiver = find_in_original_file(it.expr(), original_file);
|
||||||
.expr()
|
|
||||||
.map(|e| e.syntax().text_range())
|
|
||||||
.and_then(|r| find_node_with_range(original_file, r));
|
|
||||||
let receiver_is_ambiguous_float_literal = if let Some(ast::Expr::Literal(l)) = &receiver {
|
let receiver_is_ambiguous_float_literal = if let Some(ast::Expr::Literal(l)) = &receiver {
|
||||||
match l.kind() {
|
match l.kind() {
|
||||||
ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'),
|
ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'),
|
||||||
@ -253,15 +260,65 @@ pub(crate) fn determine_location(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::MethodCallExpr(it) => ImmediateLocation::MethodCall {
|
ast::MethodCallExpr(it) => ImmediateLocation::MethodCall {
|
||||||
receiver: it
|
receiver: find_in_original_file(it.receiver(), original_file),
|
||||||
.receiver()
|
|
||||||
.map(|e| e.syntax().text_range())
|
|
||||||
.and_then(|r| find_node_with_range(original_file, r)),
|
|
||||||
has_parens: it.arg_list().map_or(false, |it| it.l_paren_token().is_some())
|
has_parens: it.arg_list().map_or(false, |it| it.l_paren_token().is_some())
|
||||||
},
|
},
|
||||||
|
ast::Const(it) => {
|
||||||
|
if !it.ty().map_or(false, |x| x.syntax().text_range().contains(offset)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let name = find_in_original_file(it.name(), original_file)?;
|
||||||
|
let original = ast::Const::cast(name.syntax().parent()?)?;
|
||||||
|
ImmediateLocation::TypeAnnotation(TypeAnnotation::Const(original.body()))
|
||||||
|
},
|
||||||
|
ast::RetType(it) => {
|
||||||
|
if it.thin_arrow_token().is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if !it.ty().map_or(false, |x| x.syntax().text_range().contains(offset)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let parent = match ast::Fn::cast(parent.parent()?) {
|
||||||
|
Some(x) => x.param_list(),
|
||||||
|
None => ast::ClosureExpr::cast(parent.parent()?)?.param_list(),
|
||||||
|
};
|
||||||
|
let parent = find_in_original_file(parent, original_file)?.syntax().parent()?;
|
||||||
|
ImmediateLocation::TypeAnnotation(TypeAnnotation::RetType(match_ast! {
|
||||||
|
match parent {
|
||||||
|
ast::ClosureExpr(it) => {
|
||||||
|
it.body()
|
||||||
|
},
|
||||||
|
ast::Fn(it) => {
|
||||||
|
it.body().map(ast::Expr::BlockExpr)
|
||||||
|
},
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
ast::Param(it) => {
|
||||||
|
if it.colon_token().is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if !it.ty().map_or(false, |x| x.syntax().text_range().contains(offset)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
ImmediateLocation::TypeAnnotation(TypeAnnotation::FnParam(find_in_original_file(it.pat(), original_file)))
|
||||||
|
},
|
||||||
|
ast::LetStmt(it) => {
|
||||||
|
if it.colon_token().is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if !it.ty().map_or(false, |x| x.syntax().text_range().contains(offset)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
ImmediateLocation::TypeAnnotation(TypeAnnotation::Let(find_in_original_file(it.pat(), original_file)))
|
||||||
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
fn find_in_original_file<N: AstNode>(x: Option<N>, original_file: &SyntaxNode) -> Option<N> {
|
||||||
|
x.map(|e| e.syntax().text_range()).and_then(|r| find_node_with_range(original_file, r))
|
||||||
|
}
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +170,13 @@ pub(crate) fn render_resolution_with_import(
|
|||||||
Some(render_resolution_(ctx, local_name, Some(import_edit), resolution))
|
Some(render_resolution_(ctx, local_name, Some(import_edit), resolution))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn render_type_inference(ty_string: String, ctx: &CompletionContext) -> CompletionItem {
|
||||||
|
let mut builder =
|
||||||
|
CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string);
|
||||||
|
builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() });
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
fn render_resolution_(
|
fn render_resolution_(
|
||||||
ctx: RenderContext<'_>,
|
ctx: RenderContext<'_>,
|
||||||
local_name: hir::Name,
|
local_name: hir::Name,
|
||||||
@ -620,6 +627,7 @@ fn main() { let _: m::Spam = S$0 }
|
|||||||
is_op_method: false,
|
is_op_method: false,
|
||||||
is_private_editable: false,
|
is_private_editable: false,
|
||||||
postfix_match: None,
|
postfix_match: None,
|
||||||
|
is_definite: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CompletionItem {
|
CompletionItem {
|
||||||
@ -641,6 +649,7 @@ fn main() { let _: m::Spam = S$0 }
|
|||||||
is_op_method: false,
|
is_op_method: false,
|
||||||
is_private_editable: false,
|
is_private_editable: false,
|
||||||
postfix_match: None,
|
postfix_match: None,
|
||||||
|
is_definite: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -728,6 +737,7 @@ fn foo() { A { the$0 } }
|
|||||||
is_op_method: false,
|
is_op_method: false,
|
||||||
is_private_editable: false,
|
is_private_editable: false,
|
||||||
postfix_match: None,
|
postfix_match: None,
|
||||||
|
is_definite: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -89,6 +89,206 @@ fn x<'lt, T, const C: usize>() -> $0
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_const() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<T>(T);
|
||||||
|
const FOO: $0 = Foo(2);
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it Foo<i32>
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Foo<…>
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_closure_param() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn f1(f: fn(i32) -> i32) {}
|
||||||
|
fn f2() {
|
||||||
|
f1(|x: $0);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it i32
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_closure_return() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn f1(f: fn(u64) -> u64) {}
|
||||||
|
fn f2() {
|
||||||
|
f1(|x| -> $0 {
|
||||||
|
x + 5
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it u64
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_fn_return() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn f2(x: u64) -> $0 {
|
||||||
|
x + 5
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it u64
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_fn_param() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn f1(x: i32) {}
|
||||||
|
fn f2(x: $0) {
|
||||||
|
f1(x);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it i32
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_not_in_the_scope() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
mod a {
|
||||||
|
pub struct Foo<T>(T);
|
||||||
|
pub fn x() -> Foo<Foo<i32>> {
|
||||||
|
Foo(Foo(2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn foo<'lt, T, const C: usize>() {
|
||||||
|
let local = ();
|
||||||
|
let foo: $0 = a::x();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it a::Foo<a::Foo<i32>>
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tp T
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
md a
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inferred_type_let() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<T>(T);
|
||||||
|
fn foo<'lt, T, const C: usize>() {
|
||||||
|
let local = ();
|
||||||
|
let foo: $0 = Foo(2);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
it Foo<i32>
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
|
tp T
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Foo<…>
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) macro_rules! makro
|
||||||
|
un Union
|
||||||
|
bt u32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn body_type_pos() {
|
fn body_type_pos() {
|
||||||
check(
|
check(
|
||||||
|
@ -107,6 +107,7 @@ pub(crate) fn completion_item_kind(
|
|||||||
match completion_item_kind {
|
match completion_item_kind {
|
||||||
CompletionItemKind::Binding => lsp_types::CompletionItemKind::VARIABLE,
|
CompletionItemKind::Binding => lsp_types::CompletionItemKind::VARIABLE,
|
||||||
CompletionItemKind::BuiltinType => lsp_types::CompletionItemKind::STRUCT,
|
CompletionItemKind::BuiltinType => lsp_types::CompletionItemKind::STRUCT,
|
||||||
|
CompletionItemKind::InferredType => lsp_types::CompletionItemKind::SNIPPET,
|
||||||
CompletionItemKind::Keyword => lsp_types::CompletionItemKind::KEYWORD,
|
CompletionItemKind::Keyword => lsp_types::CompletionItemKind::KEYWORD,
|
||||||
CompletionItemKind::Method => lsp_types::CompletionItemKind::METHOD,
|
CompletionItemKind::Method => lsp_types::CompletionItemKind::METHOD,
|
||||||
CompletionItemKind::Snippet => lsp_types::CompletionItemKind::SNIPPET,
|
CompletionItemKind::Snippet => lsp_types::CompletionItemKind::SNIPPET,
|
||||||
|
Loading…
Reference in New Issue
Block a user