From 0e3fd8830ef4c3716c55913d5d39da5fba04ec84 Mon Sep 17 00:00:00 2001
From: xizheyin <xizheyin@smail.nju.edu.cn>
Date: Sat, 5 Apr 2025 12:12:01 +0800
Subject: [PATCH 1/2] Add ui test

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
---
 .../suggest-in-extern-macro-issue-139253.rs   | 18 +++++++++++
 ...uggest-in-extern-macro-issue-139253.stderr | 30 +++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 tests/ui/macros/suggest-in-extern-macro-issue-139253.rs
 create mode 100644 tests/ui/macros/suggest-in-extern-macro-issue-139253.stderr

diff --git a/tests/ui/macros/suggest-in-extern-macro-issue-139253.rs b/tests/ui/macros/suggest-in-extern-macro-issue-139253.rs
new file mode 100644
index 00000000000..1532eaf7e58
--- /dev/null
+++ b/tests/ui/macros/suggest-in-extern-macro-issue-139253.rs
@@ -0,0 +1,18 @@
+#[derive(Clone, Debug)]
+struct Point<T> {
+    v: T,
+}
+
+macro_rules! local_macro {
+    ($val:expr $(,)?) => {
+        match $val {
+            tmp => tmp, //~ ERROR mismatched types [E0308]
+        }
+    };
+}
+
+fn main() {
+    let a: Point<u8> = dbg!(Point { v: 42 });
+    let b: Point<u8> = dbg!(&a); //~ ERROR mismatched types [E0308]
+    let c: Point<u8> = local_macro!(&a);
+}
diff --git a/tests/ui/macros/suggest-in-extern-macro-issue-139253.stderr b/tests/ui/macros/suggest-in-extern-macro-issue-139253.stderr
new file mode 100644
index 00000000000..469066b3e8c
--- /dev/null
+++ b/tests/ui/macros/suggest-in-extern-macro-issue-139253.stderr
@@ -0,0 +1,30 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-in-extern-macro-issue-139253.rs:16:24
+   |
+LL |     let b: Point<u8> = dbg!(&a);
+   |                        ^^^^^^^^ expected `Point<u8>`, found `&Point<u8>`
+   |
+   = note: expected struct `Point<_>`
+           found reference `&Point<_>`
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-in-extern-macro-issue-139253.rs:9:20
+   |
+LL |             tmp => tmp,
+   |                    ^^^ expected `Point<u8>`, found `&Point<u8>`
+...
+LL |     let c: Point<u8> = local_macro!(&a);
+   |                        ---------------- in this macro invocation
+   |
+   = note: expected struct `Point<_>`
+           found reference `&Point<_>`
+   = note: this error originates in the macro `local_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider using clone here
+   |
+LL |             tmp => tmp.clone(),
+   |                       ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.

From 73e10eaf96ee2b4c0727013783cb9a2c06af66ae Mon Sep 17 00:00:00 2001
From: xizheyin <xizheyin@smail.nju.edu.cn>
Date: Sat, 5 Apr 2025 12:16:59 +0800
Subject: [PATCH 2/2] Suppress the clone_for_ref suggestion in extern macro

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
---
 compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 264719ca569..d4726e111ff 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1263,7 +1263,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
     ) -> bool {
-        if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind()
+        if !expr.span.in_external_macro(self.tcx.sess.source_map())
+            && let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind()
             && let Some(clone_trait_def) = self.tcx.lang_items().clone_trait()
             && expected_ty == *inner_ty
             && self