@@ -61,6 +61,9 @@ pub struct CompletionItem {
6161 pub documentation : Option < Documentation < ' static > > ,
6262
6363 /// Whether this item is marked as deprecated
64+ ///
65+ /// NOTE: this field is used in the LSP protocol. For the use of this information in completion
66+ /// scoring, see [`CompletionRelevance::is_deprecated`].
6467 pub deprecated : bool ,
6568
6669 /// If completing a function call, ask the editor to show parameter popup
@@ -194,6 +197,11 @@ pub struct CompletionRelevance {
194197 pub is_skipping_completion : bool ,
195198 /// if inherent impl already exists in current module, user may not want to implement it again.
196199 pub has_local_inherent_impl : bool ,
200+ /// Set when the completion item is deprecated.
201+ ///
202+ /// NOTE: This is duplicated from [`CompletionItem::deprecated`] in order to allow using this
203+ /// information in the calculation of the relevance score.
204+ pub is_deprecated : bool ,
197205}
198206#[ derive( Debug , Clone , Copy , Eq , PartialEq ) ]
199207pub struct CompletionRelevanceTraitInfo {
@@ -286,6 +294,7 @@ impl CompletionRelevance {
286294 function,
287295 is_skipping_completion,
288296 has_local_inherent_impl,
297+ is_deprecated,
289298 } = self ;
290299
291300 // only applicable for completions within use items
@@ -362,6 +371,11 @@ impl CompletionRelevance {
362371 score -= 5 ;
363372 }
364373
374+ // lower rank for deprecated items
375+ if is_deprecated {
376+ score -= 5 ;
377+ }
378+
365379 score
366380 }
367381
@@ -590,6 +604,9 @@ impl Builder {
590604 None => TextEdit :: replace ( self . source_range , insert_text) ,
591605 } ;
592606
607+ // Copy `deprecated` to `self.relevance.is_deprecated`
608+ let relevance = CompletionRelevance { is_deprecated : self . deprecated , ..self . relevance } ;
609+
593610 let import_to_add = self
594611 . imports_to_add
595612 . into_iter ( )
@@ -622,7 +639,7 @@ impl Builder {
622639 kind : self . kind ,
623640 deprecated : self . deprecated ,
624641 trigger_call_info : self . trigger_call_info ,
625- relevance : self . relevance ,
642+ relevance,
626643 ref_match : self . ref_match ,
627644 import_to_add,
628645 }
@@ -693,6 +710,15 @@ impl Builder {
693710 self
694711 }
695712 pub ( crate ) fn set_relevance ( & mut self , relevance : CompletionRelevance ) -> & mut Builder {
713+ // The default value of `CompletionRelevance.is_deprecated` is `false`, so it being `true`
714+ // would mean it was set manually. Advise using the other function instead.
715+ //
716+ // This is technically not necessary, because `deprecated` will get reconciled in
717+ // `Builder::build` anyway -- it just helps keep the callers consistent.
718+ assert ! (
719+ !relevance. is_deprecated,
720+ "`deprecated` should be set using `Builder::set_deprecated` instead"
721+ ) ;
696722 self . relevance = relevance;
697723 self
698724 }
@@ -727,9 +753,25 @@ mod tests {
727753 use test_utils:: assert_eq_text;
728754
729755 use super :: {
730- CompletionRelevance , CompletionRelevancePostfixMatch , CompletionRelevanceTypeMatch ,
756+ CompletionItem , CompletionItemKind , CompletionRelevance , CompletionRelevancePostfixMatch ,
757+ CompletionRelevanceTypeMatch ,
731758 } ;
732759
760+ #[ test]
761+ fn builder_deprecated_from_set_deprecated ( ) {
762+ // setting just `item.deprecated` also sets `item.relevance.is_deprecated`
763+ let mut builder = CompletionItem :: new (
764+ CompletionItemKind :: Expression ,
765+ Default :: default ( ) ,
766+ "" ,
767+ syntax:: Edition :: DEFAULT ,
768+ ) ;
769+ builder. set_deprecated ( true ) ;
770+ let item = builder. build ( & Default :: default ( ) ) ;
771+ assert ! ( item. deprecated) ;
772+ assert ! ( item. relevance. is_deprecated) ;
773+ }
774+
733775 /// Check that these are CompletionRelevance are sorted in ascending order
734776 /// by their relevance score.
735777 ///
0 commit comments