Skip to content

Commit 55af177

Browse files
Merge pull request rust-lang#22508 from ChayimFriedman2/drop-pin-drop
fix: Do not fill both `drop()` and `pin_drop()` in the "fill missing members" assist
2 parents ccaa9b5 + abeee1c commit 55af177

8 files changed

Lines changed: 136 additions & 20 deletions

File tree

crates/hir-def/src/expr_store/pretty.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use stdx::never;
1414
use syntax::ast::{HasName, RangeOp};
1515

1616
use crate::{
17-
AdtId, DefWithBodyId, FunctionId, GenericDefId, StructId, TypeParamId, VariantId,
17+
AdtId, DefWithBodyId, FunctionId, GenericDefId, MacroId, StructId, TypeParamId, VariantId,
1818
attrs::AttrFlags,
1919
expr_store::path::{GenericArg, GenericArgs},
2020
hir::{
@@ -1136,6 +1136,9 @@ impl Printer<'_> {
11361136
LangItemTarget::TraitId(it) => write_name!(it),
11371137
LangItemTarget::EnumVariantId(it) => write_name!(it),
11381138
LangItemTarget::ConstId(it) => write_name!(it),
1139+
LangItemTarget::MacroId(MacroId::Macro2Id(it)) => write_name!(it),
1140+
LangItemTarget::MacroId(MacroId::MacroRulesId(it)) => write_name!(it),
1141+
LangItemTarget::MacroId(MacroId::ProcMacroId(it)) => write_name!(it),
11391142
}
11401143

11411144
if let Some(s) = s {

crates/hir-def/src/lang_item.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ pub enum LangItemTarget {
2626
TraitId(TraitId),
2727
EnumVariantId(EnumVariantId),
2828
ConstId(ConstId),
29+
MacroId(MacroId),
2930
}
3031

3132
impl_from!(
32-
EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId, ConstId for LangItemTarget
33+
EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId, ConstId, MacroId for LangItemTarget
3334
);
3435

3536
/// Salsa query. This will look for lang items in a specific crate.
@@ -276,7 +277,6 @@ impl LangItems {
276277
(self.BitXorAssign, &mut self.BitXorAssign_bitxor_assign, sym::bitxor_assign),
277278
(self.BitOrAssign, &mut self.BitOrAssign_bitor_assign, sym::bitor_assign),
278279
(self.BitAndAssign, &mut self.BitAndAssign_bitand_assign, sym::bitand_assign),
279-
(self.Drop, &mut self.Drop_drop, sym::drop),
280280
(self.Debug, &mut self.Debug_fmt, sym::fmt),
281281
(self.Deref, &mut self.Deref_deref, sym::deref),
282282
(self.DerefMut, &mut self.DerefMut_deref_mut, sym::deref_mut),
@@ -307,6 +307,13 @@ impl LangItems {
307307
);
308308
Some(())
309309
})();
310+
(|| {
311+
methods(
312+
self.Drop?,
313+
&mut [(&mut self.Drop_drop, sym::drop), (&mut self.Drop_pin_drop, sym::pin_drop)],
314+
);
315+
Some(())
316+
})();
310317
}
311318
}
312319

@@ -397,18 +404,25 @@ macro_rules! language_item_table {
397404
}
398405

399406
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
407+
#[allow(non_camel_case_types)]
400408
pub enum LangItemEnum {
401409
$(
402410
$(#[$attr])*
403411
$lang_item,
404412
)*
413+
$( $non_lang_trait, )*
414+
$( $non_lang_macro_field, )*
415+
$( $resolve_manually, )*
405416
}
406417

407418
impl LangItemEnum {
408419
#[inline]
409420
pub fn from_lang_items(self, lang_items: &LangItems) -> Option<LangItemTarget> {
410421
match self {
411422
$( LangItemEnum::$lang_item => lang_items.$lang_item.map(Into::into), )*
423+
$( LangItemEnum::$non_lang_trait => lang_items.$non_lang_trait.map(Into::into), )*
424+
$( LangItemEnum::$non_lang_macro_field => lang_items.$non_lang_macro_field.map(Into::into), )*
425+
$( LangItemEnum::$resolve_manually => lang_items.$resolve_manually.map(Into::into), )*
412426
}
413427
}
414428

@@ -716,6 +730,7 @@ language_item_table! { LangItems =>
716730
PartialOrd_ge, FunctionId;
717731
PartialOrd_gt, FunctionId;
718732
Drop_drop, FunctionId;
733+
Drop_pin_drop, FunctionId;
719734
Debug_fmt, FunctionId;
720735
Deref_deref, FunctionId;
721736
DerefMut_deref_mut, FunctionId;

crates/hir-def/src/resolver.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ impl<'db> Resolver<'db> {
195195
LangItemTarget::FunctionId(_)
196196
| LangItemTarget::ImplId(_)
197197
| LangItemTarget::StaticId(_)
198-
| LangItemTarget::ConstId(_) => return None,
198+
| LangItemTarget::ConstId(_)
199+
| LangItemTarget::MacroId(_) => return None,
199200
};
200201
return Some((
201202
type_ns,
@@ -343,7 +344,8 @@ impl<'db> Resolver<'db> {
343344
| LangItemTarget::ImplId(_)
344345
| LangItemTarget::TypeAliasId(_)
345346
| LangItemTarget::TraitId(_)
346-
| LangItemTarget::EnumId(_) => return None,
347+
| LangItemTarget::EnumId(_)
348+
| LangItemTarget::MacroId(_) => return None,
347349
}),
348350
ResolvePathResultPrefixInfo::default(),
349351
));
@@ -359,7 +361,8 @@ impl<'db> Resolver<'db> {
359361
LangItemTarget::FunctionId(_)
360362
| LangItemTarget::ImplId(_)
361363
| LangItemTarget::StaticId(_)
362-
| LangItemTarget::ConstId(_) => return None,
364+
| LangItemTarget::ConstId(_)
365+
| LangItemTarget::MacroId(_) => return None,
363366
};
364367
// Remaining segments start from 0 because lang paths have no segments other than the remaining.
365368
return Some((

crates/hir/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,6 +2283,14 @@ impl fmt::Debug for Function {
22832283
}
22842284

22852285
impl Function {
2286+
pub fn lang(db: &dyn HirDatabase, krate: Crate, lang_item: LangItem) -> Option<Function> {
2287+
let lang_items = hir_def::lang_item::lang_items(db, krate.id);
2288+
match lang_item.from_lang_items(lang_items)? {
2289+
LangItemTarget::FunctionId(it) => Some(it.into()),
2290+
_ => None,
2291+
}
2292+
}
2293+
22862294
pub fn module(self, db: &dyn HirDatabase) -> Module {
22872295
match self.id {
22882296
AnyFunctionId::FunctionId(id) => id.module(db).into(),

crates/ide-assists/src/handlers/add_missing_impl_members.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,6 +2637,69 @@ struct Struct;
26372637
26382638
impl Trait for Struct {
26392639
$0
2640+
}
2641+
"#,
2642+
);
2643+
}
2644+
2645+
#[test]
2646+
fn drop_pin_drop() {
2647+
check_assist_not_applicable(
2648+
add_missing_impl_members,
2649+
r#"
2650+
//- minicore: drop, pin
2651+
struct Foo;
2652+
impl Drop for Foo {$0
2653+
fn drop(&mut self) {}
2654+
}
2655+
"#,
2656+
);
2657+
check_assist_not_applicable(
2658+
add_missing_impl_members,
2659+
r#"
2660+
//- minicore: drop, pin
2661+
struct Foo;
2662+
impl Drop for Foo {$0
2663+
fn pin_drop(self: core::pin::Pin<&mut Self>) {}
2664+
}
2665+
"#,
2666+
);
2667+
2668+
check_assist_not_applicable(
2669+
add_missing_default_members,
2670+
r#"
2671+
//- minicore: drop, pin
2672+
struct Foo;
2673+
impl Drop for Foo {$0
2674+
fn drop(&mut self) {}
2675+
}
2676+
"#,
2677+
);
2678+
check_assist_not_applicable(
2679+
add_missing_default_members,
2680+
r#"
2681+
//- minicore: drop, pin
2682+
struct Foo;
2683+
impl Drop for Foo {$0
2684+
fn pin_drop(self: core::pin::Pin<&mut Self>) {}
2685+
}
2686+
"#,
2687+
);
2688+
2689+
check_assist(
2690+
add_missing_impl_members,
2691+
r#"
2692+
//- minicore: drop, pin
2693+
struct Foo;
2694+
impl Drop for Foo {$0
2695+
}
2696+
"#,
2697+
r#"
2698+
struct Foo;
2699+
impl Drop for Foo {
2700+
fn drop(&mut self) {
2701+
${0:todo!()}
2702+
}
26402703
}
26412704
"#,
26422705
);

crates/ide-db/src/traits.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Functionality for obtaining data related to traits from the DB.
22
33
use crate::{RootDatabase, defs::Definition};
4-
use hir::{AsAssocItem, Semantics, db::HirDatabase};
4+
use hir::{AsAssocItem, HasCrate, Semantics, db::HirDatabase, sym};
55
use rustc_hash::FxHashSet;
66
use syntax::{AstNode, ast};
77

@@ -51,19 +51,38 @@ pub fn get_missing_assoc_items(
5151
}
5252
}
5353

54-
imp.trait_(sema.db).map_or(vec![], |target_trait| {
55-
target_trait
56-
.items(sema.db)
57-
.into_iter()
58-
.filter(|i| match i {
59-
hir::AssocItem::Function(f) => !impl_fns_consts.contains(&f.name(sema.db)),
60-
hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db)),
61-
hir::AssocItem::Const(c) => {
62-
c.name(sema.db).map(|n| !impl_fns_consts.contains(&n)).unwrap_or_default()
63-
}
64-
})
65-
.collect()
66-
})
54+
let Some(target_trait) = imp.trait_(sema.db) else { return Vec::new() };
55+
56+
// `Drop` has two methods, `drop()` and `pin_drop()`, and you can only implement one of them, so
57+
// we consider `pin_drop()` to not exist, unless you already implement it.
58+
let drop_trait = hir::Trait::lang(sema.db, imp.krate(sema.db), hir::LangItem::Drop);
59+
if let Some(drop_trait) = drop_trait
60+
&& target_trait == drop_trait
61+
{
62+
return if impl_fns_consts.is_empty() {
63+
// No method implemented, return `drop()`.
64+
let drop_drop = drop_trait.function(sema.db, sym::drop);
65+
match drop_drop {
66+
Some(drop_drop) => vec![hir::AssocItem::Function(drop_drop)],
67+
None => Vec::new(),
68+
}
69+
} else {
70+
// Some method is already implemented, leave it.
71+
Vec::new()
72+
};
73+
}
74+
75+
target_trait
76+
.items(sema.db)
77+
.into_iter()
78+
.filter(|i| match i {
79+
hir::AssocItem::Function(f) => !impl_fns_consts.contains(&f.name(sema.db)),
80+
hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db)),
81+
hir::AssocItem::Const(c) => {
82+
c.name(sema.db).map(|n| !impl_fns_consts.contains(&n)).unwrap_or_default()
83+
}
84+
})
85+
.collect()
6786
}
6887

6988
/// Converts associated trait impl items to their trait definition counterpart

crates/intern/src/symbol/symbols.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ define_symbols! {
295295
doc,
296296
drop_in_place,
297297
drop,
298+
pin_drop,
298299
dyn_metadata,
299300
efiapi,
300301
eh_catch_typeinfo,

crates/test-utils/src/minicore.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,10 @@ pub mod ops {
655655
#[lang = "drop"]
656656
pub trait Drop {
657657
fn drop(&mut self);
658+
659+
// region:pin
660+
fn pin_drop(self: crate::pin::Pin<&mut Self>) {}
661+
// endregion:pin
658662
}
659663
// endregion:drop
660664

0 commit comments

Comments
 (0)