Skip to content

Commit b201684

Browse files
committed
Auto merge of rust-lang#16274 - dfireBird:completion_score, r=Veykril
Add notable_trait predicate to `CompletionRelevance` Given a score of 1 for now, will change as per reviews needed.
2 parents 1c9bb31 + 257870e commit b201684

File tree

5 files changed

+108
-5
lines changed

5 files changed

+108
-5
lines changed

crates/hir-def/src/attr.rs

+7
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@ impl Attrs {
207207
})
208208
}
209209

210+
pub fn has_doc_notable_trait(&self) -> bool {
211+
self.by_key("doc").tt_values().any(|tt| {
212+
tt.delimiter.kind == DelimiterKind::Parenthesis &&
213+
matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.text == "notable_trait")
214+
})
215+
}
216+
210217
pub fn doc_exprs(&self) -> impl Iterator<Item = DocExpr> + '_ {
211218
self.by_key("doc").tt_values().map(DocExpr::parse)
212219
}

crates/ide-completion/src/context.rs

+5
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,11 @@ impl CompletionContext<'_> {
529529
}
530530
}
531531

532+
/// Whether the given trait has `#[doc(notable_trait)]`
533+
pub(crate) fn is_doc_notable_trait(&self, trait_: hir::Trait) -> bool {
534+
trait_.attrs(self.db).has_doc_notable_trait()
535+
}
536+
532537
/// Returns the traits in scope, with the [`Drop`] trait removed.
533538
pub(crate) fn traits_in_scope(&self) -> hir::VisibleTraits {
534539
let mut traits_in_scope = self.scope.visible_traits();

crates/ide-completion/src/item.rs

+6
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ pub struct CompletionRelevance {
152152
pub is_local: bool,
153153
/// This is set when trait items are completed in an impl of that trait.
154154
pub is_item_from_trait: bool,
155+
/// This is set for when trait items are from traits with `#[doc(notable_trait)]`
156+
pub is_item_from_notable_trait: bool,
155157
/// This is set when an import is suggested whose name is already imported.
156158
pub is_name_already_imported: bool,
157159
/// This is set for completions that will insert a `use` item.
@@ -228,6 +230,7 @@ impl CompletionRelevance {
228230
is_private_editable,
229231
postfix_match,
230232
is_definite,
233+
is_item_from_notable_trait,
231234
} = self;
232235

233236
// lower rank private things
@@ -266,6 +269,9 @@ impl CompletionRelevance {
266269
if is_item_from_trait {
267270
score += 1;
268271
}
272+
if is_item_from_notable_trait {
273+
score += 1;
274+
}
269275
if is_definite {
270276
score += 10;
271277
}

crates/ide-completion/src/render.rs

+81
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,7 @@ fn main() { let _: m::Spam = S$0 }
11701170
),
11711171
is_local: false,
11721172
is_item_from_trait: false,
1173+
is_item_from_notable_trait: false,
11731174
is_name_already_imported: false,
11741175
requires_import: false,
11751176
is_op_method: false,
@@ -1196,6 +1197,7 @@ fn main() { let _: m::Spam = S$0 }
11961197
),
11971198
is_local: false,
11981199
is_item_from_trait: false,
1200+
is_item_from_notable_trait: false,
11991201
is_name_already_imported: false,
12001202
requires_import: false,
12011203
is_op_method: false,
@@ -1274,6 +1276,7 @@ fn foo() { A { the$0 } }
12741276
),
12751277
is_local: false,
12761278
is_item_from_trait: false,
1279+
is_item_from_notable_trait: false,
12771280
is_name_already_imported: false,
12781281
requires_import: false,
12791282
is_op_method: false,
@@ -2089,6 +2092,7 @@ fn foo() {
20892092
),
20902093
is_local: false,
20912094
is_item_from_trait: false,
2095+
is_item_from_notable_trait: false,
20922096
is_name_already_imported: false,
20932097
requires_import: false,
20942098
is_op_method: false,
@@ -2439,4 +2443,81 @@ impl S {
24392443
"#,
24402444
)
24412445
}
2446+
2447+
#[test]
2448+
fn notable_traits_method_relevance() {
2449+
check_kinds(
2450+
r#"
2451+
#[doc(notable_trait)]
2452+
trait Write {
2453+
fn write(&self);
2454+
fn flush(&self);
2455+
}
2456+
2457+
struct Writer;
2458+
2459+
impl Write for Writer {
2460+
fn write(&self) {}
2461+
fn flush(&self) {}
2462+
}
2463+
2464+
fn main() {
2465+
Writer.$0
2466+
}
2467+
"#,
2468+
&[
2469+
CompletionItemKind::Method,
2470+
CompletionItemKind::SymbolKind(SymbolKind::Field),
2471+
CompletionItemKind::SymbolKind(SymbolKind::Function),
2472+
],
2473+
expect![[r#"
2474+
[
2475+
CompletionItem {
2476+
label: "flush()",
2477+
source_range: 193..193,
2478+
delete: 193..193,
2479+
insert: "flush()$0",
2480+
kind: Method,
2481+
lookup: "flush",
2482+
detail: "fn(&self)",
2483+
relevance: CompletionRelevance {
2484+
exact_name_match: false,
2485+
type_match: None,
2486+
is_local: false,
2487+
is_item_from_trait: false,
2488+
is_item_from_notable_trait: true,
2489+
is_name_already_imported: false,
2490+
requires_import: false,
2491+
is_op_method: false,
2492+
is_private_editable: false,
2493+
postfix_match: None,
2494+
is_definite: false,
2495+
},
2496+
},
2497+
CompletionItem {
2498+
label: "write()",
2499+
source_range: 193..193,
2500+
delete: 193..193,
2501+
insert: "write()$0",
2502+
kind: Method,
2503+
lookup: "write",
2504+
detail: "fn(&self)",
2505+
relevance: CompletionRelevance {
2506+
exact_name_match: false,
2507+
type_match: None,
2508+
is_local: false,
2509+
is_item_from_trait: false,
2510+
is_item_from_notable_trait: true,
2511+
is_name_already_imported: false,
2512+
requires_import: false,
2513+
is_op_method: false,
2514+
is_private_editable: false,
2515+
postfix_match: None,
2516+
is_definite: false,
2517+
},
2518+
},
2519+
]
2520+
"#]],
2521+
);
2522+
}
24422523
}

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

+9-5
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,13 @@ fn render(
7474
);
7575

7676
let ret_type = func.ret_type(db);
77-
let is_op_method = func
78-
.as_assoc_item(ctx.db())
79-
.and_then(|trait_| trait_.containing_trait_or_trait_impl(ctx.db()))
80-
.map_or(false, |trait_| completion.is_ops_trait(trait_));
77+
let assoc_item = func.as_assoc_item(db);
78+
79+
let trait_ = assoc_item.and_then(|trait_| trait_.containing_trait_or_trait_impl(db));
80+
let is_op_method = trait_.map_or(false, |trait_| completion.is_ops_trait(trait_));
81+
82+
let is_item_from_notable_trait =
83+
trait_.map_or(false, |trait_| completion.is_doc_notable_trait(trait_));
8184

8285
let (has_dot_receiver, has_call_parens, cap) = match func_kind {
8386
FuncKind::Function(&PathCompletionCtx {
@@ -105,6 +108,7 @@ fn render(
105108
},
106109
exact_name_match: compute_exact_name_match(completion, &call),
107110
is_op_method,
111+
is_item_from_notable_trait,
108112
..ctx.completion_relevance()
109113
});
110114

@@ -141,7 +145,7 @@ fn render(
141145
item.add_import(import_to_add);
142146
}
143147
None => {
144-
if let Some(actm) = func.as_assoc_item(db) {
148+
if let Some(actm) = assoc_item {
145149
if let Some(trt) = actm.containing_trait_or_trait_impl(db) {
146150
item.trait_name(trt.name(db).to_smol_str());
147151
}

0 commit comments

Comments
 (0)