Skip to content

Commit 578269e

Browse files
bors[bot]Veykril
andauthored
Merge #11093
11093: fix: Do not complete `Drop::drop`, complete `std::mem::drop` instead r=Veykril a=Veykril Fixes #5005 bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents d4c5bf7 + 85ed5a3 commit 578269e

File tree

9 files changed

+127
-42
lines changed

9 files changed

+127
-42
lines changed

crates/ide/src/hover/tests.rs

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,46 +2361,53 @@ fn foo(ar$0g: &impl Foo + Bar<S>) {}
23612361
fn test_hover_async_block_impl_trait_has_goto_type_action() {
23622362
check_actions(
23632363
r#"
2364-
//- minicore: future
2364+
//- /main.rs crate:main deps:core
2365+
// we don't use minicore here so that this test doesn't randomly fail
2366+
// when someone edits minicore
23652367
struct S;
23662368
fn foo() {
23672369
let fo$0o = async { S };
23682370
}
2371+
//- /core.rs crate:core
2372+
pub mod future {
2373+
#[lang = "future_trait"]
2374+
pub trait Future {}
2375+
}
23692376
"#,
23702377
expect![[r#"
2371-
[
2372-
GoToType(
2373-
[
2374-
HoverGotoTypeData {
2375-
mod_path: "core::future::Future",
2376-
nav: NavigationTarget {
2377-
file_id: FileId(
2378-
1,
2379-
),
2380-
full_range: 276..458,
2381-
focus_range: 315..321,
2382-
name: "Future",
2383-
kind: Trait,
2384-
description: "pub trait Future",
2385-
},
2378+
[
2379+
GoToType(
2380+
[
2381+
HoverGotoTypeData {
2382+
mod_path: "core::future::Future",
2383+
nav: NavigationTarget {
2384+
file_id: FileId(
2385+
1,
2386+
),
2387+
full_range: 21..69,
2388+
focus_range: 60..66,
2389+
name: "Future",
2390+
kind: Trait,
2391+
description: "pub trait Future",
23862392
},
2387-
HoverGotoTypeData {
2388-
mod_path: "test::S",
2389-
nav: NavigationTarget {
2390-
file_id: FileId(
2391-
0,
2392-
),
2393-
full_range: 0..9,
2394-
focus_range: 7..8,
2395-
name: "S",
2396-
kind: Struct,
2397-
description: "struct S",
2398-
},
2393+
},
2394+
HoverGotoTypeData {
2395+
mod_path: "main::S",
2396+
nav: NavigationTarget {
2397+
file_id: FileId(
2398+
0,
2399+
),
2400+
full_range: 0..110,
2401+
focus_range: 108..109,
2402+
name: "S",
2403+
kind: Struct,
2404+
description: "struct S",
23992405
},
2400-
],
2401-
),
2402-
]
2403-
"#]],
2406+
},
2407+
],
2408+
),
2409+
]
2410+
"#]],
24042411
);
24052412
}
24062413

crates/ide_completion/src/completions/attribute/derive.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Completion for derives
22
use hir::{HasAttrs, MacroDef, MacroKind};
33
use ide_db::{
4-
helpers::{import_assets::ImportAssets, insert_use::ImportScope, FamousDefs},
4+
helpers::{import_assets::ImportAssets, insert_use::ImportScope},
55
SymbolKind,
66
};
77
use itertools::Itertools;
@@ -18,7 +18,7 @@ pub(super) fn complete_derive(
1818
ctx: &CompletionContext,
1919
existing_derives: &[ast::Path],
2020
) {
21-
let core = FamousDefs(&ctx.sema, ctx.krate).core();
21+
let core = ctx.famous_defs().core();
2222
let existing_derives: FxHashSet<_> = existing_derives
2323
.into_iter()
2424
.filter_map(|path| ctx.scope.speculative_resolve_as_mac(&path))

crates/ide_completion/src/completions/dot.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@ fn complete_methods(
7676
) {
7777
if let Some(krate) = ctx.krate {
7878
let mut seen_methods = FxHashSet::default();
79-
let traits_in_scope = ctx.scope.visible_traits();
79+
let mut traits_in_scope = ctx.scope.visible_traits();
80+
81+
// Remove drop from the environment as calling `Drop::drop` is not allowed
82+
if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
83+
cov_mark::hit!(dot_remove_drop_trait);
84+
traits_in_scope.remove(&drop_trait.into());
85+
}
86+
8087
receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
8188
if func.self_param(ctx.db).is_some() && seen_methods.insert(func.name(ctx.db)) {
8289
f(func);
@@ -709,4 +716,34 @@ fn main() {
709716
"#]],
710717
)
711718
}
719+
720+
#[test]
721+
fn postfix_drop_completion() {
722+
cov_mark::check!(dot_remove_drop_trait);
723+
cov_mark::check!(postfix_drop_completion);
724+
check_edit(
725+
"drop",
726+
r#"
727+
//- minicore: drop
728+
struct Vec<T>(T);
729+
impl<T> Drop for Vec<T> {
730+
fn drop(&mut self) {}
731+
}
732+
fn main() {
733+
let x = Vec(0u32)
734+
x.$0;
735+
}
736+
"#,
737+
r"
738+
struct Vec<T>(T);
739+
impl<T> Drop for Vec<T> {
740+
fn drop(&mut self) {}
741+
}
742+
fn main() {
743+
let x = Vec(0u32)
744+
drop($0x);
745+
}
746+
",
747+
)
748+
}
712749
}

crates/ide_completion/src/completions/postfix.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
33
mod format_like;
44

5-
use hir::Documentation;
5+
use hir::{Documentation, HasAttrs};
66
use ide_db::{
7-
helpers::{insert_use::ImportScope, FamousDefs, SnippetCap},
7+
helpers::{insert_use::ImportScope, SnippetCap},
88
ty_filter::TryEnum,
99
};
1010
use syntax::{
@@ -59,6 +59,22 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
5959
None => return,
6060
};
6161

62+
if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
63+
if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) {
64+
if let &[hir::AssocItem::Function(drop_fn)] = &*drop_trait.items(ctx.db) {
65+
cov_mark::hit!(postfix_drop_completion);
66+
// FIXME: check that `drop` is in scope, use fully qualified path if it isn't/if shadowed
67+
let mut item = postfix_snippet(
68+
"drop",
69+
"fn drop(&mut self)",
70+
&format!("drop($0{})", receiver_text),
71+
);
72+
item.set_documentation(drop_fn.docs(ctx.db));
73+
item.add_to(acc);
74+
}
75+
}
76+
}
77+
6278
if !ctx.config.snippets.is_empty() {
6379
add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
6480
}
@@ -107,7 +123,7 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
107123
)
108124
.add_to(acc);
109125
postfix_snippet("not", "!expr", &format!("!{}", receiver_text)).add_to(acc);
110-
} else if let Some(trait_) = FamousDefs(&ctx.sema, ctx.krate).core_iter_IntoIterator() {
126+
} else if let Some(trait_) = ctx.famous_defs().core_iter_IntoIterator() {
111127
if receiver_ty.impls_trait(ctx.db, trait_, &[]) {
112128
postfix_snippet(
113129
"for",

crates/ide_completion/src/completions/record.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Complete fields in record literals and patterns.
2-
use ide_db::{helpers::FamousDefs, SymbolKind};
2+
use ide_db::SymbolKind;
33
use syntax::{ast::Expr, T};
44

55
use crate::{
@@ -13,7 +13,7 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
1313
| ImmediateLocation::RecordExprUpdate(record_expr),
1414
) => {
1515
let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
16-
let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
16+
let default_trait = ctx.famous_defs().core_default_Default();
1717
let impl_default_trait = default_trait.zip(ty).map_or(false, |(default_trait, ty)| {
1818
ty.original.impls_trait(ctx.db, default_trait, &[])
1919
});

crates/ide_completion/src/context.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use hir::{Local, Name, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo};
55
use ide_db::{
66
active_parameter::ActiveParameter,
77
base_db::{FilePosition, SourceDatabase},
8+
helpers::FamousDefs,
89
RootDatabase,
910
};
1011
use syntax::{
@@ -150,6 +151,10 @@ impl<'a> CompletionContext<'a> {
150151
self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
151152
}
152153

154+
pub(crate) fn famous_defs(&self) -> FamousDefs {
155+
FamousDefs(&self.sema, self.krate)
156+
}
157+
153158
pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
154159
match &self.completion_location {
155160
Some(

crates/ide_completion/src/render.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ impl<'a> RenderContext<'a> {
7171
.unwrap_or(false)
7272
}
7373

74+
// FIXME: remove this
7475
fn docs(&self, def: impl HasAttrs) -> Option<hir::Documentation> {
7576
def.docs(self.db())
7677
}

crates/ide_db/src/helpers/famous_defs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ impl FamousDefs<'_, '_> {
7676
self.find_enum("core:ops:ControlFlow")
7777
}
7878

79+
pub fn core_ops_Drop(&self) -> Option<Trait> {
80+
self.find_trait("core:ops:Drop")
81+
}
82+
7983
pub fn core_marker_Copy(&self) -> Option<Trait> {
8084
self.find_trait("core:marker:Copy")
8185
}

crates/test_utils/src/minicore.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
//! bool_impl: option, fn
3737
//! add:
3838
//! as_ref: sized
39+
//! drop:
3940
4041
pub mod marker {
4142
// region:sized
@@ -118,7 +119,6 @@ pub mod clone {
118119
}
119120
// endregion:clone
120121

121-
122122
pub mod convert {
123123
// region:from
124124
pub trait From<T>: Sized {
@@ -195,6 +195,13 @@ pub mod ops {
195195
};
196196
// endregion:deref
197197

198+
// region:drop
199+
#[lang = "drop"]
200+
pub trait Drop {
201+
fn drop(&mut self);
202+
}
203+
// endregion:drop
204+
198205
// region:index
199206
mod index {
200207
#[lang = "index"]
@@ -237,6 +244,12 @@ pub mod ops {
237244
pub use self::index::{Index, IndexMut};
238245
// endregion:index
239246

247+
// region:drop
248+
pub mod mem {
249+
pub fn drop<T>(_x: T) {}
250+
}
251+
// endregion:drop
252+
240253
// region:range
241254
mod range {
242255
#[lang = "RangeFull"]
@@ -620,13 +633,15 @@ pub mod prelude {
620633
clone::Clone, // :clone
621634
cmp::{Eq, PartialEq}, // :eq
622635
cmp::{Ord, PartialOrd}, // :ord
623-
convert::{From, Into}, // :from
624636
convert::AsRef, // :as_ref
637+
convert::{From, Into}, // :from
625638
default::Default, // :default
626639
iter::{IntoIterator, Iterator}, // :iterator
627640
macros::builtin::derive, // :derive
628641
marker::Copy, // :copy
629642
marker::Sized, // :sized
643+
mem::drop, // :drop
644+
ops::Drop, // :drop
630645
ops::{Fn, FnMut, FnOnce}, // :fn
631646
option::Option::{self, None, Some}, // :option
632647
result::Result::{self, Err, Ok}, // :result

0 commit comments

Comments
 (0)