fix: Do not complete Drop::drop
, complete std::mem::drop
instead
This commit is contained in:
parent
276687a6ee
commit
5360c9bd22
@ -1,7 +1,7 @@
|
||||
//! Completion for derives
|
||||
use hir::{HasAttrs, MacroDef, MacroKind};
|
||||
use ide_db::{
|
||||
helpers::{import_assets::ImportAssets, insert_use::ImportScope, FamousDefs},
|
||||
helpers::{import_assets::ImportAssets, insert_use::ImportScope},
|
||||
SymbolKind,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -18,7 +18,7 @@ pub(super) fn complete_derive(
|
||||
ctx: &CompletionContext,
|
||||
existing_derives: &[ast::Path],
|
||||
) {
|
||||
let core = FamousDefs(&ctx.sema, ctx.krate).core();
|
||||
let core = ctx.famous_defs().core();
|
||||
let existing_derives: FxHashSet<_> = existing_derives
|
||||
.into_iter()
|
||||
.filter_map(|path| ctx.scope.speculative_resolve_as_mac(&path))
|
||||
|
@ -76,7 +76,14 @@ fn complete_methods(
|
||||
) {
|
||||
if let Some(krate) = ctx.krate {
|
||||
let mut seen_methods = FxHashSet::default();
|
||||
let traits_in_scope = ctx.scope.visible_traits();
|
||||
let mut traits_in_scope = ctx.scope.visible_traits();
|
||||
|
||||
// Remove drop from the environment as calling `Drop::drop` is not allowed
|
||||
if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
|
||||
cov_mark::hit!(dot_remove_drop_trait);
|
||||
traits_in_scope.remove(&drop_trait.into());
|
||||
}
|
||||
|
||||
receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
|
||||
if func.self_param(ctx.db).is_some() && seen_methods.insert(func.name(ctx.db)) {
|
||||
f(func);
|
||||
@ -709,4 +716,34 @@ fn main() {
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn postfix_drop_completion() {
|
||||
cov_mark::check!(dot_remove_drop_trait);
|
||||
cov_mark::check!(postfix_drop_completion);
|
||||
check_edit(
|
||||
"drop",
|
||||
r#"
|
||||
//- minicore: drop
|
||||
struct Vec<T>(T);
|
||||
impl<T> Drop for Vec<T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
fn main() {
|
||||
let x = Vec(0u32)
|
||||
x.$0;
|
||||
}
|
||||
"#,
|
||||
r"
|
||||
struct Vec<T>(T);
|
||||
impl<T> Drop for Vec<T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
fn main() {
|
||||
let x = Vec(0u32)
|
||||
drop($0x);
|
||||
}
|
||||
",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
mod format_like;
|
||||
|
||||
use hir::Documentation;
|
||||
use hir::{Documentation, HasAttrs};
|
||||
use ide_db::{
|
||||
helpers::{insert_use::ImportScope, FamousDefs, SnippetCap},
|
||||
helpers::{insert_use::ImportScope, SnippetCap},
|
||||
ty_filter::TryEnum,
|
||||
};
|
||||
use syntax::{
|
||||
@ -59,6 +59,22 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
None => return,
|
||||
};
|
||||
|
||||
if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
|
||||
if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) {
|
||||
if let &[hir::AssocItem::Function(drop_fn)] = &*drop_trait.items(ctx.db) {
|
||||
cov_mark::hit!(postfix_drop_completion);
|
||||
// FIXME: check that `drop` is in scope, use fully qualified path if it isn't/if shadowed
|
||||
let mut item = postfix_snippet(
|
||||
"drop",
|
||||
"fn drop(&mut self)",
|
||||
&format!("drop($0{})", receiver_text),
|
||||
);
|
||||
item.set_documentation(drop_fn.docs(ctx.db));
|
||||
item.add_to(acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !ctx.config.snippets.is_empty() {
|
||||
add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
|
||||
}
|
||||
@ -107,7 +123,7 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
)
|
||||
.add_to(acc);
|
||||
postfix_snippet("not", "!expr", &format!("!{}", receiver_text)).add_to(acc);
|
||||
} else if let Some(trait_) = FamousDefs(&ctx.sema, ctx.krate).core_iter_IntoIterator() {
|
||||
} else if let Some(trait_) = ctx.famous_defs().core_iter_IntoIterator() {
|
||||
if receiver_ty.impls_trait(ctx.db, trait_, &[]) {
|
||||
postfix_snippet(
|
||||
"for",
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Complete fields in record literals and patterns.
|
||||
use ide_db::{helpers::FamousDefs, SymbolKind};
|
||||
use ide_db::SymbolKind;
|
||||
use syntax::{ast::Expr, T};
|
||||
|
||||
use crate::{
|
||||
@ -13,7 +13,7 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
|
||||
| ImmediateLocation::RecordExprUpdate(record_expr),
|
||||
) => {
|
||||
let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
|
||||
let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
|
||||
let default_trait = ctx.famous_defs().core_default_Default();
|
||||
let impl_default_trait = default_trait.zip(ty).map_or(false, |(default_trait, ty)| {
|
||||
ty.original.impls_trait(ctx.db, default_trait, &[])
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ use hir::{Local, Name, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo};
|
||||
use ide_db::{
|
||||
active_parameter::ActiveParameter,
|
||||
base_db::{FilePosition, SourceDatabase},
|
||||
helpers::FamousDefs,
|
||||
RootDatabase,
|
||||
};
|
||||
use syntax::{
|
||||
@ -150,6 +151,10 @@ impl<'a> CompletionContext<'a> {
|
||||
self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
|
||||
}
|
||||
|
||||
pub(crate) fn famous_defs(&self) -> FamousDefs {
|
||||
FamousDefs(&self.sema, self.krate)
|
||||
}
|
||||
|
||||
pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
|
||||
match &self.completion_location {
|
||||
Some(
|
||||
|
@ -71,6 +71,7 @@ impl<'a> RenderContext<'a> {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
// FIXME: remove this
|
||||
fn docs(&self, def: impl HasAttrs) -> Option<hir::Documentation> {
|
||||
def.docs(self.db())
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ impl FamousDefs<'_, '_> {
|
||||
self.find_enum("core:ops:ControlFlow")
|
||||
}
|
||||
|
||||
pub fn core_ops_Drop(&self) -> Option<Trait> {
|
||||
self.find_trait("core:ops:Drop")
|
||||
}
|
||||
|
||||
pub fn core_marker_Copy(&self) -> Option<Trait> {
|
||||
self.find_trait("core:marker:Copy")
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
//! bool_impl: option, fn
|
||||
//! add:
|
||||
//! as_ref: sized
|
||||
//! drop:
|
||||
|
||||
pub mod marker {
|
||||
// region:sized
|
||||
@ -118,7 +119,6 @@ pub mod clone {
|
||||
}
|
||||
// endregion:clone
|
||||
|
||||
|
||||
pub mod convert {
|
||||
// region:from
|
||||
pub trait From<T>: Sized {
|
||||
@ -195,6 +195,13 @@ pub mod ops {
|
||||
};
|
||||
// endregion:deref
|
||||
|
||||
// region:drop
|
||||
#[lang = "drop"]
|
||||
pub trait Drop {
|
||||
fn drop(&mut self);
|
||||
}
|
||||
// endregion:drop
|
||||
|
||||
// region:index
|
||||
mod index {
|
||||
#[lang = "index"]
|
||||
@ -237,6 +244,12 @@ pub mod ops {
|
||||
pub use self::index::{Index, IndexMut};
|
||||
// endregion:index
|
||||
|
||||
// region:drop
|
||||
pub mod mem {
|
||||
pub fn drop<T>(_x: T) {}
|
||||
}
|
||||
// endregion:drop
|
||||
|
||||
// region:range
|
||||
mod range {
|
||||
#[lang = "RangeFull"]
|
||||
@ -620,13 +633,15 @@ pub mod prelude {
|
||||
clone::Clone, // :clone
|
||||
cmp::{Eq, PartialEq}, // :eq
|
||||
cmp::{Ord, PartialOrd}, // :ord
|
||||
convert::{From, Into}, // :from
|
||||
convert::AsRef, // :as_ref
|
||||
convert::{From, Into}, // :from
|
||||
default::Default, // :default
|
||||
iter::{IntoIterator, Iterator}, // :iterator
|
||||
macros::builtin::derive, // :derive
|
||||
marker::Copy, // :copy
|
||||
marker::Sized, // :sized
|
||||
mem::drop, // :drop
|
||||
ops::Drop, // :drop
|
||||
ops::{Fn, FnMut, FnOnce}, // :fn
|
||||
option::Option::{self, None, Some}, // :option
|
||||
result::Result::{self, Err, Ok}, // :result
|
||||
|
Loading…
x
Reference in New Issue
Block a user