fix: prefer keeping Self if it is in the same impl def

This commit is contained in:
Ryan Mehri 2023-10-09 08:30:34 -07:00 committed by Lukas Wirth
parent f4349ff26e
commit 7e768cbe70
4 changed files with 28 additions and 11 deletions

View File

@ -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(

View File

@ -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)]

View File

@ -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)

View File

@ -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() {