Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-db/src/traits.rs')
| -rw-r--r-- | crates/ide-db/src/traits.rs | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/crates/ide-db/src/traits.rs b/crates/ide-db/src/traits.rs index d38d9b6708..994427ac76 100644 --- a/crates/ide-db/src/traits.rs +++ b/crates/ide-db/src/traits.rs @@ -1,7 +1,7 @@ //! Functionality for obtaining data related to traits from the DB. use crate::{RootDatabase, defs::Definition}; -use hir::{AsAssocItem, Semantics, db::HirDatabase}; +use hir::{AsAssocItem, HasCrate, Semantics, db::HirDatabase, sym}; use rustc_hash::FxHashSet; use syntax::{AstNode, ast}; @@ -51,19 +51,38 @@ pub fn get_missing_assoc_items( } } - imp.trait_(sema.db).map_or(vec![], |target_trait| { - target_trait - .items(sema.db) - .into_iter() - .filter(|i| match i { - hir::AssocItem::Function(f) => !impl_fns_consts.contains(&f.name(sema.db)), - hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db)), - hir::AssocItem::Const(c) => { - c.name(sema.db).map(|n| !impl_fns_consts.contains(&n)).unwrap_or_default() - } - }) - .collect() - }) + let Some(target_trait) = imp.trait_(sema.db) else { return Vec::new() }; + + // `Drop` has two methods, `drop()` and `pin_drop()`, and you can only implement one of them, so + // we consider `pin_drop()` to not exist, unless you already implement it. + let drop_trait = hir::Trait::lang(sema.db, imp.krate(sema.db), hir::LangItem::Drop); + if let Some(drop_trait) = drop_trait + && target_trait == drop_trait + { + return if impl_fns_consts.is_empty() { + // No method implemented, return `drop()`. + let drop_drop = drop_trait.function(sema.db, sym::drop); + match drop_drop { + Some(drop_drop) => vec![hir::AssocItem::Function(drop_drop)], + None => Vec::new(), + } + } else { + // Some method is already implemented, leave it. + Vec::new() + }; + } + + target_trait + .items(sema.db) + .into_iter() + .filter(|i| match i { + hir::AssocItem::Function(f) => !impl_fns_consts.contains(&f.name(sema.db)), + hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db)), + hir::AssocItem::Const(c) => { + c.name(sema.db).map(|n| !impl_fns_consts.contains(&n)).unwrap_or_default() + } + }) + .collect() } /// Converts associated trait impl items to their trait definition counterpart |