From 52167e04e62a84fe5073c4074733c72f96961ace Mon Sep 17 00:00:00 2001
From: Mu001999 <mu001999@outlook.com>
Date: Sat, 14 Jun 2025 12:05:19 +0800
Subject: [PATCH] Marks ADT live if it appears in pattern

---
 compiler/rustc_passes/src/dead.rs             | 78 +++++++------------
 library/core/src/default.rs                   |  1 -
 tests/incremental/track-deps-in-new-solver.rs |  2 +
 .../ui/const-generics/issues/issue-86535-2.rs |  2 +-
 .../issues/issue-86535-2.stderr               | 10 +++
 tests/ui/const-generics/issues/issue-86535.rs |  2 +-
 .../const-generics/issues/issue-86535.stderr  | 10 +++
 tests/ui/derives/clone-debug-dead-code.stderr |  2 +-
 .../impl-trait/extra-impl-in-trait-impl.fixed |  1 +
 .../ui/impl-trait/extra-impl-in-trait-impl.rs |  1 +
 .../extra-impl-in-trait-impl.stderr           |  8 +-
 tests/ui/lint/dead-code/issue-41883.stderr    |  2 -
 tests/ui/lint/dead-code/issue-59003.rs        |  2 +-
 .../lint-unused-adt-appeared-in-pattern.rs    | 37 +++++++++
 ...lint-unused-adt-appeared-in-pattern.stderr | 20 +++++
 ...tiple-dead-codes-in-the-same-struct.stderr |  2 -
 ...nt-adt-appeared-in-pattern-issue-120770.rs | 32 ++++++++
 ...sed-adt-impl-pub-trait-with-assoc-const.rs |  2 +-
 ...adt-impl-pub-trait-with-assoc-const.stderr |  8 +-
 .../dead-code/unused-struct-derive-default.rs |  1 +
 .../unused-struct-derive-default.stderr       |  1 -
 tests/ui/parser/issues/issue-105366.fixed     |  1 +
 tests/ui/parser/issues/issue-105366.rs        |  1 +
 tests/ui/parser/issues/issue-105366.stderr    |  2 +-
 24 files changed, 161 insertions(+), 67 deletions(-)
 create mode 100644 tests/ui/const-generics/issues/issue-86535-2.stderr
 create mode 100644 tests/ui/const-generics/issues/issue-86535.stderr
 create mode 100644 tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs
 create mode 100644 tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr
 create mode 100644 tests/ui/lint/dead-code/not-lint-adt-appeared-in-pattern-issue-120770.rs

diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 4257d8e8d16bd..4738036318d30 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -234,7 +234,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         pats: &[hir::PatField<'_>],
     ) {
         let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
-            ty::Adt(adt, _) => adt.variant_of_res(res),
+            ty::Adt(adt, _) => {
+                // Marks the ADT live if its variant appears as the pattern,
+                // considering cases when we have `let T(x) = foo()` and `fn foo<T>() -> T;`,
+                // we will lose the liveness info of `T` cause we cannot mark it live when visiting `foo`.
+                // Related issue: https://github.com/rust-lang/rust/issues/120770
+                self.check_def_id(adt.did());
+                adt.variant_of_res(res)
+            }
             _ => span_bug!(lhs.span, "non-ADT in struct pattern"),
         };
         for pat in pats {
@@ -254,7 +261,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         dotdot: hir::DotDotPos,
     ) {
         let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
-            ty::Adt(adt, _) => adt.variant_of_res(res),
+            ty::Adt(adt, _) => {
+                // Marks the ADT live if its variant appears as the pattern
+                self.check_def_id(adt.did());
+                adt.variant_of_res(res)
+            }
             _ => {
                 self.tcx.dcx().span_delayed_bug(lhs.span, "non-ADT in tuple struct pattern");
                 return;
@@ -359,31 +370,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 return false;
             }
 
-            // don't ignore impls for Enums and pub Structs whose methods don't have self receiver,
-            // cause external crate may call such methods to construct values of these types
-            if let Some(local_impl_of) = impl_of.as_local()
-                && let Some(local_def_id) = def_id.as_local()
-                && let Some(fn_sig) =
-                    self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
-                && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
-                && let TyKind::Path(QPath::Resolved(_, path)) =
-                    self.tcx.hir_expect_item(local_impl_of).expect_impl().self_ty.kind
-                && let Res::Def(def_kind, did) = path.res
-            {
-                match def_kind {
-                    // for example, #[derive(Default)] pub struct T(i32);
-                    // external crate can call T::default() to construct T,
-                    // so that don't ignore impl Default for pub Enum and Structs
-                    DefKind::Struct | DefKind::Union if self.tcx.visibility(did).is_public() => {
-                        return false;
-                    }
-                    // don't ignore impl Default for Enums,
-                    // cause we don't know which variant is constructed
-                    DefKind::Enum => return false,
-                    _ => (),
-                };
-            }
-
             if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
                 && self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
             {
@@ -494,38 +480,25 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         impl_id: hir::ItemId,
         local_def_id: LocalDefId,
     ) -> bool {
-        if self.should_ignore_item(local_def_id.to_def_id()) {
-            return false;
-        }
-
         let trait_def_id = match self.tcx.def_kind(local_def_id) {
             // assoc impl items of traits are live if the corresponding trait items are live
-            DefKind::AssocFn => self.tcx.associated_item(local_def_id).trait_item_def_id,
+            DefKind::AssocFn => self
+                .tcx
+                .associated_item(local_def_id)
+                .trait_item_def_id
+                .and_then(|def_id| def_id.as_local()),
             // impl items are live if the corresponding traits are live
             DefKind::Impl { of_trait: true } => self
                 .tcx
                 .impl_trait_ref(impl_id.owner_id.def_id)
-                .and_then(|trait_ref| Some(trait_ref.skip_binder().def_id)),
+                .and_then(|trait_ref| trait_ref.skip_binder().def_id.as_local()),
             _ => None,
         };
 
-        if let Some(trait_def_id) = trait_def_id {
-            if let Some(trait_def_id) = trait_def_id.as_local()
-                && !self.live_symbols.contains(&trait_def_id)
-            {
-                return false;
-            }
-
-            // FIXME: legacy logic to check whether the function may construct `Self`,
-            // this can be removed after supporting marking ADTs appearing in patterns
-            // as live, then we can check private impls of public traits directly
-            if let Some(fn_sig) =
-                self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
-                && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
-                && self.tcx.visibility(trait_def_id).is_public()
-            {
-                return true;
-            }
+        if let Some(trait_def_id) = trait_def_id
+            && !self.live_symbols.contains(&trait_def_id)
+        {
+            return false;
         }
 
         // The impl or impl item is used if the corresponding trait or trait item is used and the ty is used.
@@ -635,6 +608,11 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
     fn visit_pat_expr(&mut self, expr: &'tcx rustc_hir::PatExpr<'tcx>) {
         match &expr.kind {
             rustc_hir::PatExprKind::Path(qpath) => {
+                // mark the type of variant live when meeting E::V in expr
+                if let ty::Adt(adt, _) = self.typeck_results().node_type(expr.hir_id).kind() {
+                    self.check_def_id(adt.did());
+                }
+
                 let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
                 self.handle_res(res);
             }
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 044997a81a9a2..0a15cedfb552d 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -103,7 +103,6 @@ use crate::ascii::Char as AsciiChar;
 /// ```
 #[rustc_diagnostic_item = "Default"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_trivial_field_reads]
 pub trait Default: Sized {
     /// Returns the "default value" for a type.
     ///
diff --git a/tests/incremental/track-deps-in-new-solver.rs b/tests/incremental/track-deps-in-new-solver.rs
index fb013b2b24a7c..51cd6b89e37e5 100644
--- a/tests/incremental/track-deps-in-new-solver.rs
+++ b/tests/incremental/track-deps-in-new-solver.rs
@@ -3,6 +3,8 @@
 //@ compile-flags: -Znext-solver
 //@ check-pass
 
+#![allow(dead_code)]
+
 pub trait Future {
     type Error;
     fn poll() -> Self::Error;
diff --git a/tests/ui/const-generics/issues/issue-86535-2.rs b/tests/ui/const-generics/issues/issue-86535-2.rs
index 8d064f3eeb1b7..5c9132fe54d3d 100644
--- a/tests/ui/const-generics/issues/issue-86535-2.rs
+++ b/tests/ui/const-generics/issues/issue-86535-2.rs
@@ -9,7 +9,7 @@ pub trait Foo {
         [(); Self::ASSOC_C]:;
 }
 
-struct Bar<const N: &'static ()>;
+struct Bar<const N: &'static ()>; //~ WARN struct `Bar` is never constructed
 impl<const N: &'static ()> Foo for Bar<N> {
     const ASSOC_C: usize = 3;
 
diff --git a/tests/ui/const-generics/issues/issue-86535-2.stderr b/tests/ui/const-generics/issues/issue-86535-2.stderr
new file mode 100644
index 0000000000000..0ba748365754c
--- /dev/null
+++ b/tests/ui/const-generics/issues/issue-86535-2.stderr
@@ -0,0 +1,10 @@
+warning: struct `Bar` is never constructed
+  --> $DIR/issue-86535-2.rs:12:8
+   |
+LL | struct Bar<const N: &'static ()>;
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/const-generics/issues/issue-86535.rs b/tests/ui/const-generics/issues/issue-86535.rs
index 62454f4a388a0..2cdf801c1561c 100644
--- a/tests/ui/const-generics/issues/issue-86535.rs
+++ b/tests/ui/const-generics/issues/issue-86535.rs
@@ -2,7 +2,7 @@
 #![feature(adt_const_params, unsized_const_params, generic_const_exprs)]
 #![allow(incomplete_features, unused_variables)]
 
-struct F<const S: &'static str>;
+struct F<const S: &'static str>; //~ WARN struct `F` is never constructed
 impl<const S: &'static str> X for F<{ S }> {
     const W: usize = 3;
 
diff --git a/tests/ui/const-generics/issues/issue-86535.stderr b/tests/ui/const-generics/issues/issue-86535.stderr
new file mode 100644
index 0000000000000..84d6c1c11ff6a
--- /dev/null
+++ b/tests/ui/const-generics/issues/issue-86535.stderr
@@ -0,0 +1,10 @@
+warning: struct `F` is never constructed
+  --> $DIR/issue-86535.rs:5:8
+   |
+LL | struct F<const S: &'static str>;
+   |        ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/derives/clone-debug-dead-code.stderr b/tests/ui/derives/clone-debug-dead-code.stderr
index 34b7f929ec5ec..38be486e33207 100644
--- a/tests/ui/derives/clone-debug-dead-code.stderr
+++ b/tests/ui/derives/clone-debug-dead-code.stderr
@@ -40,7 +40,7 @@ LL | struct D { f: () }
    |        |
    |        field in this struct
    |
-   = note: `D` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis
+   = note: `D` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
 
 error: field `f` is never read
   --> $DIR/clone-debug-dead-code.rs:21:12
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
index 886fc1d005802..d8eceeff67888 100644
--- a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
@@ -1,5 +1,6 @@
 //@ run-rustfix
 
+#![allow(dead_code)]
 struct S<T>(T);
 struct S2;
 
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
index f3271993867cb..c2e511c0d055b 100644
--- a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
@@ -1,5 +1,6 @@
 //@ run-rustfix
 
+#![allow(dead_code)]
 struct S<T>(T);
 struct S2;
 
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
index 5aafc8b64d4ff..22e68463a8cfb 100644
--- a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
@@ -1,23 +1,23 @@
 error: unexpected `impl` keyword
-  --> $DIR/extra-impl-in-trait-impl.rs:6:18
+  --> $DIR/extra-impl-in-trait-impl.rs:7:18
    |
 LL | impl<T: Default> impl Default for S<T> {
    |                  ^^^^^ help: remove the extra `impl`
    |
 note: this is parsed as an `impl Trait` type, but a trait is expected at this position
-  --> $DIR/extra-impl-in-trait-impl.rs:6:18
+  --> $DIR/extra-impl-in-trait-impl.rs:7:18
    |
 LL | impl<T: Default> impl Default for S<T> {
    |                  ^^^^^^^^^^^^
 
 error: unexpected `impl` keyword
-  --> $DIR/extra-impl-in-trait-impl.rs:12:6
+  --> $DIR/extra-impl-in-trait-impl.rs:13:6
    |
 LL | impl impl Default for S2 {
    |      ^^^^^ help: remove the extra `impl`
    |
 note: this is parsed as an `impl Trait` type, but a trait is expected at this position
-  --> $DIR/extra-impl-in-trait-impl.rs:12:6
+  --> $DIR/extra-impl-in-trait-impl.rs:13:6
    |
 LL | impl impl Default for S2 {
    |      ^^^^^^^^^^^^
diff --git a/tests/ui/lint/dead-code/issue-41883.stderr b/tests/ui/lint/dead-code/issue-41883.stderr
index cf079e4dda33a..47ccef9a53069 100644
--- a/tests/ui/lint/dead-code/issue-41883.stderr
+++ b/tests/ui/lint/dead-code/issue-41883.stderr
@@ -29,8 +29,6 @@ error: struct `UnusedStruct` is never constructed
    |
 LL |     struct UnusedStruct;
    |            ^^^^^^^^^^^^
-   |
-   = note: `UnusedStruct` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/lint/dead-code/issue-59003.rs b/tests/ui/lint/dead-code/issue-59003.rs
index e3dcaca577889..319cf2db1495f 100644
--- a/tests/ui/lint/dead-code/issue-59003.rs
+++ b/tests/ui/lint/dead-code/issue-59003.rs
@@ -4,8 +4,8 @@
 
 #![deny(dead_code)]
 
+#[allow(dead_code)]
 struct Foo {
-    #[allow(dead_code)]
     inner: u32,
 }
 
diff --git a/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs
new file mode 100644
index 0000000000000..25777438456b6
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs
@@ -0,0 +1,37 @@
+#![deny(dead_code)]
+
+struct Foo(u8); //~ ERROR struct `Foo` is never constructed
+
+enum Bar { //~ ERROR enum `Bar` is never used
+    Var1(u8),
+    Var2(u8),
+}
+
+pub trait Tr1 {
+    fn f1() -> Self;
+}
+
+impl Tr1 for Foo {
+    fn f1() -> Foo {
+        let f = Foo(0);
+        let Foo(tag) = f;
+        Foo(tag)
+    }
+}
+
+impl Tr1 for Bar {
+    fn f1() -> Bar {
+        let b = Bar::Var1(0);
+        let b = if let Bar::Var1(_) = b {
+            Bar::Var1(0)
+        } else {
+            Bar::Var2(0)
+        };
+        match b {
+            Bar::Var1(_) => Bar::Var2(0),
+            Bar::Var2(_) => Bar::Var1(0),
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr
new file mode 100644
index 0000000000000..7c1a4b4597755
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr
@@ -0,0 +1,20 @@
+error: struct `Foo` is never constructed
+  --> $DIR/lint-unused-adt-appeared-in-pattern.rs:3:8
+   |
+LL | struct Foo(u8);
+   |        ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-adt-appeared-in-pattern.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: enum `Bar` is never used
+  --> $DIR/lint-unused-adt-appeared-in-pattern.rs:5:6
+   |
+LL | enum Bar {
+   |      ^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
index b992005318f2e..25a7d96cb8978 100644
--- a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
@@ -56,8 +56,6 @@ warning: struct `Foo` is never constructed
    |
 LL | struct Foo(usize, #[allow(unused)] usize);
    |        ^^^
-   |
-   = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
 
 error: aborting due to 2 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/lint/dead-code/not-lint-adt-appeared-in-pattern-issue-120770.rs b/tests/ui/lint/dead-code/not-lint-adt-appeared-in-pattern-issue-120770.rs
new file mode 100644
index 0000000000000..43a2e43190433
--- /dev/null
+++ b/tests/ui/lint/dead-code/not-lint-adt-appeared-in-pattern-issue-120770.rs
@@ -0,0 +1,32 @@
+//@ check-pass
+
+#![deny(dead_code)]
+
+#[repr(u8)]
+#[derive(Copy, Clone, Debug)]
+pub enum RecordField {
+    Target = 1,
+    Level,
+    Module,
+    File,
+    Line,
+    NumArgs,
+}
+
+unsafe trait Pod {}
+
+#[repr(transparent)]
+struct RecordFieldWrapper(RecordField);
+
+unsafe impl Pod for RecordFieldWrapper {}
+
+fn try_read<T: Pod>(buf: &[u8]) -> T {
+    unsafe { std::ptr::read_unaligned(buf.as_ptr() as *const T) }
+}
+
+pub fn foo(buf: &[u8]) -> RecordField {
+    let RecordFieldWrapper(tag) = try_read(buf);
+    tag
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs
index 5b755d62a0598..415eb4138defe 100644
--- a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs
+++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs
@@ -2,7 +2,7 @@
 
 struct T1; //~ ERROR struct `T1` is never constructed
 pub struct T2(i32); //~ ERROR field `0` is never read
-struct T3;
+struct T3; //~ ERROR struct `T3` is never constructed
 
 trait Trait1 { //~ ERROR trait `Trait1` is never used
     const UNUSED: i32;
diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr
index 2441a3f868dc2..778dadee153f0 100644
--- a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr
+++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr
@@ -20,11 +20,17 @@ LL | pub struct T2(i32);
    |
    = help: consider removing this field
 
+error: struct `T3` is never constructed
+  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:5:8
+   |
+LL | struct T3;
+   |        ^^
+
 error: trait `Trait1` is never used
   --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7
    |
 LL | trait Trait1 {
    |       ^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.rs b/tests/ui/lint/dead-code/unused-struct-derive-default.rs
index 330ad32dd5709..f20b7cb66ee51 100644
--- a/tests/ui/lint/dead-code/unused-struct-derive-default.rs
+++ b/tests/ui/lint/dead-code/unused-struct-derive-default.rs
@@ -22,4 +22,5 @@ pub struct T2 {
 
 fn main() {
     let _x: Used = Default::default();
+    let _e: E = Default::default();
 }
diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.stderr b/tests/ui/lint/dead-code/unused-struct-derive-default.stderr
index bbb0bd7be7064..7422f9a39f312 100644
--- a/tests/ui/lint/dead-code/unused-struct-derive-default.stderr
+++ b/tests/ui/lint/dead-code/unused-struct-derive-default.stderr
@@ -4,7 +4,6 @@ error: struct `T` is never constructed
 LL | struct T;
    |        ^
    |
-   = note: `T` has a derived impl for the trait `Default`, but this is intentionally ignored during dead code analysis
 note: the lint level is defined here
   --> $DIR/unused-struct-derive-default.rs:1:9
    |
diff --git a/tests/ui/parser/issues/issue-105366.fixed b/tests/ui/parser/issues/issue-105366.fixed
index 7157b647524dd..95419dc07f2cc 100644
--- a/tests/ui/parser/issues/issue-105366.fixed
+++ b/tests/ui/parser/issues/issue-105366.fixed
@@ -1,5 +1,6 @@
 //@ run-rustfix
 
+#[allow(dead_code)]
 struct Foo;
 
 impl From<i32> for Foo {
diff --git a/tests/ui/parser/issues/issue-105366.rs b/tests/ui/parser/issues/issue-105366.rs
index dc3cb8b343d32..3278b73799125 100644
--- a/tests/ui/parser/issues/issue-105366.rs
+++ b/tests/ui/parser/issues/issue-105366.rs
@@ -1,5 +1,6 @@
 //@ run-rustfix
 
+#[allow(dead_code)]
 struct Foo;
 
 fn From<i32> for Foo {
diff --git a/tests/ui/parser/issues/issue-105366.stderr b/tests/ui/parser/issues/issue-105366.stderr
index d8c79a0e0eaf6..225e436b4aa84 100644
--- a/tests/ui/parser/issues/issue-105366.stderr
+++ b/tests/ui/parser/issues/issue-105366.stderr
@@ -1,5 +1,5 @@
 error: you might have meant to write `impl` instead of `fn`
-  --> $DIR/issue-105366.rs:5:1
+  --> $DIR/issue-105366.rs:6:1
    |
 LL | fn From<i32> for Foo {
    | ^^