Unnamed repository; edit this file 'description' to name the repository.
-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 50da9ed06a..ba0a2c0224 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 46835ec04e..55c1431207 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 7a5d3d0859..db1e0ceaec 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 49b990172a..fb4c0c1269 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() {