]> git.lizzy.rs Git - rust.git/commitdiff
Type-safer API for dealing with parameter lists with optional self
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 1 Dec 2020 10:53:12 +0000 (13:53 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 1 Dec 2020 10:53:39 +0000 (13:53 +0300)
crates/completion/src/completions/trait_impl.rs
crates/completion/src/render/function.rs
crates/hir/src/code_model.rs
crates/ide/src/references/rename.rs

index a14be9c73b21f02e161645347f6e60f02af1660e..e2fe44aff9fa17cabc1b672527db33028e6d1aab 100644 (file)
@@ -139,7 +139,7 @@ fn add_function_impl(
 ) {
     let fn_name = func.name(ctx.db).to_string();
 
-    let label = if func.params(ctx.db).is_empty() {
+    let label = if func.assoc_fn_params(ctx.db).is_empty() {
         format!("fn {}()", fn_name)
     } else {
         format!("fn {}(..)", fn_name)
index 542383d7e77097eaee53ec3b052c57fde4bc675e..09d9f85bc0cd335e5c320249a9cd07b4422b9943 100644 (file)
@@ -22,7 +22,7 @@ pub(crate) fn render_fn<'a>(
 struct FunctionRender<'a> {
     ctx: RenderContext<'a>,
     name: String,
-    fn_: hir::Function,
+    func: hir::Function,
     ast_node: Fn,
 }
 
@@ -35,15 +35,15 @@ fn new(
         let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
         let ast_node = fn_.source(ctx.db()).value;
 
-        FunctionRender { ctx, name, fn_, ast_node }
+        FunctionRender { ctx, name, func: fn_, ast_node }
     }
 
     fn render(self, import_to_add: Option<ImportToAdd>) -> CompletionItem {
         let params = self.params();
         CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone())
             .kind(self.kind())
-            .set_documentation(self.ctx.docs(self.fn_))
-            .set_deprecated(self.ctx.is_deprecated(self.fn_))
+            .set_documentation(self.ctx.docs(self.func))
+            .set_deprecated(self.ctx.is_deprecated(self.func))
             .detail(self.detail())
             .add_call_parens(self.ctx.completion, self.name, params)
             .add_import(import_to_add)
@@ -67,7 +67,11 @@ fn add_arg(&self, arg: &str, ty: &Type) -> String {
     }
 
     fn params(&self) -> Params {
-        let params_ty = self.fn_.params(self.ctx.db());
+        let params_ty = if self.ctx.completion.dot_receiver.is_some() {
+            self.func.method_params(self.ctx.db()).unwrap_or_default()
+        } else {
+            self.func.assoc_fn_params(self.ctx.db())
+        };
         let params = self
             .ast_node
             .param_list()
@@ -87,7 +91,7 @@ fn params(&self) -> Params {
     }
 
     fn kind(&self) -> CompletionItemKind {
-        if self.fn_.self_param(self.ctx.db()).is_some() {
+        if self.func.self_param(self.ctx.db()).is_some() {
             CompletionItemKind::Method
         } else {
             CompletionItemKind::Function
index f06b5cd9f043fffcecaf76514dca332892b13a11..ba121104ba07cff22d1ec1876e3349899603d48f 100644 (file)
@@ -744,14 +744,13 @@ pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
         Some(SelfParam { func: self.id })
     }
 
-    pub fn params(self, db: &dyn HirDatabase) -> Vec<Param> {
+    pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
         let resolver = self.id.resolver(db.upcast());
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let environment = TraitEnvironment::lower(db, &resolver);
         db.function_data(self.id)
             .params
             .iter()
-            .skip(if self.self_param(db).is_some() { 1 } else { 0 })
             .map(|type_ref| {
                 let ty = Type {
                     krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate,
@@ -764,6 +763,14 @@ pub fn params(self, db: &dyn HirDatabase) -> Vec<Param> {
             })
             .collect()
     }
+    pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
+        if self.self_param(db).is_none() {
+            return None;
+        }
+        let mut res = self.assoc_fn_params(db);
+        res.remove(0);
+        Some(res)
+    }
 
     pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
         db.function_data(self.id).is_unsafe
index 73145769679b07e38464020adf57c2412a7c76e1..64fe8bd654cab8aa651982ecbeeeef733b6eb6a2 100644 (file)
@@ -241,7 +241,7 @@ fn rename_to_self(
         return Err(RenameError("Method already has a self parameter".to_string()));
     }
 
-    let params = fn_def.params(sema.db);
+    let params = fn_def.assoc_fn_params(sema.db);
     let first_param =
         params.first().ok_or_else(|| RenameError("Method has no parameters".into()))?;
     let first_param_ty = first_param.ty();