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.rs47
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