diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a880fa6713d..0007d7fa881 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -11,7 +11,6 @@ use hir_def::{ docs::Documentation, expr::{BindingAnnotation, Pat, PatId}, import_map, - item_tree::SelfParam, per_ns::PerNs, resolver::{HasResolver, Resolver}, src::HasSource as _, @@ -671,8 +670,8 @@ impl Function { db.function_data(self.id).name.clone() } - pub fn self_param(self, db: &dyn HirDatabase) -> Option { - db.function_data(self.id).self_param + pub fn has_self_param(self, db: &dyn HirDatabase) -> bool { + db.function_data(self.id).has_self_param } pub fn params(self, db: &dyn HirDatabase) -> Vec { diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 31f3241c9ed..34b02c5365f 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -49,7 +49,7 @@ pub use hir_def::{ docs::Documentation, nameres::ModuleSource, path::{ModPath, Path, PathKind}, - type_ref::Mutability, + type_ref::{Mutability, TypeRef}, }; pub use hir_expand::{ hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 2a26b0183e2..88a8ef9bffe 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -10,7 +10,7 @@ use crate::{ attr::Attrs, body::Expander, db::DefDatabase, - item_tree::{AssocItem, ItemTreeId, ModItem, SelfParam}, + item_tree::{AssocItem, ItemTreeId, ModItem}, type_ref::{TypeBound, TypeRef}, visibility::RawVisibility, AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, @@ -25,7 +25,7 @@ pub struct FunctionData { pub attrs: Attrs, /// True if the first param is `self`. This is relevant to decide whether this /// can be called as a method. - pub self_param: Option, + pub has_self_param: bool, pub is_unsafe: bool, pub is_varargs: bool, pub visibility: RawVisibility, @@ -42,7 +42,7 @@ impl FunctionData { params: func.params.to_vec(), ret_type: func.ret_type.clone(), attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), - self_param: func.self_param, + has_self_param: func.has_self_param, is_unsafe: func.is_unsafe, is_varargs: func.is_varargs, visibility: item_tree[func.visibility].clone(), diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index 1eaea66e4a3..a67e75dac06 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs @@ -500,7 +500,7 @@ pub struct Function { pub name: Name, pub visibility: RawVisibilityId, pub generic_params: GenericParamsId, - pub self_param: Option, + pub has_self_param: bool, pub is_unsafe: bool, pub params: Box<[TypeRef]>, pub is_varargs: bool, @@ -508,12 +508,6 @@ pub struct Function { pub ast_id: FileAstId, } -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct SelfParam { - pub is_ref: bool, - pub is_mut: bool, -} - #[derive(Debug, Clone, Eq, PartialEq)] pub struct Struct { pub name: Name, diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs index 89ad91d376f..450ef879814 100644 --- a/crates/ra_hir_def/src/item_tree/lower.rs +++ b/crates/ra_hir_def/src/item_tree/lower.rs @@ -283,7 +283,7 @@ impl Ctx { let name = func.name()?.as_name(); let mut params = Vec::new(); - let mut func_self_param = None; + let mut has_self_param = false; if let Some(param_list) = func.param_list() { if let Some(self_param) = param_list.self_param() { let self_type = match self_param.ty() { @@ -302,10 +302,7 @@ impl Ctx { } }; params.push(self_type); - func_self_param = Some(SelfParam { - is_ref: self_param.amp_token().is_some(), - is_mut: self_param.mut_token().is_some(), - }); + has_self_param = true; } for param in param_list.params() { let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty()); @@ -338,7 +335,7 @@ impl Ctx { name, visibility, generic_params: GenericParamsId::EMPTY, - self_param: func_self_param, + has_self_param, is_unsafe: func.unsafe_token().is_some(), params: params.into_boxed_slice(), is_varargs, diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 79c5adf0f1b..fb4b30a131f 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -640,7 +640,7 @@ fn is_valid_candidate( } } if let Some(receiver_ty) = receiver_ty { - if data.self_param.is_none() { + if !data.has_self_param { return false; } let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index 5488db43f72..5326652852f 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs @@ -48,7 +48,7 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T let mut seen_methods = FxHashSet::default(); let traits_in_scope = ctx.scope.traits_in_scope(); receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { - if func.self_param(ctx.db).is_some() + if func.has_self_param(ctx.db) && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m)) && seen_methods.insert(func.name(ctx.db)) { diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs index e3ba7ebc47f..d9a0ef167db 100644 --- a/crates/ra_ide/src/completion/complete_trait_impl.rs +++ b/crates/ra_ide/src/completion/complete_trait_impl.rs @@ -136,7 +136,7 @@ fn add_function_impl( .lookup_by(fn_name) .set_documentation(func.docs(ctx.db)); - let completion_kind = if func.self_param(ctx.db).is_some() { + let completion_kind = if func.has_self_param(ctx.db) { CompletionItemKind::Method } else { CompletionItemKind::Function diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index fc3d1a4bda4..9a94ff47671 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -191,7 +191,7 @@ impl Completions { func: hir::Function, local_name: Option, ) { - let has_self_param = func.self_param(ctx.db).is_some(); + let has_self_param = func.has_self_param(ctx.db); let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); let ast_node = func.source(ctx.db).value; diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 02b16b13c04..d5a5f69cca3 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -4,7 +4,7 @@ mod injection; #[cfg(test)] mod tests; -use hir::{Name, Semantics, VariantDef}; +use hir::{Name, Semantics, TypeRef, VariantDef}; use ra_ide_db::{ defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, RootDatabase, @@ -756,8 +756,13 @@ fn is_method_call_unsafe( } let func = sema.resolve_method_call(&method_call_expr)?; - if func.self_param(sema.db)?.is_ref { - Some(()) + if func.has_self_param(sema.db) { + let params = func.params(sema.db); + if matches!(params.into_iter().next(), Some(TypeRef::Reference(..))) { + Some(()) + } else { + None + } } else { None }