Skip to content

Commit 9fff4ad

Browse files
committed
Refactor completion relevance constructor type enum
1 parent 49ec70b commit 9fff4ad

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
@@ -167,7 +167,7 @@ pub struct CompletionRelevance {
167167
/// This is set for type inference results
168168
pub is_definite: bool,
169169
/// This is set for items that are constructors for the type of the impl/trait
170-
pub constructor_type: Option<CompletionRelevanceConstructorType>,
170+
pub associated_fn_type: Option<CompletionRelevanceAssociatedFnType>,
171171
}
172172

173173
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -210,7 +210,9 @@ pub enum CompletionRelevancePostfixMatch {
210210
}
211211

212212
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
213-
pub enum CompletionRelevanceConstructorType {
213+
pub enum CompletionRelevanceAssociatedFnType {
214+
/// Returns a type that is expected in this context
215+
ReturnsExpectedType,
214216
/// Returns the Self type of the impl/trait
215217
DirectConstructor,
216218
DirectConstructorWithArgs,
@@ -244,7 +246,7 @@ impl CompletionRelevance {
244246
postfix_match,
245247
is_definite,
246248
is_item_from_notable_trait,
247-
constructor_type,
249+
associated_fn_type: constructor_type,
248250
} = self;
249251

250252
// lower rank private things
@@ -291,10 +293,11 @@ impl CompletionRelevance {
291293
}
292294

293295
score += match constructor_type {
294-
Some(CompletionRelevanceConstructorType::DirectConstructor) => 3,
295-
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs) => 2,
296-
Some(CompletionRelevanceConstructorType::Builder) => 2,
297-
Some(CompletionRelevanceConstructorType::Constructor) => 2,
296+
Some(CompletionRelevanceAssociatedFnType::ReturnsExpectedType) => 5,
297+
Some(CompletionRelevanceAssociatedFnType::DirectConstructor) => 4,
298+
Some(CompletionRelevanceAssociatedFnType::DirectConstructorWithArgs) => 3,
299+
Some(CompletionRelevanceAssociatedFnType::Builder) => 2,
300+
Some(CompletionRelevanceAssociatedFnType::Constructor) => 1,
298301
None => 0,
299302
};
300303

crates/ide-completion/src/render.rs

Lines changed: 135 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ fn main() { let _: m::Spam = S$0 }
11771177
is_private_editable: false,
11781178
postfix_match: None,
11791179
is_definite: false,
1180-
constructor_type: None,
1180+
associated_fn_type: None,
11811181
},
11821182
trigger_call_info: true,
11831183
},
@@ -1205,7 +1205,7 @@ fn main() { let _: m::Spam = S$0 }
12051205
is_private_editable: false,
12061206
postfix_match: None,
12071207
is_definite: false,
1208-
constructor_type: None,
1208+
associated_fn_type: None,
12091209
},
12101210
trigger_call_info: true,
12111211
},
@@ -1285,7 +1285,7 @@ fn foo() { A { the$0 } }
12851285
is_private_editable: false,
12861286
postfix_match: None,
12871287
is_definite: false,
1288-
constructor_type: None,
1288+
associated_fn_type: None,
12891289
},
12901290
},
12911291
]
@@ -2093,7 +2093,7 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
20932093
is_private_editable: false,
20942094
postfix_match: None,
20952095
is_definite: false,
2096-
constructor_type: Some(
2096+
associated_fn_type: Some(
20972097
DirectConstructorWithArgs,
20982098
),
20992099
},
@@ -2135,6 +2135,135 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
21352135
);
21362136
}
21372137

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

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,
@@ -112,7 +112,7 @@ fn render(
112112
exact_name_match: compute_exact_name_match(completion, &call),
113113
is_op_method,
114114
is_item_from_notable_trait,
115-
constructor_type: compute_constructor_type(&ctx, func, db),
115+
associated_fn_type: compute_constructor_type(&ctx, func, db),
116116
..ctx.completion_relevance()
117117
});
118118

@@ -165,23 +165,29 @@ fn compute_constructor_type(
165165
ctx: &RenderContext<'_>,
166166
func: hir::Function,
167167
db: &dyn HirDatabase,
168-
) -> Option<CompletionRelevanceConstructorType> {
168+
) -> Option<CompletionRelevanceAssociatedFnType> {
169169
if func.as_assoc_item(ctx.db()).is_none() {
170170
return None;
171171
}
172172

173173
let has_args = !func.assoc_fn_params(db).is_empty();
174174
let ret_type = func.ret_type(db);
175175

176-
if !has_args && !ret_type.is_unit() {
176+
dbg!(&ret_type, &func, &ctx);
177+
178+
if ctx.completion.expected_type.as_ref() == Some(&ret_type) {
179+
// impl Foo { fn baz(&self) -> u32 { 0 } }
180+
// let _: u32 = foo.$0; // baz is preffered as it returns expected u32
181+
Some(CompletionRelevanceAssociatedFnType::ReturnsExpectedType)
182+
} else if !has_args && !ret_type.is_unit() {
177183
// fn() -> A
178-
Some(CompletionRelevanceConstructorType::DirectConstructor)
184+
Some(CompletionRelevanceAssociatedFnType::DirectConstructor)
179185
} else if has_args && !ret_type.is_unit() {
180186
// fn(..) -> A
181-
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs)
187+
Some(CompletionRelevanceAssociatedFnType::DirectConstructorWithArgs)
182188
} else if !has_args && ret_type.display(db).to_string().ends_with("Builder") {
183189
// -> [..]Builder
184-
Some(CompletionRelevanceConstructorType::Builder)
190+
Some(CompletionRelevanceAssociatedFnType::Builder)
185191
} else {
186192
None
187193
}

0 commit comments

Comments
 (0)