Repository: rust-lang/rust-analyzer
Pull request #12011 (2022-04-16 19:47:07)

fix: Show `impl Trait` in argument positon in completion details
Follow up for #11991 

`hir`: Use `db.callable_item_signature` query more.


Patch:
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 5aa1ca7e0b..382d1f9a54 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1389,15 +1389,15 @@ impl Function {
     }
 
     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 = db.trait_environment(self.id.into());
-        db.function_data(self.id)
-            .params
+        let substs = TyBuilder::placeholder_subst(db, self.id);
+        let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
+        callable_sig
+            .params()
             .iter()
             .enumerate()
-            .map(|(idx, (_, type_ref))| {
-                let ty = Type { env: environment.clone(), ty: ctx.lower_ty(type_ref) };
+            .map(|(idx, ty)| {
+                let ty = Type { env: environment.clone(), ty: ty.clone() };
                 Param { func: self, ty, idx }
             })
             .collect()
@@ -1411,17 +1411,17 @@ impl Function {
     }
 
     pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec<Param> {
-        let resolver = self.id.resolver(db.upcast());
-        let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let environment = db.trait_environment(self.id.into());
+        let substs = TyBuilder::placeholder_subst(db, self.id);
+        let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
         let skip = if db.function_data(self.id).has_self_param() { 1 } else { 0 };
-        db.function_data(self.id)
-            .params
+        callable_sig
+            .params()
             .iter()
             .enumerate()
             .skip(skip)
-            .map(|(idx, (_, type_ref))| {
-                let ty = Type { env: environment.clone(), ty: ctx.lower_ty(type_ref) };
+            .map(|(idx, ty)| {
+                let ty = Type { env: environment.clone(), ty: ty.clone() };
                 Param { func: self, ty, idx }
             })
             .collect()
@@ -1573,11 +1573,12 @@ impl SelfParam {
     }
 
     pub fn ty(&self, db: &dyn HirDatabase) -> Type {
-        let resolver = self.func.resolver(db.upcast());
-        let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
+        let substs = TyBuilder::placeholder_subst(db, self.func);
+        let callable_sig =
+            db.callable_item_signature(self.func.into()).substitute(Interner, &substs);
         let environment = db.trait_environment(self.func.into());
-
-        Type { env: environment, ty: ctx.lower_ty(&db.function_data(self.func).params[0].1) }
+        let ty = callable_sig.params()[0].clone();
+        Type { env: environment, ty }
     }
 }
 
@@ -2576,10 +2577,9 @@ impl Impl {
     }
 
     pub fn self_ty(self, db: &dyn HirDatabase) -> Type {
-        let impl_data = db.impl_data(self.id);
         let resolver = self.id.resolver(db.upcast());
-        let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
-        let ty = ctx.lower_ty(&impl_data.self_ty);
+        let substs = TyBuilder::placeholder_subst(db, self.id);
+        let ty = db.impl_self_ty(self.id).substitute(Interner, &substs);
         Type::new_with_resolver_inner(db, &resolver, ty)
     }
 
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index cfbd5f63bc..9fc3e30199 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -192,8 +192,7 @@ impl GlobalState {
                 if let Some(path) = vfs.file_path(file.file_id).as_path() {
                     let path = path.to_path_buf();
                     if reload::should_refresh_for_change(&path, file.change_kind) {
-                        self.fetch_workspaces_queue
-                            .request_op(format!("vfs file change: {}", path.display()));
+                        self.fetch_workspaces_queue.request_op();
                     }
                     fs_changes.push((path, file.change_kind));
                     if file.is_created_or_deleted() {
@@ -228,7 +227,7 @@ impl GlobalState {
                 let crates = raw_database.relevant_crates(file.file_id);
                 let crate_graph = raw_database.crate_graph();
 
-                crates.iter().any(|&krate| crate_graph[krate].is_proc_macro)
+                crates.iter().any(|&krate| !crate_graph[krate].is_proc_macro)
             });
         true
     }
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index e305fe408e..de44ba5e07 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -149,9 +149,9 @@ impl GlobalState {
             );
         }
 
-        self.fetch_workspaces_queue.request_op("startup".to_string());
-        if let Some(cause) = self.fetch_workspaces_queue.should_start_op() {
-            self.fetch_workspaces(cause);
+        self.fetch_workspaces_queue.request_op();
+        if self.fetch_workspaces_queue.should_start_op() {
+            self.fetch_workspaces();
         }
 
         while let Some(event) = self.next_event(&inbox) {
@@ -240,8 +240,7 @@ impl GlobalState {
                                     let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
 
                                     if self.config.run_build_scripts() && workspaces_updated {
-                                        self.fetch_build_data_queue
-                                            .request_op(format!("workspace updated"));
+                                        self.fetch_build_data_queue.request_op()
                                     }
 
                                     (Progress::End, None)
@@ -313,8 +312,7 @@ impl GlobalState {
 
                             self.prime_caches_queue.op_completed(());
                             if cancelled {
-                                self.prime_caches_queue
-                                    .request_op("restart after cancelation".to_string());
+                                self.prime_caches_queue.request_op();
                             }
                         }
                     };
@@ -445,7 +443,7 @@ impl GlobalState {
                     flycheck.update();
                 }
                 if self.config.prefill_caches() {
-                    self.prime_caches_queue.request_op("became quiescent".to_string());
+                    self.prime_caches_queue.request_op();
                 }
             }
 
@@ -495,15 +493,14 @@ impl GlobalState {
         }
 
         if self.config.cargo_autoreload() {
-            if let Some(cause) = self.fetch_workspaces_queue.should_start_op() {
-                self.fetch_workspaces(cause);
+            if self.fetch_workspaces_queue.should_start_op() {
+                self.fetch_workspaces();
             }
         }
-        if let Some(cause) = self.fetch_build_data_queue.should_start_op() {
-            self.fetch_build_data(cause);
+        if self.fetch_build_data_queue.should_start_op() {
+            self.fetch_build_data();
         }
-        if let Some(cause) = self.prime_caches_queue.should_start_op() {
-            tracing::debug!(%cause, "will prime caches");
+        if self.prime_caches_queue.should_start_op() {
             let num_worker_threads = self.config.prime_caches_num_threads();
 
             self.task_pool.handle.spawn_with_sender({
@@ -572,7 +569,7 @@ impl GlobalState {
 
         RequestDispatcher { req: Some(req), global_state: self }
             .on_sync_mut::<lsp_ext::ReloadWorkspace>(|s, ()| {
-                s.fetch_workspaces_queue.request_op("reload workspace request".to_string());
+                s.fetch_workspaces_queue.request_op();
                 Ok(())
             })?
             .on_sync_mut::<lsp_types::request::Shutdown>(|s, ()| {
@@ -717,7 +714,7 @@ impl GlobalState {
                 }
                 if let Ok(abs_path) = from_proto::abs_path(&params.text_document.uri) {
                     if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) {
-                        this.fetch_workspaces_queue.request_op(format!("DidSaveTextDocument {}", abs_path.display()));
+                        this.fetch_workspaces_queue.request_op();
                     }
                 }
                 Ok(())
diff --git a/crates/rust-analyzer/src/op_queue.rs b/crates/rust-analyzer/src/op_queue.rs
index 97aca01618..e2894b3ff2 100644
--- a/crates/rust-analyzer/src/op_queue.rs
+++ b/crates/rust-analyzer/src/op_queue.rs
@@ -1,30 +1,29 @@
 //! Bookkeeping to make sure only one long-running operation is being executed
 //! at a time.
 
-pub(crate) type Cause = String;
-
 pub(crate) struct OpQueue<Output> {
-    op_requested: Option<Cause>,
+    op_requested: bool,
     op_in_progress: bool,
     last_op_result: Output,
 }
 
 impl<Output: Default> Default for OpQueue<Output> {
     fn default() -> Self {
-        Self { op_requested: None, op_in_progress: false, last_op_result: Default::default() }
+        Self { op_requested: false, op_in_progress: false, last_op_result: Default::default() }
     }
 }
 
 impl<Output> OpQueue<Output> {
-    pub(crate) fn request_op(&mut self, reason: Cause) {
-        self.op_requested = Some(reason);
+    pub(crate) fn request_op(&mut self) {
+        self.op_requested = true;
     }
-    pub(crate) fn should_start_op(&mut self) -> Option<Cause> {
+    pub(crate) fn should_start_op(&mut self) -> bool {
         if self.op_in_progress {
-            return None;
+            return false;
         }
-        self.op_in_progress = self.op_requested.is_some();
-        self.op_requested.take()
+        self.op_in_progress = self.op_requested;
+        self.op_requested = false;
+        self.op_in_progress
     }
     pub(crate) fn op_completed(&mut self, result: Output) {
         assert!(self.op_in_progress);
@@ -39,6 +38,6 @@ impl<Output> OpQueue<Output> {
         self.op_in_progress
     }
     pub(crate) fn op_requested(&self) -> bool {
-        self.op_requested.is_some()
+        self.op_requested
     }
 }
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index d4e40d807d..5189d94eae 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -18,7 +18,6 @@ use crate::{
     global_state::GlobalState,
     lsp_ext,
     main_loop::Task,
-    op_queue::Cause,
 };
 
 #[derive(Debug)]
@@ -50,7 +49,7 @@ impl GlobalState {
             self.analysis_host.update_lru_capacity(self.config.lru_capacity());
         }
         if self.config.linked_projects() != old_config.linked_projects() {
-            self.fetch_workspaces_queue.request_op("linked projects changed".to_string())
+            self.fetch_workspaces_queue.request_op()
         } else if self.config.flycheck() != old_config.flycheck() {
             self.reload_flycheck();
         }
@@ -93,8 +92,8 @@ impl GlobalState {
         status
     }
 
-    pub(crate) fn fetch_workspaces(&mut self, cause: Cause) {
-        tracing::info!(%cause, "will fetch workspaces");
+    pub(crate) fn fetch_workspaces(&mut self) {
+        tracing::info!("will fetch workspaces");
 
         self.task_pool.handle.spawn_with_sender({
             let linked_projects = self.config.linked_projects();
@@ -145,8 +144,7 @@ impl GlobalState {
         });
     }
 
-    pub(crate) fn fetch_build_data(&mut self, cause: Cause) {
-        tracing::debug!(%cause, "will fetch build data");
+    pub(crate) fn fetch_build_data(&mut self) {
         let workspaces = Arc::clone(&self.workspaces);
         let config = self.config.cargo();
         self.task_pool.handle.spawn_with_sender(move |sender| {


Test patch:
diff --git a/crates/ide_completion/src/tests/expression.rs b/crates/ide_completion/src/tests/expression.rs
index 77296d9099..650c68134d 100644
--- a/crates/ide_completion/src/tests/expression.rs
+++ b/crates/ide_completion/src/tests/expression.rs
@@ -642,3 +642,23 @@ fn main() {
         "]],
     );
 }
+
+#[test]
+fn detail_impl_trait_in_argument_position() {
+    check_empty(
+        r"
+//- minicore: sized
+trait Trait<T> {}
+struct Foo;
+impl Foo {
+    fn bar<U>(_: impl Trait<U>) {}
+}
+fn main() {
+    Foo::$0
+}
+",
+        expect![[r"
+            fn bar(…) fn(impl Trait<U>)
+        "]],
+    );
+}