rust-analyzer/crates
bors 34df29620a Auto merge of #16112 - roife:rewrite-generate-delete-trait, r=Veykril
fix: rewrite code_action `generate_delegate_trait`

I've made substantial enhancements to the "generate delegate trait" code action in rust-analyzer. Here's a summary of the changes:

#### Resolved the "Can’t find CONST_ARG@158..159 in AstIdMap" error

Fix #15804, fix #15968, fix #15108

The issue stemmed from an incorrect application of PathTransform in the original code. Previously, a new 'impl' was generated first and then transformed, causing PathTransform to fail in locating the correct AST node, resulting in an error. I rectified this by performing the transformation before generating the new 'impl' (using make::impl_trait), ensuring a step-by-step transformation of associated items.

#### Rectified generation of `Self` type

`generate_delegate_trait` is unable to properly handle trait with `Self` type.

Let's take the following code as an example:

```rust
trait Trait {
    fn f() -> Self;
}

struct B {}
impl Trait for B {
    fn f() -> B { B{} }
}

struct S {
    b: B,
}
```

Here, if we implement `Trait` for `S`, the type of `f` should be `() -> Self`, i.e. `() -> S`. However we cannot automatically generate a function that constructs `S`.

To ensure that the code action doesn't generate delegate traits for traits with Self types, I add a function named `has_self_type` to handle it.

#### Extended support for generics in structs and fields within this code action

The former version of `generate_delegate_trait` cannot handle structs with generics properly. Here's an example:

```rust
struct B<T> {
    a: T
}

trait Trait<T> {
    fn f(a: T);
}

impl<T1, T2> Trait<T1> for B<T2> {
    fn f(a: T1) -> T2 { self.a }
}

struct A {}
struct S {
    b$0 : B<A>,
}
```

The former version  will generates improper code:

```rust
impl<T1, T2> Trait<T1, T2> for S {
    fn f(&self, a: T1) -> T1 {
        <B as Trait<T1, T2>>::f( &self.b , a)
    }
}
```

The rewritten version can handle generics properly:

```rust
impl<T1> Trait<T1> for S {
    fn f(&self, a: T1) -> T1 {
        <B<A> as Trait<T1>>::f(&self.b, a)
    }
}
```

See more examples in added unit tests.

I enabled support for generic structs in `generate_delegate_trait` through the following steps (using the code example provided):

1. Initially, to prevent conflicts between the generic parameters in struct `S` and the ones in the impl of `B`, I renamed the generic parameters of `S`.
2. Then, since `B`'s parameters are instantiated within `S`, the original generic parameters of `B` needed removal within `S` (to avoid errors from redundant parameters). An important consideration here arises when Trait and B share parameters in `B`'s impl. In such cases, these shared generic parameters cannot be removed.
3. Next, I addressed the matching of types between `B`'s type in `S` and its type in the impl. Given that some generic parameters in the impl are instantiated in `B`, I replaced these parameters with their instantiated results using PathTransform. For instance, in the example provided, matching `B<A>` and `B<T2>`, where `T2` is instantiated as `A`, I replaced all occurrences of `T2` in the impl with `A` (i.e. apply the instantiated generic arguments to the params).
4. Finally, I performed transformations on each assoc item (also to prevent the initial issue) and handled redundant where clauses.

For a more detailed explanation, please refer to the code and comments. I welcome suggestions and any further questions!
2024-01-02 12:30:19 +00:00
..
base-db Auto merge of #16178 - Veykril:builtin-fn-callsite, r=Veykril 2023-12-21 15:22:23 +00:00
cfg Remove Delimiter::DUMMY_INVISIBLE 2023-12-20 14:00:14 +01:00
flycheck internal: Move out WithFixture into dev-dep only crate 2023-12-18 15:24:08 +01:00
hir Auto merge of #16112 - roife:rewrite-generate-delete-trait, r=Veykril 2024-01-02 12:30:19 +00:00
hir-def internal: Cleanup Expander a bit 2023-12-22 13:01:13 +01:00
hir-expand fix: Fix SyntaxContextID using incorrect self IDs 2024-01-01 12:54:30 +01:00
hir-ty Auto merge of #16167 - Veykril:dummy-spans, r=Veykril 2023-12-20 13:33:36 +00:00
ide minor: Render more crate information in status command 2024-01-01 13:32:04 +01:00
ide-assists Auto merge of #16112 - roife:rewrite-generate-delete-trait, r=Veykril 2024-01-02 12:30:19 +00:00
ide-completion Auto merge of #16049 - dfireBird:followup-callable-fields, r=Veykril 2024-01-02 10:20:31 +00:00
ide-db Auto merge of #16112 - roife:rewrite-generate-delete-trait, r=Veykril 2024-01-02 12:30:19 +00:00
ide-diagnostics add test case for negative impl 2023-12-24 20:07:33 +08:00
ide-ssr internal: Move out WithFixture into dev-dep only crate 2023-12-18 15:24:08 +01:00
intern internal: Move out WithFixture into dev-dep only crate 2023-12-18 15:24:08 +01:00
limit Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
load-cargo internal: Move out WithFixture into dev-dep only crate 2023-12-18 15:24:08 +01:00
mbe Auto merge of #16167 - Veykril:dummy-spans, r=Veykril 2023-12-20 13:33:36 +00:00
parser Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
paths Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
proc-macro-api More general server config message for proc-macro-api 2023-12-22 10:35:10 +01:00
proc-macro-srv Special case fixup spans in server::Span impl, they are immutable 2023-12-22 10:13:00 +01:00
proc-macro-srv-cli More general server config message for proc-macro-api 2023-12-22 10:35:10 +01:00
profile Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
project-model Auto merge of #16165 - Veykril:meta-vars, r=Veykril 2023-12-20 10:30:58 +00:00
rust-analyzer Auto merge of #16062 - davidbarsky:david/fix-references-to-removed-settings, r=Veykril 2024-01-02 09:57:48 +00:00
rustc-dependencies Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
sourcegen Don't auto-publish sourcegen 2023-12-18 15:54:01 +02:00
span Special case fixup spans in server::Span impl, they are immutable 2023-12-22 10:13:00 +01:00
stdx Auto merge of #118817 - lnicola:sync-from-ra, r=lnicola 2023-12-12 08:22:37 +00:00
syntax Auto merge of #16112 - roife:rewrite-generate-delete-trait, r=Veykril 2024-01-02 12:30:19 +00:00
test-fixture Try to support pre and post-change metavars 2023-12-19 20:45:12 +01:00
test-utils fix: Fix span marking for builtin fn macros 2023-12-21 16:20:27 +01:00
text-edit Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
toolchain Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00
tt Remove SyntaxContext trait 2023-12-20 14:02:40 +01:00
vfs internal: Move out WithFixture into dev-dep only crate 2023-12-18 15:24:08 +01:00
vfs-notify Merge commit '457b966b17' into sync-from-ra 2023-12-11 11:16:01 +02:00