Skip to content

Commit 8349d32

Browse files
committed
Refactor completion relevance constructor type enum
1 parent 17c6f3d commit 8349d32

File tree

3 files changed

+158
-20
lines changed

3 files changed

+158
-20
lines changed

crates/ide-completion/src/item.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ pub struct CompletionRelevance {
165165
/// This is set for type inference results
166166
pub is_definite: bool,
167167
/// This is set for items that are constructors for the type of the impl/trait
168-
pub constructor_type: Option<CompletionRelevanceConstructorType>,
168+
pub associated_fn_type: Option<CompletionRelevanceAssociatedFnType>,
169169
}
170170

171171
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -208,7 +208,9 @@ pub enum CompletionRelevancePostfixMatch {
208208
}
209209

210210
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
211-
pub enum CompletionRelevanceConstructorType {
211+
pub enum CompletionRelevanceAssociatedFnType {
212+
/// Returns a type that is expected in this context
213+
ReturnsExpectedType,
212214
/// Returns the Self type of the impl/trait
213215
DirectConstructor,
214216
DirectConstructorWithArgs,
@@ -241,7 +243,7 @@ impl CompletionRelevance {
241243
is_private_editable,
242244
postfix_match,
243245
is_definite,
244-
constructor_type,
246+
associated_fn_type: constructor_type,
245247
} = self;
246248

247249
// lower rank private things
@@ -285,10 +287,11 @@ impl CompletionRelevance {
285287
}
286288

287289
score += match constructor_type {
288-
Some(CompletionRelevanceConstructorType::DirectConstructor) => 3,
289-
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs) => 2,
290-
Some(CompletionRelevanceConstructorType::Builder) => 2,
291-
Some(CompletionRelevanceConstructorType::Constructor) => 2,
290+
Some(CompletionRelevanceAssociatedFnType::ReturnsExpectedType) => 5,
291+
Some(CompletionRelevanceAssociatedFnType::DirectConstructor) => 4,
292+
Some(CompletionRelevanceAssociatedFnType::DirectConstructorWithArgs) => 3,
293+
Some(CompletionRelevanceAssociatedFnType::Builder) => 2,
294+
Some(CompletionRelevanceAssociatedFnType::Constructor) => 1,
292295
None => 0,
293296
};
294297

crates/ide-completion/src/render.rs

Lines changed: 135 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,7 @@ fn main() { let _: m::Spam = S$0 }
11761176
is_private_editable: false,
11771177
postfix_match: None,
11781178
is_definite: false,
1179-
constructor_type: None,
1179+
associated_fn_type: None,
11801180
},
11811181
trigger_call_info: true,
11821182
},
@@ -1203,7 +1203,7 @@ fn main() { let _: m::Spam = S$0 }
12031203
is_private_editable: false,
12041204
postfix_match: None,
12051205
is_definite: false,
1206-
constructor_type: None,
1206+
associated_fn_type: None,
12071207
},
12081208
trigger_call_info: true,
12091209
},
@@ -1282,7 +1282,7 @@ fn foo() { A { the$0 } }
12821282
is_private_editable: false,
12831283
postfix_match: None,
12841284
is_definite: false,
1285-
constructor_type: None,
1285+
associated_fn_type: None,
12861286
},
12871287
},
12881288
]
@@ -2090,7 +2090,7 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
20902090
is_private_editable: false,
20912091
postfix_match: None,
20922092
is_definite: false,
2093-
constructor_type: Some(
2093+
associated_fn_type: Some(
20942094
DirectConstructorWithArgs,
20952095
),
20962096
},
@@ -2132,6 +2132,135 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
21322132
);
21332133
}
21342134

2135+
#[test]
2136+
fn associated_fn_type() {
2137+
check_kinds(
2138+
r#"
2139+
struct A;
2140+
struct ABuilder;
2141+
impl A {
2142+
fn foo(&self) {}
2143+
fn new_1(input: u32) -> A { A }
2144+
fn new_2() -> Self { A }
2145+
fn aaaabuilder() -> ABuilder { A }
2146+
}
2147+
fn test() {
2148+
let a = A::$0;
2149+
}
2150+
"#,
2151+
&[
2152+
CompletionItemKind::Method,
2153+
CompletionItemKind::Method,
2154+
CompletionItemKind::Method,
2155+
CompletionItemKind::Method,
2156+
],
2157+
expect![[r#"
2158+
[
2159+
CompletionItem {
2160+
label: "foo(…)",
2161+
source_range: 190..190,
2162+
delete: 190..190,
2163+
insert: "foo(${1:&self})$0",
2164+
kind: Method,
2165+
lookup: "foo",
2166+
detail: "fn(&self)",
2167+
relevance: CompletionRelevance {
2168+
exact_name_match: false,
2169+
type_match: Some(
2170+
CouldUnify,
2171+
),
2172+
is_local: false,
2173+
is_item_from_trait: false,
2174+
is_name_already_imported: false,
2175+
requires_import: false,
2176+
is_op_method: false,
2177+
is_private_editable: false,
2178+
postfix_match: None,
2179+
is_definite: false,
2180+
associated_fn_type: None,
2181+
},
2182+
trigger_call_info: true,
2183+
},
2184+
CompletionItem {
2185+
label: "foo(…)",
2186+
source_range: 190..190,
2187+
delete: 190..190,
2188+
insert: "foo(${1:&self})$0",
2189+
kind: Method,
2190+
lookup: "foo",
2191+
detail: "fn(&self)",
2192+
relevance: CompletionRelevance {
2193+
exact_name_match: false,
2194+
type_match: Some(
2195+
CouldUnify,
2196+
),
2197+
is_local: false,
2198+
is_item_from_trait: false,
2199+
is_name_already_imported: false,
2200+
requires_import: false,
2201+
is_op_method: false,
2202+
is_private_editable: false,
2203+
postfix_match: None,
2204+
is_definite: false,
2205+
associated_fn_type: None,
2206+
},
2207+
trigger_call_info: true,
2208+
},
2209+
CompletionItem {
2210+
label: "foo(…)",
2211+
source_range: 190..190,
2212+
delete: 190..190,
2213+
insert: "foo(${1:&self})$0",
2214+
kind: Method,
2215+
lookup: "foo",
2216+
detail: "fn(&self)",
2217+
relevance: CompletionRelevance {
2218+
exact_name_match: false,
2219+
type_match: Some(
2220+
CouldUnify,
2221+
),
2222+
is_local: false,
2223+
is_item_from_trait: false,
2224+
is_name_already_imported: false,
2225+
requires_import: false,
2226+
is_op_method: false,
2227+
is_private_editable: false,
2228+
postfix_match: None,
2229+
is_definite: false,
2230+
associated_fn_type: None,
2231+
},
2232+
trigger_call_info: true,
2233+
},
2234+
CompletionItem {
2235+
label: "foo(…)",
2236+
source_range: 190..190,
2237+
delete: 190..190,
2238+
insert: "foo(${1:&self})$0",
2239+
kind: Method,
2240+
lookup: "foo",
2241+
detail: "fn(&self)",
2242+
relevance: CompletionRelevance {
2243+
exact_name_match: false,
2244+
type_match: Some(
2245+
CouldUnify,
2246+
),
2247+
is_local: false,
2248+
is_item_from_trait: false,
2249+
is_name_already_imported: false,
2250+
requires_import: false,
2251+
is_op_method: false,
2252+
is_private_editable: false,
2253+
postfix_match: None,
2254+
is_definite: false,
2255+
associated_fn_type: None,
2256+
},
2257+
trigger_call_info: true,
2258+
},
2259+
]
2260+
"#]],
2261+
);
2262+
}
2263+
21352264
#[test]
21362265
fn expected_fn_type_ref() {
21372266
check_kinds(
@@ -2167,7 +2296,7 @@ fn foo() {
21672296
is_private_editable: false,
21682297
postfix_match: None,
21692298
is_definite: false,
2170-
constructor_type: None,
2299+
associated_fn_type: None,
21712300
},
21722301
},
21732302
]
@@ -2216,7 +2345,7 @@ fn main() {
22162345
is_private_editable: false,
22172346
postfix_match: None,
22182347
is_definite: false,
2219-
constructor_type: Some(
2348+
associated_fn_type: Some(
22202349
DirectConstructor,
22212350
),
22222351
},

crates/ide-completion/src/render/function.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind},
1111
item::{
1212
Builder, CompletionItem, CompletionItemKind, CompletionRelevance,
13-
CompletionRelevanceConstructorType,
13+
CompletionRelevanceAssociatedFnType,
1414
},
1515
render::{compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext},
1616
CallableSnippets,
@@ -108,7 +108,7 @@ fn render(
108108
},
109109
exact_name_match: compute_exact_name_match(completion, &call),
110110
is_op_method,
111-
constructor_type: compute_constructor_type(&ctx, func, db),
111+
associated_fn_type: compute_constructor_type(&ctx, func, db),
112112
..ctx.completion_relevance()
113113
});
114114

@@ -161,23 +161,29 @@ fn compute_constructor_type(
161161
ctx: &RenderContext<'_>,
162162
func: hir::Function,
163163
db: &dyn HirDatabase,
164-
) -> Option<CompletionRelevanceConstructorType> {
164+
) -> Option<CompletionRelevanceAssociatedFnType> {
165165
if func.as_assoc_item(ctx.db()).is_none() {
166166
return None;
167167
}
168168

169169
let has_args = !func.assoc_fn_params(db).is_empty();
170170
let ret_type = func.ret_type(db);
171171

172-
if !has_args && !ret_type.is_unit() {
172+
dbg!(&ret_type, &func, &ctx);
173+
174+
if ctx.completion.expected_type.as_ref() == Some(&ret_type) {
175+
// impl Foo { fn baz(&self) -> u32 { 0 } }
176+
// let _: u32 = foo.$0; // baz is preffered as it returns expected u32
177+
Some(CompletionRelevanceAssociatedFnType::ReturnsExpectedType)
178+
} else if !has_args && !ret_type.is_unit() {
173179
// fn() -> A
174-
Some(CompletionRelevanceConstructorType::DirectConstructor)
180+
Some(CompletionRelevanceAssociatedFnType::DirectConstructor)
175181
} else if has_args && !ret_type.is_unit() {
176182
// fn(..) -> A
177-
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs)
183+
Some(CompletionRelevanceAssociatedFnType::DirectConstructorWithArgs)
178184
} else if !has_args && ret_type.display(db).to_string().ends_with("Builder") {
179185
// -> [..]Builder
180-
Some(CompletionRelevanceConstructorType::Builder)
186+
Some(CompletionRelevanceAssociatedFnType::Builder)
181187
} else {
182188
None
183189
}

0 commit comments

Comments
 (0)