@@ -92,26 +92,32 @@ impl<'a> RenderContext<'a> {
9292 && self . completion . token . parent ( ) . is_some_and ( |it| it. kind ( ) == SyntaxKind :: MACRO_CALL )
9393 }
9494
95- fn is_deprecated ( & self , def : impl HasAttrs ) -> bool {
96- def. attrs ( self . db ( ) ) . is_deprecated ( )
97- }
98-
99- fn is_deprecated_assoc_item ( & self , as_assoc_item : impl AsAssocItem ) -> bool {
95+ /// Whether `def` is deprecated.
96+ ///
97+ /// This can happen for two reasons:
98+ /// - the def is marked with `#[deprecated]`
99+ /// - the def is an assoc item whose trait is deprecated
100+ ///
101+ /// In order to be able to check for the latter, we'd ideally want to `try_as_dyn<_, dyn AsAssocItem>(def)`
102+ /// (see [`try_as_dyn`][]), but that function is currently unstable. Therefore, we employ a hack instead:
103+ /// if `def` can be an assoc item, it should be passed to this method as follows:
104+ /// ```ignore
105+ /// self.is_deprecated(def, Some(def))
106+ /// ```
107+ /// otherwise, it should be passed as:
108+ /// ```ignore
109+ /// self.is_deprecated(def, None)
110+ /// ```
111+ ///
112+ /// [`try_as_dyn`]: https://doc.rust-lang.org/std/any/fn.try_as_dyn.html
113+ fn is_deprecated ( & self , def : impl HasAttrs , def_as_assoc_item : Option < hir:: AssocItem > ) -> bool {
100114 let db = self . db ( ) ;
101- let assoc = match as_assoc_item. as_assoc_item ( db) {
102- Some ( assoc) => assoc,
103- None => return false ,
104- } ;
105-
106- let is_assoc_deprecated = match assoc {
107- hir:: AssocItem :: Function ( it) => self . is_deprecated ( it) ,
108- hir:: AssocItem :: Const ( it) => self . is_deprecated ( it) ,
109- hir:: AssocItem :: TypeAlias ( it) => self . is_deprecated ( it) ,
110- } ;
111- is_assoc_deprecated
112- || assoc
113- . container_or_implemented_trait ( db)
114- . is_some_and ( |trait_| self . is_deprecated ( trait_) )
115+ def. attrs ( db) . is_deprecated ( )
116+ || def_as_assoc_item
117+ . and_then ( |assoc| assoc. container_or_implemented_trait ( db) )
118+ . is_some_and ( |trait_| {
119+ self . is_deprecated ( trait_, None /* traits can't be assoc items */ )
120+ } )
115121 }
116122
117123 // FIXME: remove this
@@ -128,7 +134,7 @@ pub(crate) fn render_field(
128134 ty : & hir:: Type < ' _ > ,
129135) -> CompletionItem {
130136 let db = ctx. db ( ) ;
131- let is_deprecated = ctx. is_deprecated ( field) ;
137+ let is_deprecated = ctx. is_deprecated ( field, None /* fields can't be assoc items */ ) ;
132138 let name = field. name ( db) ;
133139 let ( name, escaped_name) =
134140 ( name. as_str ( ) . to_smolstr ( ) , name. display_no_db ( ctx. completion . edition ) . to_smolstr ( ) ) ;
@@ -575,10 +581,15 @@ fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<Documentati
575581}
576582
577583fn scope_def_is_deprecated ( ctx : & RenderContext < ' _ > , resolution : ScopeDef ) -> bool {
584+ let db = ctx. db ( ) ;
578585 match resolution {
579- ScopeDef :: ModuleDef ( it) => ctx. is_deprecated ( it) || ctx. is_deprecated_assoc_item ( it) ,
580- ScopeDef :: GenericParam ( it) => ctx. is_deprecated ( it) ,
581- ScopeDef :: AdtSelfType ( it) => ctx. is_deprecated ( it) ,
586+ ScopeDef :: ModuleDef ( it) => ctx. is_deprecated ( it, it. as_assoc_item ( db) ) ,
587+ ScopeDef :: GenericParam ( it) => {
588+ ctx. is_deprecated ( it, None /* generic params can't be assoc items */ )
589+ }
590+ ScopeDef :: AdtSelfType ( it) => {
591+ ctx. is_deprecated ( it, None /* `Self` can't be an assoc item */ )
592+ }
582593 _ => false ,
583594 }
584595}
0 commit comments