about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide-assists/src/handlers/inline_call.rs148
1 files changed, 147 insertions, 1 deletions
diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs
index 4ba33ada48c..0af4248eb62 100644
--- a/crates/ide-assists/src/handlers/inline_call.rs
+++ b/crates/ide-assists/src/handlers/inline_call.rs
@@ -415,7 +415,24 @@ fn inline(
         let expr: &ast::Expr = expr;
 
         let mut insert_let_stmt = || {
-            let ty = sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty.clone());
+            let param_ty = match param_ty {
+                None => None,
+                Some(param_ty) => {
+                    if sema.hir_file_for(param_ty.syntax()).is_macro() {
+                        if let Some(param_ty) =
+                            ast::Type::cast(insert_ws_into(param_ty.syntax().clone()))
+                        {
+                            Some(param_ty)
+                        } else {
+                            Some(param_ty.clone_for_update())
+                        }
+                    } else {
+                        Some(param_ty.clone_for_update())
+                    }
+                }
+            };
+            let ty: Option<syntax::ast::Type> =
+                sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty);
 
             let is_self = param
                 .name(sema.db)
@@ -1735,4 +1752,133 @@ pub fn main() {
 "#,
         )
     }
+
+    #[test]
+    fn inline_call_with_reference_in_macros() {
+        check_assist(
+            inline_call,
+            r#"
+fn _write_u64(s: &mut u64, x: u64) {
+    *s += x;
+}
+macro_rules! impl_write {
+    ($(($ty:ident, $meth:ident),)*) => {$(
+        fn _hash(inner_self_: &u64, state: &mut u64) {
+            $meth(state, *inner_self_)
+        }
+    )*}
+}
+impl_write! { (u64, _write_u64), }
+fn _hash2(self_: &u64, state: &mut u64) {
+    $0_hash(&self_, state);
+}
+"#,
+            r#"
+fn _write_u64(s: &mut u64, x: u64) {
+    *s += x;
+}
+macro_rules! impl_write {
+    ($(($ty:ident, $meth:ident),)*) => {$(
+        fn _hash(inner_self_: &u64, state: &mut u64) {
+            $meth(state, *inner_self_)
+        }
+    )*}
+}
+impl_write! { (u64, _write_u64), }
+fn _hash2(self_: &u64, state: &mut u64) {
+    {
+        let inner_self_: &u64 = &self_;
+        let state: &mut u64 = state;
+      _write_u64(state, *inner_self_)
+    };
+}
+"#,
+        )
+    }
+
+    #[test]
+    fn inline_call_with_reference_in_macro_generated_trait_impl() {
+        check_assist(
+            inline_call,
+            r#"
+trait Hash2 {
+    fn hash2<H: Hasher2>(&self, state: &mut H);
+}
+
+trait Hasher2 {
+    fn write2_u64(&mut self, x: u64);
+}
+impl Hasher2 for u64 {
+    fn write2_u64(&mut self, x: u64) {
+        *self += x;
+    }
+}
+
+macro_rules! impl_write {
+    ($(($ty:ident, $meth:ident),)*) => {$(
+        impl Hash2 for $ty {
+            #[inline]
+            fn hash2<H: Hasher2>(&self, state: &mut H) {
+                state.$meth(*self)
+            }
+        }
+    )*}
+}
+
+impl_write! { (u64, write2_u64), }
+
+pub struct MyStruct {
+    value: u64,
+}
+
+impl Hash2 for MyStruct {
+    fn hash2<H: Hasher2>(&self, state: &mut H) {
+        self.value.$0hash2(state)
+    }
+}
+"#,
+            //
+            r#"
+trait Hash2 {
+    fn hash2<H: Hasher2>(&self, state: &mut H);
+}
+
+trait Hasher2 {
+    fn write2_u64(&mut self, x: u64);
+}
+impl Hasher2 for u64 {
+    fn write2_u64(&mut self, x: u64) {
+        *self += x;
+    }
+}
+
+macro_rules! impl_write {
+    ($(($ty:ident, $meth:ident),)*) => {$(
+        impl Hash2 for $ty {
+            #[inline]
+            fn hash2<H: Hasher2>(&self, state: &mut H) {
+                state.$meth(*self)
+            }
+        }
+    )*}
+}
+
+impl_write! { (u64, write2_u64), }
+
+pub struct MyStruct {
+    value: u64,
+}
+
+impl Hash2 for MyStruct {
+    fn hash2<H: Hasher2>(&self, state: &mut H) {
+        {
+            let this = &self.value;
+            let state: &mut H = state;
+          state.write2_u64(*this)
+        }
+    }
+}
+"#,
+        )
+    }
 }