about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAli Bektas <bektasali@protonmail.com>2024-09-08 19:10:15 +0200
committerAli Bektas <bektasali@protonmail.com>2024-09-12 23:52:09 +0200
commitbd085df893d054c3dd8190dea089a82d40ea5e61 (patch)
tree627a8f59b67db1d8e5e55c6e98e441014d9a1389 /src
parentf16a03f3a96d5b82f30f46d979989ef3f529f031 (diff)
downloadrust-bd085df893d054c3dd8190dea089a82d40ea5e61.tar.gz
rust-bd085df893d054c3dd8190dea089a82d40ea5e61.zip
fix: Immutable tree panic in `generate_delegate_trait`
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs
index c22d19574fb..46ef1ff9292 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs
@@ -282,8 +282,11 @@ fn generate_impl(
                 ai.assoc_items()
                     .filter(|item| matches!(item, AssocItem::MacroCall(_)).not())
                     .for_each(|item| {
-                        let assoc =
-                            process_assoc_item(item, qualified_path_type.clone(), field_name);
+                        let assoc = process_assoc_item(
+                            item.clone_for_update(),
+                            qualified_path_type.clone(),
+                            field_name,
+                        );
                         if let Some(assoc) = assoc {
                             delegate_assoc_items.add_item(assoc);
                         }
@@ -1786,4 +1789,40 @@ impl T for B {
 "#,
         );
     }
+
+    #[test]
+    fn assoc_items_attributes_mutably_cloned() {
+        check_assist(
+            generate_delegate_trait,
+            r#"
+pub struct A;
+pub trait C<D> {
+    #[allow(clippy::dead_code)]
+    fn a_funk(&self) -> &D;
+}
+
+pub struct B<T: C<A>> {
+    has_dr$0ain: T,
+}
+"#,
+            r#"
+pub struct A;
+pub trait C<D> {
+    #[allow(clippy::dead_code)]
+    fn a_funk(&self) -> &D;
+}
+
+pub struct B<T: C<A>> {
+    has_drain: T,
+}
+
+impl<D, T: C<A>> C<D> for B<T> {
+    #[allow(clippy::dead_code)]
+    fn a_funk(&self) -> &D {
+        <T as C<D>>::a_funk(&self.has_drain)
+    }
+}
+"#,
+        )
+    }
 }