Auto merge of #14948 - alibektas:14386, r=Veykril

feature : assist delegate impl

This PR ( fixes #14386 ) introduces a new IDE assist that generates a trait impl for a struct that delegates a field. This is a draft because the current `ide_db::path_transform::PathTransform` produces some unwanted results when it deals with extern crates, an example of which I attach as a GIF.

GIFs :
1. A general case
![14386-functional](https://github.com/rust-lang/rust-analyzer/assets/20956650/22114959-caa6-45ec-a154-b4b2f458f6b1)

2. A case where `ide_db::path_transform::PathTransform` fails to correctly resolve a property ( take `Allocator` as an example ) to its full path, thus causing an error to occur. ( Not to even mention that resolving this causes another error `use of unstable library feature 'allocator_api'` to occur
![14386-erroneous](https://github.com/rust-lang/rust-analyzer/assets/20956650/922ca715-594e-4168-a579-7c5c006f93aa)
This commit is contained in:
bors 2023-06-22 10:44:01 +00:00
commit f0e00ed599
3 changed files with 1114 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -145,6 +145,7 @@ mod handlers {
mod generate_constant;
mod generate_default_from_enum_variant;
mod generate_default_from_new;
mod generate_delegate_trait;
mod generate_deref;
mod generate_derive;
mod generate_documentation_template;
@ -251,6 +252,7 @@ pub(crate) fn all() -> &'static [Handler] {
generate_constant::generate_constant,
generate_default_from_enum_variant::generate_default_from_enum_variant,
generate_default_from_new::generate_default_from_new,
generate_delegate_trait::generate_delegate_trait,
generate_derive::generate_derive,
generate_documentation_template::generate_documentation_template,
generate_documentation_template::generate_doc_example,

View File

@ -1015,6 +1015,69 @@ impl Person {
)
}
#[test]
fn doctest_generate_delegate_trait() {
check_doc_test(
"generate_delegate_trait",
r#####"
trait SomeTrait {
type T;
fn fn_(arg: u32) -> u32;
fn method_(&mut self) -> bool;
}
struct A;
impl SomeTrait for A {
type T = u32;
fn fn_(arg: u32) -> u32 {
42
}
fn method_(&mut self) -> bool {
false
}
}
struct B {
a$0: A,
}
"#####,
r#####"
trait SomeTrait {
type T;
fn fn_(arg: u32) -> u32;
fn method_(&mut self) -> bool;
}
struct A;
impl SomeTrait for A {
type T = u32;
fn fn_(arg: u32) -> u32 {
42
}
fn method_(&mut self) -> bool {
false
}
}
struct B {
a: A,
}
impl SomeTrait for B {
type T = <A as SomeTrait>::T;
fn fn_(arg: u32) -> u32 {
<A as SomeTrait>::fn_(arg)
}
fn method_(&mut self) -> bool {
<A as SomeTrait>::method_( &mut self.a )
}
}
"#####,
)
}
#[test]
fn doctest_generate_deref() {
check_doc_test(