about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyan Mehri <ryan.mehri1@gmail.com>2023-10-09 08:30:34 -0700
committerLukas Wirth <lukastw97@gmail.com>2023-12-08 12:30:14 +0100
commit7e768cbe703188bb8c126d1be6960637795e4943 (patch)
treec1a264e60ef94d074ca3d121683eb3167167257f
parentf4349ff26ef0736ed6e37a7e491f01ee4c6a76a7 (diff)
downloadrust-7e768cbe703188bb8c126d1be6960637795e4943.tar.gz
rust-7e768cbe703188bb8c126d1be6960637795e4943.zip
fix: prefer keeping Self if it is in the same impl def
-rw-r--r--crates/hir-def/src/resolver.rs8
-rw-r--r--crates/hir/src/semantics.rs4
-rw-r--r--crates/ide-assists/src/handlers/generate_delegate_methods.rs19
-rw-r--r--crates/ide-db/src/path_transform.rs8
4 files changed, 28 insertions, 11 deletions
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 50da9ed06a0..ba0a2c0224a 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -588,6 +588,14 @@ impl Resolver {
             _ => None,
         })
     }
+
+    pub fn impl_def(&self) -> Option<ImplId> {
+        self.scopes().find_map(|scope| match scope {
+            Scope::ImplDefScope(def) => Some(*def),
+            _ => None,
+        })
+    }
+
     /// `expr_id` is required to be an expression id that comes after the top level expression scope in the given resolver
     #[must_use]
     pub fn update_to_inner_scope(
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 46835ec04e0..55c14312071 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -1556,6 +1556,10 @@ impl SemanticsScope<'_> {
     pub fn extern_crate_decls(&self) -> impl Iterator<Item = Name> + '_ {
         self.resolver.extern_crate_decls_in_scope(self.db.upcast())
     }
+
+    pub fn has_same_self_type(&self, other: &SemanticsScope<'_>) -> bool {
+        self.resolver.impl_def() == other.resolver.impl_def()
+    }
 }
 
 #[derive(Debug)]
diff --git a/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/crates/ide-assists/src/handlers/generate_delegate_methods.rs
index 7a5d3d0859c..db1e0ceaec1 100644
--- a/crates/ide-assists/src/handlers/generate_delegate_methods.rs
+++ b/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -1,6 +1,6 @@
 use std::collections::HashSet;
 
-use hir::{self, HasCrate, HasSource, HasVisibility};
+use hir::{self, HasCrate, HasVisibility};
 use ide_db::path_transform::PathTransform;
 use syntax::{
     ast::{
@@ -106,11 +106,8 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
             target,
             |edit| {
                 // Create the function
-                let method_source = match method.source(ctx.db()) {
-                    Some(source) => {
-                        ctx.sema.parse_or_expand(source.file_id);
-                        source.value
-                    }
+                let method_source = match ctx.sema.source(method) {
+                    Some(source) => source.value,
                     None => return,
                 };
                 let vis = method_source.visibility();
@@ -187,11 +184,11 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
                 let assoc_items = impl_def.get_or_create_assoc_item_list();
                 assoc_items.add_item(f.clone().into());
 
-                PathTransform::generic_transformation(
-                    &ctx.sema.scope(strukt.syntax()).unwrap(),
-                    &ctx.sema.scope(method_source.syntax()).unwrap(),
-                )
-                .apply(f.syntax());
+                if let Some((target, source)) =
+                    ctx.sema.scope(strukt.syntax()).zip(ctx.sema.scope(method_source.syntax()))
+                {
+                    PathTransform::generic_transformation(&target, &source).apply(f.syntax());
+                }
 
                 if let Some(cap) = ctx.config.snippet_cap {
                     edit.add_tabstop_before(cap, f)
diff --git a/crates/ide-db/src/path_transform.rs b/crates/ide-db/src/path_transform.rs
index 49b990172a5..fb4c0c12691 100644
--- a/crates/ide-db/src/path_transform.rs
+++ b/crates/ide-db/src/path_transform.rs
@@ -183,6 +183,7 @@ impl<'a> PathTransform<'a> {
             lifetime_substs,
             target_module,
             source_scope: self.source_scope,
+            same_self_type: self.target_scope.has_same_self_type(self.source_scope),
         };
         ctx.transform_default_values(defaulted_params);
         ctx
@@ -195,6 +196,7 @@ struct Ctx<'a> {
     lifetime_substs: FxHashMap<LifetimeName, ast::Lifetime>,
     target_module: hir::Module,
     source_scope: &'a SemanticsScope<'a>,
+    same_self_type: bool,
 }
 
 fn postorder(item: &SyntaxNode) -> impl Iterator<Item = SyntaxNode> {
@@ -333,6 +335,11 @@ impl Ctx<'_> {
                 }
             }
             hir::PathResolution::SelfType(imp) => {
+                // keep Self type if it does not need to be replaced
+                if self.same_self_type {
+                    return None;
+                }
+
                 let ty = imp.self_ty(self.source_scope.db);
                 let ty_str = &ty
                     .display_source_code(
@@ -349,6 +356,7 @@ impl Ctx<'_> {
                             self.source_scope.db.upcast(),
                             ModuleDef::from(adt),
                             false,
+                            true,
                         )?;
 
                         if let Some(qual) = mod_path_to_ast(&found_path).qualifier() {