diff --git a/compiler/rustc_apfloat/src/ppc.rs b/compiler/rustc_apfloat/src/ppc.rs
index 4ae8edf3157eb..65a0f66645bef 100644
--- a/compiler/rustc_apfloat/src/ppc.rs
+++ b/compiler/rustc_apfloat/src/ppc.rs
@@ -30,7 +30,7 @@ pub type DoubleDouble = DoubleFloat<ieee::Double>;
 // FIXME: Implement all operations in DoubleDouble, and delete these
 // semantics.
 // FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
-pub struct FallbackS<F>(F);
+pub struct FallbackS<F>(#[allow(unused)] F);
 type Fallback<F> = ieee::IeeeFloat<FallbackS<F>>;
 impl<F: Float> ieee::Semantics for FallbackS<F> {
     // Forbid any conversion to/from bits.
@@ -45,7 +45,7 @@ impl<F: Float> ieee::Semantics for FallbackS<F> {
 // truncate the mantissa. The result of that second conversion
 // may be inexact, but should never underflow.
 // FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
-pub struct FallbackExtendedS<F>(F);
+pub struct FallbackExtendedS<F>(#[allow(unused)] F);
 type FallbackExtended<F> = ieee::IeeeFloat<FallbackExtendedS<F>>;
 impl<F: Float> ieee::Semantics for FallbackExtendedS<F> {
     // Forbid any conversion to/from bits.
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index a2205c3613d92..1a0ea8f416064 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -410,12 +410,12 @@ fn parse_options<'a>(
             try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
         } else if !is_global_asm && p.eat_keyword(sym::nostack) {
             try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
+        } else if !is_global_asm && p.eat_keyword(sym::may_unwind) {
+            try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
         } else if p.eat_keyword(sym::att_syntax) {
             try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
         } else if p.eat_keyword(kw::Raw) {
             try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
-        } else if p.eat_keyword(sym::may_unwind) {
-            try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
         } else {
             return p.unexpected();
         }
@@ -656,7 +656,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                     let span = arg_spans.next().unwrap_or(template_sp);
 
                     let operand_idx = match arg.position {
-                        parse::ArgumentIs(idx, _) | parse::ArgumentImplicitlyIs(idx) => {
+                        parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => {
                             if idx >= args.operands.len()
                                 || named_pos.contains_key(&idx)
                                 || args.reg_args.contains(&idx)
@@ -702,11 +702,12 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                                 Some(idx)
                             }
                         }
-                        parse::ArgumentNamed(name, span) => {
+                        parse::ArgumentNamed(name) => {
                             match args.named_args.get(&Symbol::intern(name)) {
                                 Some(&idx) => Some(idx),
                                 None => {
                                     let msg = format!("there is no argument named `{}`", name);
+                                    let span = arg.position_span;
                                     ecx.struct_span_err(
                                         template_span
                                             .from_inner(InnerSpan::new(span.start, span.end)),
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 082c78934262b..f536d0b5900bc 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -381,8 +381,8 @@ impl<'a, 'b> Context<'a, 'b> {
         match *p {
             parse::String(_) => {}
             parse::NextArgument(ref mut arg) => {
-                if let parse::ArgumentNamed(s, _) = arg.position {
-                    arg.position = parse::ArgumentIs(lookup(s), None);
+                if let parse::ArgumentNamed(s) = arg.position {
+                    arg.position = parse::ArgumentIs(lookup(s));
                 }
                 if let parse::CountIsName(s, _) = arg.format.width {
                     arg.format.width = parse::CountIsParam(lookup(s));
@@ -417,14 +417,14 @@ impl<'a, 'b> Context<'a, 'b> {
                 // argument second, if it's an implicit positional parameter
                 // it's written second, so it should come after width/precision.
                 let pos = match arg.position {
-                    parse::ArgumentIs(i, arg_end) => {
+                    parse::ArgumentIs(i) => {
                         self.unused_names_lint.maybe_add_positional_named_arg(
                             i,
                             self.args.len(),
                             i,
                             PositionalNamedArgType::Arg,
                             self.curpiece,
-                            arg_end,
+                            Some(arg.position_span),
                             &self.names,
                         );
 
@@ -442,8 +442,9 @@ impl<'a, 'b> Context<'a, 'b> {
                         );
                         Exact(i)
                     }
-                    parse::ArgumentNamed(s, span) => {
+                    parse::ArgumentNamed(s) => {
                         let symbol = Symbol::intern(s);
+                        let span = arg.position_span;
                         Named(symbol, InnerSpan::new(span.start, span.end))
                     }
                 };
@@ -878,8 +879,9 @@ impl<'a, 'b> Context<'a, 'b> {
                         // track the current argument ourselves.
                         let i = self.curarg;
                         self.curarg += 1;
-                        parse::ArgumentIs(i, None)
+                        parse::ArgumentIs(i)
                     },
+                    position_span: arg.position_span,
                     format: parse::FormatSpec {
                         fill: arg.format.fill,
                         align: parse::AlignUnknown,
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 39690851d1ea8..f00165cd3b370 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -630,6 +630,32 @@ declare_lint! {
     "detects attributes that were not used by the compiler"
 }
 
+declare_lint! {
+    /// The `unused_tuple_struct_fields` lint detects fields of tuple structs
+    /// that are never read.
+    ///
+    /// ### Example
+    ///
+    /// ```
+    /// #[warn(unused_tuple_struct_fields)]
+    /// struct S(i32, i32, i32);
+    /// let s = S(1, 2, 3);
+    /// let _ = (s.0, s.2);
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Tuple struct fields that are never read anywhere may indicate a
+    /// mistake or unfinished code. To silence this warning, consider
+    /// removing the unused field(s) or, to preserve the numbering of the
+    /// remaining fields, change the unused field(s) to have unit type.
+    pub UNUSED_TUPLE_STRUCT_FIELDS,
+    Allow,
+    "detects tuple struct fields that are never read"
+}
+
 declare_lint! {
     /// The `unreachable_code` lint detects unreachable code paths.
     ///
@@ -3281,6 +3307,7 @@ declare_lint_pass! {
         UNSUPPORTED_CALLING_CONVENTIONS,
         BREAK_WITH_LABEL_AND_LOOP,
         UNUSED_ATTRIBUTES,
+        UNUSED_TUPLE_STRUCT_FIELDS,
         NON_EXHAUSTIVE_OMITTED_PATTERNS,
         TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
         DEREF_INTO_DYN_SUPERTRAIT,
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index e64136928cce8..21132eb991fd5 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -222,18 +222,6 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> {
     }
 }
 
-struct TransferWrapper<'a>(&'a mut ChunkedBitSet<Local>);
-
-impl<'a> GenKill<Local> for TransferWrapper<'a> {
-    fn gen(&mut self, l: Local) {
-        self.0.insert(l);
-    }
-
-    fn kill(&mut self, l: Local) {
-        self.0.remove(l);
-    }
-}
-
 impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
     fn apply_statement_effect(
         &self,
@@ -271,7 +259,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
                 return;
             }
         }
-        TransferFunction(&mut TransferWrapper(trans)).visit_statement(statement, location);
+        TransferFunction(trans).visit_statement(statement, location);
     }
 
     fn apply_terminator_effect(
@@ -280,7 +268,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
         terminator: &mir::Terminator<'tcx>,
         location: Location,
     ) {
-        TransferFunction(&mut TransferWrapper(trans)).visit_terminator(terminator, location);
+        TransferFunction(trans).visit_terminator(terminator, location);
     }
 
     fn apply_call_return_effect(
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 5deb17b8651b6..a7ff9711691fb 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -70,6 +70,9 @@ pub enum Piece<'a> {
 pub struct Argument<'a> {
     /// Where to find this argument
     pub position: Position<'a>,
+    /// The span of the position indicator. Includes any whitespace in implicit
+    /// positions (`{  }`).
+    pub position_span: InnerSpan,
     /// How to format the argument
     pub format: FormatSpec<'a>,
 }
@@ -105,9 +108,9 @@ pub enum Position<'a> {
     /// The argument is implied to be located at an index
     ArgumentImplicitlyIs(usize),
     /// The argument is located at a specific index given in the format,
-    ArgumentIs(usize, Option<InnerSpan>),
+    ArgumentIs(usize),
     /// The argument has a name.
-    ArgumentNamed(&'a str, InnerSpan),
+    ArgumentNamed(&'a str),
 }
 
 impl Position<'_> {
@@ -216,14 +219,15 @@ impl<'a> Iterator for Parser<'a> {
                 '{' => {
                     let curr_last_brace = self.last_opening_brace;
                     let byte_pos = self.to_span_index(pos);
-                    self.last_opening_brace = Some(byte_pos.to(InnerOffset(byte_pos.0 + 1)));
+                    let lbrace_end = InnerOffset(byte_pos.0 + 1);
+                    self.last_opening_brace = Some(byte_pos.to(lbrace_end));
                     self.cur.next();
                     if self.consume('{') {
                         self.last_opening_brace = curr_last_brace;
 
                         Some(String(self.string(pos + 1)))
                     } else {
-                        let arg = self.argument();
+                        let arg = self.argument(lbrace_end);
                         if let Some(rbrace_byte_idx) = self.must_consume('}') {
                             let lbrace_inner_offset = self.to_span_index(pos);
                             let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
@@ -477,8 +481,16 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an `Argument` structure, or what's contained within braces inside the format string.
-    fn argument(&mut self) -> Argument<'a> {
+    fn argument(&mut self, start: InnerOffset) -> Argument<'a> {
         let pos = self.position();
+
+        let end = self
+            .cur
+            .clone()
+            .find(|(_, ch)| !ch.is_whitespace())
+            .map_or(start, |(end, _)| self.to_span_index(end));
+        let position_span = start.to(end);
+
         let format = match self.mode {
             ParseMode::Format => self.format(),
             ParseMode::InlineAsm => self.inline_asm(),
@@ -494,7 +506,7 @@ impl<'a> Parser<'a> {
             }
         };
 
-        Argument { position: pos, format }
+        Argument { position: pos, position_span, format }
     }
 
     /// Parses a positional argument for a format. This could either be an
@@ -502,23 +514,11 @@ impl<'a> Parser<'a> {
     /// Returns `Some(parsed_position)` if the position is not implicitly
     /// consuming a macro argument, `None` if it's the case.
     fn position(&mut self) -> Option<Position<'a>> {
-        let start_position = self.cur.peek().map(|item| item.0);
         if let Some(i) = self.integer() {
-            let inner_span = start_position.and_then(|start| {
-                self.cur
-                    .peek()
-                    .cloned()
-                    .and_then(|item| Some(self.to_span_index(start).to(self.to_span_index(item.0))))
-            });
-            Some(ArgumentIs(i, inner_span))
+            Some(ArgumentIs(i))
         } else {
             match self.cur.peek() {
-                Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
-                    let word = self.word();
-                    let end = start + word.len();
-                    let span = self.to_span_index(start).to(self.to_span_index(end));
-                    Some(ArgumentNamed(word, span))
-                }
+                Some(&(_, c)) if rustc_lexer::is_id_start(c) => Some(ArgumentNamed(self.word())),
 
                 // This is an `ArgumentNext`.
                 // Record the fact and do the resolution after parsing the
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index a98f816644bd6..578530696105d 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -58,14 +58,22 @@ fn invalid06() {
 
 #[test]
 fn format_nothing() {
-    same("{}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), format: fmtdflt() })]);
+    same(
+        "{}",
+        &[NextArgument(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
+            format: fmtdflt(),
+        })],
+    );
 }
 #[test]
 fn format_position() {
     same(
         "{3}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: fmtdflt(),
         })],
     );
@@ -75,17 +83,30 @@ fn format_position_nothing_else() {
     same(
         "{3:}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: fmtdflt(),
         })],
     );
 }
 #[test]
+fn format_named() {
+    same(
+        "{name}",
+        &[NextArgument(Argument {
+            position: ArgumentNamed("name"),
+            position_span: InnerSpan { start: 2, end: 6 },
+            format: fmtdflt(),
+        })],
+    )
+}
+#[test]
 fn format_type() {
     same(
         "{3:x}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -105,7 +126,8 @@ fn format_align_fill() {
     same(
         "{3:>}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: FormatSpec {
                 fill: None,
                 align: AlignRight,
@@ -122,7 +144,8 @@ fn format_align_fill() {
     same(
         "{3:0<}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: FormatSpec {
                 fill: Some('0'),
                 align: AlignLeft,
@@ -139,7 +162,8 @@ fn format_align_fill() {
     same(
         "{3:*<abcd}",
         &[NextArgument(Argument {
-            position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(3),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: FormatSpec {
                 fill: Some('*'),
                 align: AlignLeft,
@@ -160,6 +184,7 @@ fn format_counts() {
         "{:10x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -177,6 +202,7 @@ fn format_counts() {
         "{:10$.10x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -193,7 +219,8 @@ fn format_counts() {
     same(
         "{1:0$.10x}",
         &[NextArgument(Argument {
-            position: ArgumentIs(1, Some(InnerSpan { start: 2, end: 3 })),
+            position: ArgumentIs(1),
+            position_span: InnerSpan { start: 2, end: 3 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -211,6 +238,7 @@ fn format_counts() {
         "{:.*x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(1),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -228,6 +256,7 @@ fn format_counts() {
         "{:.10$x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -245,6 +274,7 @@ fn format_counts() {
         "{:a$.b$?}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -265,6 +295,7 @@ fn format_flags() {
         "{:-}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -282,6 +313,7 @@ fn format_flags() {
         "{:+#}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 2 },
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
@@ -303,7 +335,8 @@ fn format_mixture() {
         &[
             String("abcd "),
             NextArgument(Argument {
-                position: ArgumentIs(3, Some(InnerSpan { start: 7, end: 8 })),
+                position: ArgumentIs(3),
+                position_span: InnerSpan { start: 7, end: 8 },
                 format: FormatSpec {
                     fill: None,
                     align: AlignUnknown,
@@ -320,3 +353,22 @@ fn format_mixture() {
         ],
     );
 }
+#[test]
+fn format_whitespace() {
+    same(
+        "{ }",
+        &[NextArgument(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 3 },
+            format: fmtdflt(),
+        })],
+    );
+    same(
+        "{  }",
+        &[NextArgument(Argument {
+            position: ArgumentImplicitlyIs(0),
+            position_span: InnerSpan { start: 2, end: 4 },
+            format: fmtdflt(),
+        })],
+    );
+}
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index fde12b9eee6b9..e8de412aff61a 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -53,7 +53,7 @@ pub(crate) fn target_from_impl_item<'tcx>(
 #[derive(Clone, Copy)]
 enum ItemLike<'tcx> {
     Item(&'tcx Item<'tcx>),
-    ForeignItem(&'tcx ForeignItem<'tcx>),
+    ForeignItem,
 }
 
 struct CheckAttrVisitor<'tcx> {
@@ -1995,12 +1995,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
 
     fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) {
         let target = Target::from_foreign_item(f_item);
-        self.check_attributes(
-            f_item.hir_id(),
-            f_item.span,
-            target,
-            Some(ItemLike::ForeignItem(f_item)),
-        );
+        self.check_attributes(f_item.hir_id(), f_item.span, target, Some(ItemLike::ForeignItem));
         intravisit::walk_foreign_item(self, f_item)
     }
 
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 58c5e5b4dfe53..1e2fbeb384cee 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -4,7 +4,7 @@
 
 use itertools::Itertools;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{pluralize, MultiSpan};
+use rustc_errors::{pluralize, Applicability, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -42,6 +42,7 @@ struct MarkSymbolVisitor<'tcx> {
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
     live_symbols: FxHashSet<LocalDefId>,
     repr_has_repr_c: bool,
+    repr_has_repr_simd: bool,
     in_pat: bool,
     ignore_variant_stack: Vec<DefId>,
     // maps from tuple struct constructors to tuple struct items
@@ -220,6 +221,32 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
     }
 
+    fn handle_tuple_field_pattern_match(
+        &mut self,
+        lhs: &hir::Pat<'_>,
+        res: Res,
+        pats: &[hir::Pat<'_>],
+        dotdot: Option<usize>,
+    ) {
+        let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
+            ty::Adt(adt, _) => adt.variant_of_res(res),
+            _ => span_bug!(lhs.span, "non-ADT in tuple struct pattern"),
+        };
+        let first_n = pats.iter().enumerate().take(dotdot.unwrap_or(pats.len()));
+        let missing = variant.fields.len() - pats.len();
+        let last_n = pats
+            .iter()
+            .enumerate()
+            .skip(dotdot.unwrap_or(pats.len()))
+            .map(|(idx, pat)| (idx + missing, pat));
+        for (idx, pat) in first_n.chain(last_n) {
+            if let PatKind::Wild = pat.kind {
+                continue;
+            }
+            self.insert_def_id(variant.fields[idx].did);
+        }
+    }
+
     fn mark_live_symbols(&mut self) {
         let mut scanned = FxHashSet::default();
         while let Some(id) = self.worklist.pop() {
@@ -274,12 +301,15 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
 
         let had_repr_c = self.repr_has_repr_c;
+        let had_repr_simd = self.repr_has_repr_simd;
         self.repr_has_repr_c = false;
+        self.repr_has_repr_simd = false;
         match node {
             Node::Item(item) => match item.kind {
                 hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
                     let def = self.tcx.adt_def(item.def_id);
                     self.repr_has_repr_c = def.repr().c();
+                    self.repr_has_repr_simd = def.repr().simd();
 
                     intravisit::walk_item(self, &item)
                 }
@@ -315,6 +345,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
             }
             _ => {}
         }
+        self.repr_has_repr_simd = had_repr_simd;
         self.repr_has_repr_c = had_repr_c;
     }
 
@@ -347,9 +378,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
     ) {
         let tcx = self.tcx;
         let has_repr_c = self.repr_has_repr_c;
+        let has_repr_simd = self.repr_has_repr_simd;
         let live_fields = def.fields().iter().filter_map(|f| {
             let def_id = tcx.hir().local_def_id(f.hir_id);
-            if has_repr_c {
+            if has_repr_c || (f.is_positional() && has_repr_simd) {
                 return Some(def_id);
             }
             if !tcx.visibility(f.hir_id.owner).is_public() {
@@ -408,6 +440,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
                 let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
                 self.handle_res(res);
             }
+            PatKind::TupleStruct(ref qpath, ref fields, dotdot) => {
+                let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
+                self.handle_tuple_field_pattern_match(pat, res, fields, dotdot);
+            }
             _ => (),
         }
 
@@ -440,7 +476,11 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
     }
 }
 
-fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
+fn has_allow_dead_code_or_lang_attr_helper(
+    tcx: TyCtxt<'_>,
+    id: hir::HirId,
+    lint: &'static lint::Lint,
+) -> bool {
     let attrs = tcx.hir().attrs(id);
     if tcx.sess.contains_name(attrs, sym::lang) {
         return true;
@@ -470,7 +510,11 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
         }
     }
 
-    tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
+    tcx.lint_level_at_node(lint, id).0 == lint::Allow
+}
+
+fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
+    has_allow_dead_code_or_lang_attr_helper(tcx, id, lint::builtin::DEAD_CODE)
 }
 
 // These check_* functions seeds items that
@@ -623,6 +667,7 @@ fn live_symbols_and_ignored_derived_traits<'tcx>(
         maybe_typeck_results: None,
         live_symbols: Default::default(),
         repr_has_repr_c: false,
+        repr_has_repr_simd: false,
         in_pat: false,
         ignore_variant_stack: vec![],
         struct_constructors,
@@ -644,17 +689,30 @@ struct DeadVisitor<'tcx> {
     ignored_derived_traits: &'tcx FxHashMap<LocalDefId, Vec<(DefId, DefId)>>,
 }
 
+enum ShouldWarnAboutField {
+    Yes(bool), // positional?
+    No,
+}
+
 impl<'tcx> DeadVisitor<'tcx> {
-    fn should_warn_about_field(&mut self, field: &ty::FieldDef) -> bool {
+    fn should_warn_about_field(&mut self, field: &ty::FieldDef) -> ShouldWarnAboutField {
         if self.live_symbols.contains(&field.did.expect_local()) {
-            return false;
+            return ShouldWarnAboutField::No;
+        }
+        let field_type = self.tcx.type_of(field.did);
+        if field_type.is_phantom_data() {
+            return ShouldWarnAboutField::No;
         }
         let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
-        if is_positional {
-            return false;
+        if is_positional
+            && self
+                .tcx
+                .layout_of(self.tcx.param_env(field.did).and(field_type))
+                .map_or(true, |layout| layout.is_zst())
+        {
+            return ShouldWarnAboutField::No;
         }
-        let field_type = self.tcx.type_of(field.did);
-        !field_type.is_phantom_data()
+        ShouldWarnAboutField::Yes(is_positional)
     }
 
     fn warn_multiple_dead_codes(
@@ -662,6 +720,7 @@ impl<'tcx> DeadVisitor<'tcx> {
         dead_codes: &[LocalDefId],
         participle: &str,
         parent_item: Option<LocalDefId>,
+        is_positional: bool,
     ) {
         if let Some(&first_id) = dead_codes.first() {
             let tcx = self.tcx;
@@ -669,7 +728,7 @@ impl<'tcx> DeadVisitor<'tcx> {
                 .iter()
                 .map(|&def_id| tcx.item_name(def_id.to_def_id()).to_string())
                 .collect();
-            let spans = dead_codes
+            let spans: Vec<_> = dead_codes
                 .iter()
                 .map(|&def_id| match tcx.def_ident_span(def_id) {
                     Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()),
@@ -678,9 +737,13 @@ impl<'tcx> DeadVisitor<'tcx> {
                 .collect();
 
             tcx.struct_span_lint_hir(
-                lint::builtin::DEAD_CODE,
+                if is_positional {
+                    lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
+                } else {
+                    lint::builtin::DEAD_CODE
+                },
                 tcx.hir().local_def_id_to_hir_id(first_id),
-                MultiSpan::from_spans(spans),
+                MultiSpan::from_spans(spans.clone()),
                 |lint| {
                     let descr = tcx.def_kind(first_id).descr(first_id.to_def_id());
                     let span_len = dead_codes.len();
@@ -702,6 +765,21 @@ impl<'tcx> DeadVisitor<'tcx> {
                         are = pluralize!("is", span_len),
                     ));
 
+                    if is_positional {
+                        err.multipart_suggestion(
+                            &format!(
+                                "consider changing the field{s} to be of unit type to \
+                                      suppress this warning while preserving the field \
+                                      numbering, or remove the field{s}",
+                                s = pluralize!(span_len)
+                            ),
+                            spans.iter().map(|sp| (*sp, "()".to_string())).collect(),
+                            // "HasPlaceholders" because applying this fix by itself isn't
+                            // enough: All constructor calls have to be adjusted as well
+                            Applicability::HasPlaceholders,
+                        );
+                    }
+
                     if let Some(parent_item) = parent_item {
                         let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id());
                         err.span_label(
@@ -743,6 +821,7 @@ impl<'tcx> DeadVisitor<'tcx> {
         def_id: LocalDefId,
         participle: &str,
         dead_codes: Vec<DeadVariant>,
+        is_positional: bool,
     ) {
         let mut dead_codes = dead_codes
             .iter()
@@ -758,12 +837,13 @@ impl<'tcx> DeadVisitor<'tcx> {
                 &group.map(|v| v.def_id).collect::<Vec<_>>(),
                 participle,
                 Some(def_id),
+                is_positional,
             );
         }
     }
 
     fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) {
-        self.warn_multiple_dead_codes(&[id], participle, None);
+        self.warn_multiple_dead_codes(&[id], participle, None, false);
     }
 
     fn check_definition(&mut self, def_id: LocalDefId) {
@@ -829,24 +909,37 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
                     continue;
                 }
 
+                let mut is_positional = false;
                 let dead_fields = variant
                     .fields
                     .iter()
                     .filter_map(|field| {
                         let def_id = field.did.expect_local();
                         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-                        if visitor.should_warn_about_field(&field) {
-                            let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
+                        if let ShouldWarnAboutField::Yes(is_pos) =
+                            visitor.should_warn_about_field(&field)
+                        {
+                            let level = tcx
+                                .lint_level_at_node(
+                                    if is_pos {
+                                        is_positional = true;
+                                        lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
+                                    } else {
+                                        lint::builtin::DEAD_CODE
+                                    },
+                                    hir_id,
+                                )
+                                .0;
                             Some(DeadVariant { def_id, name: field.name, level })
                         } else {
                             None
                         }
                     })
                     .collect();
-                visitor.warn_dead_fields_and_variants(def_id, "read", dead_fields)
+                visitor.warn_dead_fields_and_variants(def_id, "read", dead_fields, is_positional)
             }
 
-            visitor.warn_dead_fields_and_variants(item.def_id, "constructed", dead_variants);
+            visitor.warn_dead_fields_and_variants(item.def_id, "constructed", dead_variants, false);
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index 4d3b0b4cf077c..9227bbf011dbf 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -300,7 +300,7 @@ impl<'tcx> OnUnimplementedFormatString {
             match token {
                 Piece::String(_) => (), // Normal string, no need to check it
                 Piece::NextArgument(a) => match a.position {
-                    Position::ArgumentNamed(s, _) => {
+                    Position::ArgumentNamed(s) => {
                         match Symbol::intern(s) {
                             // `{Self}` is allowed
                             kw::SelfUpper => (),
@@ -386,7 +386,7 @@ impl<'tcx> OnUnimplementedFormatString {
             .map(|p| match p {
                 Piece::String(s) => s,
                 Piece::NextArgument(a) => match a.position {
-                    Position::ArgumentNamed(s, _) => {
+                    Position::ArgumentNamed(s) => {
                         let s = Symbol::intern(s);
                         match generic_map.get(&s) {
                             Some(val) => val,
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 5fe2c9ab4e37b..4c7c9412edda7 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -120,7 +120,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
             kind: Box::new(ImplItem(Box::new(Impl {
                 unsafety: hir::Unsafety::Normal,
                 generics: new_generics,
-                trait_: Some(trait_ref.clean(self.cx)),
+                trait_: Some(clean_trait_ref_with_bindings(self.cx, trait_ref, &[])),
                 for_: clean_middle_ty(ty, self.cx, None),
                 items: Vec::new(),
                 polarity,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 8aecd9b15e842..01dd95e6e4093 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -115,7 +115,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             ),
                             // FIXME(eddyb) compute both `trait_` and `for_` from
                             // the post-inference `trait_ref`, as it's more accurate.
-                            trait_: Some(trait_ref.0.clean(cx)),
+                            trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref.0, &[])),
                             for_: clean_middle_ty(ty.0, cx, None),
                             items: cx.tcx
                                 .associated_items(impl_def_id)
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 6577315a2b710..13a79acb41054 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -16,9 +16,9 @@ use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
 
 use crate::clean::{
-    self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty, clean_ty,
-    clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
-    Clean, ImplKind, ItemId, Type, Visibility,
+    self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty,
+    clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def,
+    clean_visibility, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, Type, Visibility,
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
@@ -450,7 +450,7 @@ pub(crate) fn build_impl(
         ),
     };
     let polarity = tcx.impl_polarity(did);
-    let trait_ = associated_trait.map(|t| t.clean(cx));
+    let trait_ = associated_trait.map(|t| clean_trait_ref_with_bindings(cx, t, &[]));
     if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b6791bfab4ad4..4496602f43ebc 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -130,7 +130,7 @@ impl<'tcx> Clean<'tcx, Attributes> for [ast::Attribute] {
 impl<'tcx> Clean<'tcx, Option<GenericBound>> for hir::GenericBound<'tcx> {
     fn clean(&self, cx: &mut DocContext<'tcx>) -> Option<GenericBound> {
         Some(match *self {
-            hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
+            hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
             hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
                 let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
 
@@ -163,7 +163,7 @@ impl<'tcx> Clean<'tcx, Option<GenericBound>> for hir::GenericBound<'tcx> {
     }
 }
 
-fn clean_trait_ref_with_bindings<'tcx>(
+pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
     cx: &mut DocContext<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
     bindings: &[TypeBinding],
@@ -180,12 +180,6 @@ fn clean_trait_ref_with_bindings<'tcx>(
     path
 }
 
-impl<'tcx> Clean<'tcx, Path> for ty::TraitRef<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'tcx>) -> Path {
-        clean_trait_ref_with_bindings(cx, *self, &[])
-    }
-}
-
 fn clean_poly_trait_ref_with_bindings<'tcx>(
     cx: &mut DocContext<'tcx>,
     poly_trait_ref: ty::PolyTraitRef<'tcx>,
@@ -220,21 +214,19 @@ impl<'tcx> Clean<'tcx, GenericBound> for ty::PolyTraitRef<'tcx> {
     }
 }
 
-impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime {
-    fn clean(&self, cx: &mut DocContext<'tcx>) -> Lifetime {
-        let def = cx.tcx.named_region(self.hir_id);
-        if let Some(
-            rl::Region::EarlyBound(_, node_id)
-            | rl::Region::LateBound(_, _, node_id)
-            | rl::Region::Free(_, node_id),
-        ) = def
-        {
-            if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() {
-                return lt;
-            }
+fn clean_lifetime<'tcx>(lifetime: hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime {
+    let def = cx.tcx.named_region(lifetime.hir_id);
+    if let Some(
+        rl::Region::EarlyBound(_, node_id)
+        | rl::Region::LateBound(_, _, node_id)
+        | rl::Region::Free(_, node_id),
+    ) = def
+    {
+        if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() {
+            return lt;
         }
-        Lifetime(self.name.ident().name)
     }
+    Lifetime(lifetime.name.ident().name)
 }
 
 pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
@@ -311,7 +303,7 @@ impl<'tcx> Clean<'tcx, Option<WherePredicate>> for hir::WherePredicate<'tcx> {
             }
 
             hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
-                lifetime: wrp.lifetime.clean(cx),
+                lifetime: clean_lifetime(wrp.lifetime, cx),
                 bounds: wrp.bounds.iter().filter_map(|x| x.clean(cx)).collect(),
             },
 
@@ -432,7 +424,7 @@ fn clean_projection<'tcx>(
     def_id: Option<DefId>,
 ) -> Type {
     let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
-    let trait_ = lifted.trait_ref(cx.tcx).clean(cx);
+    let trait_ = clean_trait_ref_with_bindings(cx, lifted.trait_ref(cx.tcx), &[]);
     let self_type = clean_middle_ty(ty.self_ty(), cx, None);
     let self_def_id = if let Some(def_id) = def_id {
         cx.tcx.opt_parent(def_id).or(Some(def_id))
@@ -524,7 +516,7 @@ fn clean_generic_param<'tcx>(
                     .filter(|bp| !bp.in_where_clause)
                     .flat_map(|bp| bp.bounds)
                     .map(|bound| match bound {
-                        hir::GenericBound::Outlives(lt) => lt.clean(cx),
+                        hir::GenericBound::Outlives(lt) => clean_lifetime(*lt, cx),
                         _ => panic!(),
                     })
                     .collect()
@@ -1431,7 +1423,8 @@ fn maybe_expand_private_type_alias<'tcx>(
                 });
                 if let Some(lt) = lifetime.cloned() {
                     let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
-                    let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() };
+                    let cleaned =
+                        if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };
                     substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
                 }
                 indices.lifetimes += 1;
@@ -1503,7 +1496,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
             // there's no case where it could cause the function to fail to compile.
             let elided =
                 l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh));
-            let lifetime = if elided { None } else { Some(l.clean(cx)) };
+            let lifetime = if elided { None } else { Some(clean_lifetime(*l, cx)) };
             BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
         }
         TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
@@ -1539,7 +1532,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
         TyKind::Path(_) => clean_qpath(ty, cx),
         TyKind::TraitObject(bounds, ref lifetime, _) => {
             let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect();
-            let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None };
+            let lifetime =
+                if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
             DynTrait(bounds, lifetime)
         }
         TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))),
@@ -1875,7 +1869,7 @@ impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> {
                 .iter()
                 .map(|arg| match arg {
                     hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
-                        GenericArg::Lifetime(lt.clean(cx))
+                        GenericArg::Lifetime(clean_lifetime(*lt, cx))
                     }
                     hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
                     hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs
index 25cf5dad61403..6df4ff7e58bb2 100644
--- a/src/test/codegen-units/item-collection/generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs
@@ -34,9 +34,9 @@ enum EnumNoDrop<T1, T2> {
 }
 
 
-struct NonGenericNoDrop(i32);
+struct NonGenericNoDrop(#[allow(unused_tuple_struct_fields)] i32);
 
-struct NonGenericWithDrop(i32);
+struct NonGenericWithDrop(#[allow(unused_tuple_struct_fields)] i32);
 //~ MONO_ITEM fn std::ptr::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal]
 
 impl Drop for NonGenericWithDrop {
diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
index 8249e7cba946b..e286c800b7cae 100644
--- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
@@ -6,9 +6,9 @@
 #![feature(start)]
 
 //~ MONO_ITEM fn std::ptr::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal]
-struct Root(Intermediate);
+struct Root(#[allow(unused_tuple_struct_fields)] Intermediate);
 //~ MONO_ITEM fn std::ptr::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal]
-struct Intermediate(Leaf);
+struct Intermediate(#[allow(unused_tuple_struct_fields)] Leaf);
 //~ MONO_ITEM fn std::ptr::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal]
 struct Leaf;
 
@@ -17,9 +17,9 @@ impl Drop for Leaf {
     fn drop(&mut self) {}
 }
 
-struct RootGen<T>(IntermediateGen<T>);
-struct IntermediateGen<T>(LeafGen<T>);
-struct LeafGen<T>(T);
+struct RootGen<T>(#[allow(unused_tuple_struct_fields)] IntermediateGen<T>);
+struct IntermediateGen<T>(#[allow(unused_tuple_struct_fields)] LeafGen<T>);
+struct LeafGen<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T> Drop for LeafGen<T> {
     fn drop(&mut self) {}
diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs
index 81675377941bd..111a7231209a1 100644
--- a/src/test/codegen-units/item-collection/unsizing.rs
+++ b/src/test/codegen-units/item-collection/unsizing.rs
@@ -40,7 +40,7 @@ impl Trait for u32 {
 }
 
 #[derive(Clone, Copy)]
-struct Wrapper<T: ?Sized>(*const T);
+struct Wrapper<T: ?Sized>(#[allow(unused_tuple_struct_fields)] *const T);
 
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
 
diff --git a/src/test/run-make-fulldeps/issues-41478-43796/a.rs b/src/test/run-make-fulldeps/issues-41478-43796/a.rs
index fd67221144a38..b072235b5bc5a 100644
--- a/src/test/run-make-fulldeps/issues-41478-43796/a.rs
+++ b/src/test/run-make-fulldeps/issues-41478-43796/a.rs
@@ -1,5 +1,5 @@
 #![crate_type = "lib"]
-pub struct V<S>(S);
+pub struct V<S>(#[allow(unused_tuple_struct_fields)] S);
 pub trait An {
     type U;
 }
diff --git a/src/test/ui/align-with-extern-c-fn.rs b/src/test/ui/align-with-extern-c-fn.rs
index f77f40998de01..9e490e27ad17d 100644
--- a/src/test/ui/align-with-extern-c-fn.rs
+++ b/src/test/ui/align-with-extern-c-fn.rs
@@ -8,7 +8,7 @@
 #![feature(repr_align)]
 
 #[repr(align(16))]
-pub struct A(i64);
+pub struct A(#[allow(unused_tuple_struct_fields)] i64);
 
 #[allow(improper_ctypes_definitions)]
 pub extern "C" fn foo(x: A) {}
diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
index c9b4abbfd3fd3..54b7c8bb9c6f8 100644
--- a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
+++ b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
@@ -92,7 +92,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
 extern fn rust_eh_personality() {}
 
 #[derive(Debug)]
-struct Page([[u64; 32]; 16]);
+struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
 
 #[start]
 pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs
index d6cd4a6af855f..ffa331a992c8b 100644
--- a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs
+++ b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs
@@ -79,7 +79,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
 extern fn rust_eh_personality() {}
 
 #[derive(Debug)]
-struct Page([[u64; 32]; 16]);
+struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
 
 #[start]
 pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
diff --git a/src/test/ui/array-slice-vec/show-boxed-slice.rs b/src/test/ui/array-slice-vec/show-boxed-slice.rs
index dfa4c720bb09a..c10f779b1f617 100644
--- a/src/test/ui/array-slice-vec/show-boxed-slice.rs
+++ b/src/test/ui/array-slice-vec/show-boxed-slice.rs
@@ -1,7 +1,7 @@
 // run-pass
 
 #[derive(Debug)]
-struct Foo(Box<[u8]>);
+struct Foo(#[allow(unused_tuple_struct_fields)] Box<[u8]>);
 
 pub fn main() {
     println!("{:?}", Foo(Box::new([0, 1, 2])));
diff --git a/src/test/ui/asm/aarch64/bad-options.stderr b/src/test/ui/asm/aarch64/bad-options.stderr
index 867e0433eae1b..21bcc4a9c7bad 100644
--- a/src/test/ui/asm/aarch64/bad-options.stderr
+++ b/src/test/ui/asm/aarch64/bad-options.stderr
@@ -36,41 +36,41 @@ LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
    |                    |
    |                    generic outputs
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/bad-options.rs:28:25
    |
 LL | global_asm!("", options(nomem));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `readonly`
+error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
   --> $DIR/bad-options.rs:30:25
    |
 LL | global_asm!("", options(readonly));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `noreturn`
+error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
   --> $DIR/bad-options.rs:32:25
    |
 LL | global_asm!("", options(noreturn));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `pure`
+error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
   --> $DIR/bad-options.rs:34:25
    |
 LL | global_asm!("", options(pure));
-   |                         ^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nostack`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
   --> $DIR/bad-options.rs:36:25
    |
 LL | global_asm!("", options(nostack));
-   |                         ^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `preserves_flags`
+error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
   --> $DIR/bad-options.rs:38:25
    |
 LL | global_asm!("", options(preserves_flags));
-   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: invalid ABI for `clobber_abi`
   --> $DIR/bad-options.rs:20:18
diff --git a/src/test/ui/asm/aarch64/parse-error.stderr b/src/test/ui/asm/aarch64/parse-error.stderr
index f2013046cda42..804966b06ba7d 100644
--- a/src/test/ui/asm/aarch64/parse-error.stderr
+++ b/src/test/ui/asm/aarch64/parse-error.stderr
@@ -260,23 +260,23 @@ error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
 LL | global_asm!("{}", const(reg) FOO);
    |                              ^^^ expected one of `,`, `.`, `?`, or an operator
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `FOO`
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
   --> $DIR/parse-error.rs:102:25
    |
 LL | global_asm!("", options(FOO));
-   |                         ^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/parse-error.rs:104:25
    |
 LL | global_asm!("", options(nomem FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/parse-error.rs:106:25
    |
 LL | global_asm!("", options(nomem, FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: arguments are not allowed after options
   --> $DIR/parse-error.rs:108:30
diff --git a/src/test/ui/asm/x86_64/bad-options.stderr b/src/test/ui/asm/x86_64/bad-options.stderr
index a63c42aac2737..e2351840eef21 100644
--- a/src/test/ui/asm/x86_64/bad-options.stderr
+++ b/src/test/ui/asm/x86_64/bad-options.stderr
@@ -45,41 +45,41 @@ LL |         asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
    |                    |             clobber_abi
    |                    generic outputs
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/bad-options.rs:31:25
    |
 LL | global_asm!("", options(nomem));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `readonly`
+error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
   --> $DIR/bad-options.rs:33:25
    |
 LL | global_asm!("", options(readonly));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `noreturn`
+error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
   --> $DIR/bad-options.rs:35:25
    |
 LL | global_asm!("", options(noreturn));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `pure`
+error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
   --> $DIR/bad-options.rs:37:25
    |
 LL | global_asm!("", options(pure));
-   |                         ^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nostack`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
   --> $DIR/bad-options.rs:39:25
    |
 LL | global_asm!("", options(nostack));
-   |                         ^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `preserves_flags`
+error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
   --> $DIR/bad-options.rs:41:25
    |
 LL | global_asm!("", options(preserves_flags));
-   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: invalid ABI for `clobber_abi`
   --> $DIR/bad-options.rs:20:18
diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr
index 1fd317a96a8a6..57702c37b7ce2 100644
--- a/src/test/ui/asm/x86_64/parse-error.stderr
+++ b/src/test/ui/asm/x86_64/parse-error.stderr
@@ -266,23 +266,23 @@ error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
 LL | global_asm!("{}", const(reg) FOO);
    |                              ^^^ expected one of `,`, `.`, `?`, or an operator
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `FOO`
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
   --> $DIR/parse-error.rs:104:25
    |
 LL | global_asm!("", options(FOO));
-   |                         ^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/parse-error.rs:106:25
    |
 LL | global_asm!("", options(nomem FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/parse-error.rs:108:25
    |
 LL | global_asm!("", options(nomem, FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: arguments are not allowed after options
   --> $DIR/parse-error.rs:110:30
diff --git a/src/test/ui/associated-consts/associated-const-type-parameters.rs b/src/test/ui/associated-consts/associated-const-type-parameters.rs
index 47c3313ec2847..e7ead1045e636 100644
--- a/src/test/ui/associated-consts/associated-const-type-parameters.rs
+++ b/src/test/ui/associated-consts/associated-const-type-parameters.rs
@@ -17,7 +17,7 @@ impl Foo for Def {
     const X: i32 = 97;
 }
 
-struct Proxy<T>(T);
+struct Proxy<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T: Foo> Foo for Proxy<T> {
     const X: i32 = T::X;
diff --git a/src/test/ui/associated-type-bounds/enum-bounds.rs b/src/test/ui/associated-type-bounds/enum-bounds.rs
index a6b0bb7070b7a..193f2efe19929 100644
--- a/src/test/ui/associated-type-bounds/enum-bounds.rs
+++ b/src/test/ui/associated-type-bounds/enum-bounds.rs
@@ -1,6 +1,7 @@
 // run-pass
 
 #![feature(associated_type_bounds)]
+#![allow(dead_code)]
 
 trait Tr1 { type As1; }
 trait Tr2 { type As2; }
diff --git a/src/test/ui/associated-types/associated-types-method.rs b/src/test/ui/associated-types/associated-types-method.rs
index 64132cfeed7d2..45df3ac20c2ea 100644
--- a/src/test/ui/associated-types/associated-types-method.rs
+++ b/src/test/ui/associated-types/associated-types-method.rs
@@ -5,6 +5,7 @@
 trait Device {
     type Resources;
 }
+#[allow(unused_tuple_struct_fields)]
 struct Foo<D, R>(D, R);
 
 trait Tr {
diff --git a/src/test/ui/associated-types/associated-types-struct-field-numbered.rs b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs
index fa59060629ddf..8612911d8f809 100644
--- a/src/test/ui/associated-types/associated-types-struct-field-numbered.rs
+++ b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs
@@ -9,7 +9,7 @@ pub trait UnifyKey {
     fn dummy(&self) { }
 }
 
-pub struct Node<K:UnifyKey>(K, K::Value);
+pub struct Node<K:UnifyKey>(#[allow(unused_tuple_struct_fields)] K, K::Value);
 
 fn foo<K : UnifyKey<Value=Option<V>>,V : Clone>(node: &Node<K>) -> Option<V> {
     node.1.clone()
diff --git a/src/test/ui/async-await/async-fn-size-moved-locals.rs b/src/test/ui/async-await/async-fn-size-moved-locals.rs
index a603ebd6e8547..15566256600df 100644
--- a/src/test/ui/async-await/async-fn-size-moved-locals.rs
+++ b/src/test/ui/async-await/async-fn-size-moved-locals.rs
@@ -17,7 +17,7 @@ use std::pin::Pin;
 use std::task::{Context, Poll};
 
 const BIG_FUT_SIZE: usize = 1024;
-struct BigFut([u8; BIG_FUT_SIZE]);
+struct BigFut(#[allow(unused_tuple_struct_fields)] [u8; BIG_FUT_SIZE]);
 
 impl BigFut {
     fn new() -> Self {
diff --git a/src/test/ui/async-await/async-fn-size-uninit-locals.rs b/src/test/ui/async-await/async-fn-size-uninit-locals.rs
index d5d7b3fc3f0bd..31a086ba97569 100644
--- a/src/test/ui/async-await/async-fn-size-uninit-locals.rs
+++ b/src/test/ui/async-await/async-fn-size-uninit-locals.rs
@@ -16,7 +16,7 @@ use std::pin::Pin;
 use std::task::{Context, Poll};
 
 const BIG_FUT_SIZE: usize = 1024;
-struct Big([u8; BIG_FUT_SIZE]);
+struct Big(#[allow(unused_tuple_struct_fields)] [u8; BIG_FUT_SIZE]);
 
 impl Big {
     fn new() -> Self {
diff --git a/src/test/ui/auto-traits/auto-traits.rs b/src/test/ui/auto-traits/auto-traits.rs
index 567b86c276274..7b52d9c176e88 100644
--- a/src/test/ui/auto-traits/auto-traits.rs
+++ b/src/test/ui/auto-traits/auto-traits.rs
@@ -9,7 +9,7 @@ unsafe auto trait AutoUnsafe {}
 impl !Auto for bool {}
 impl !AutoUnsafe for bool {}
 
-struct AutoBool(bool);
+struct AutoBool(#[allow(unused_tuple_struct_fields)] bool);
 
 impl Auto for AutoBool {}
 unsafe impl AutoUnsafe for AutoBool {}
diff --git a/src/test/ui/bench/issue-32062.rs b/src/test/ui/bench/issue-32062.rs
index dc45061da5b50..7eb52196e16e7 100644
--- a/src/test/ui/bench/issue-32062.rs
+++ b/src/test/ui/bench/issue-32062.rs
@@ -15,7 +15,7 @@ trait Parser {
     }
 }
 
-struct Token<T>(T::Item) where T: Iterator;
+struct Token<T>(#[allow(unused_tuple_struct_fields)] T::Item) where T: Iterator;
 
 impl<T> Parser for Token<T> where T: Iterator {
     type Input = T;
@@ -25,7 +25,7 @@ impl<T> Parser for Token<T> where T: Iterator {
     }
 }
 
-struct Chain<L, R>(L, R);
+struct Chain<L, R>(#[allow(unused_tuple_struct_fields)] L, #[allow(unused_tuple_struct_fields)] R);
 
 impl<L, R> Parser for Chain<L, R> where L: Parser, R: Parser<Input = L::Input> {
     type Input = L::Input;
diff --git a/src/test/ui/binding/match-tag.rs b/src/test/ui/binding/match-tag.rs
index eceb646778493..407716aa28af9 100644
--- a/src/test/ui/binding/match-tag.rs
+++ b/src/test/ui/binding/match-tag.rs
@@ -3,7 +3,7 @@
 #![allow(non_camel_case_types)]
 
 
-
+#[allow(unused_tuple_struct_fields)]
 enum color {
     rgb(isize, isize, isize),
     rgba(isize, isize, isize, isize),
diff --git a/src/test/ui/binding/or-pattern.rs b/src/test/ui/binding/or-pattern.rs
index 2ab44a96c3a4b..47623a3d72263 100644
--- a/src/test/ui/binding/or-pattern.rs
+++ b/src/test/ui/binding/or-pattern.rs
@@ -1,7 +1,7 @@
 // run-pass
 #![allow(non_camel_case_types)]
 
-enum blah { a(isize, isize, usize), b(isize, isize), c, }
+enum blah { a(isize, isize, #[allow(unused_tuple_struct_fields)] usize), b(isize, isize), c, }
 
 fn or_alt(q: blah) -> isize {
     match q { blah::a(x, y, _) | blah::b(x, y) => { return x + y; } blah::c => { return 0; } }
diff --git a/src/test/ui/binding/simple-generic-match.rs b/src/test/ui/binding/simple-generic-match.rs
index 50cfe19fef48d..2cf050d011dae 100644
--- a/src/test/ui/binding/simple-generic-match.rs
+++ b/src/test/ui/binding/simple-generic-match.rs
@@ -3,6 +3,6 @@
 
 // pretty-expanded FIXME #23616
 
-enum clam<T> { a(T), }
+enum clam<T> { a(#[allow(unused_tuple_struct_fields)] T), }
 
 pub fn main() { let c = clam::a(2); match c { clam::a::<isize>(_) => { } } }
diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs b/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs
index 117014b44ee11..cdde48871ea90 100644
--- a/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs
+++ b/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs
@@ -12,7 +12,7 @@ use trait_superkinds_in_metadata::RequiresCopy;
 use std::marker;
 
 #[derive(Copy, Clone)]
-struct X<T>(T);
+struct X<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T:Sync> RequiresShare for X<T> { }
 
diff --git a/src/test/ui/chalkify/builtin-copy-clone.rs b/src/test/ui/chalkify/builtin-copy-clone.rs
index 4323e87b08de7..7712e9465424b 100644
--- a/src/test/ui/chalkify/builtin-copy-clone.rs
+++ b/src/test/ui/chalkify/builtin-copy-clone.rs
@@ -4,7 +4,7 @@
 // Test that `Clone` is correctly implemented for builtin types.
 
 #[derive(Copy, Clone)]
-struct S(i32);
+struct S(#[allow(unused_tuple_struct_fields)] i32);
 
 fn test_clone<T: Clone>(arg: T) {
     let _ = arg.clone();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
index 2b86b0ddade23..173dd2e2cff2e 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
@@ -18,10 +18,10 @@ impl Foo {
     }
 }
 
-struct S(Foo);
+struct S(#[allow(unused_tuple_struct_fields)] Foo);
 
 #[derive(Clone)]
-struct T(i32);
+struct T(#[allow(unused_tuple_struct_fields)] i32);
 
 struct U(S, T);
 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
index 3cac4abfad7c2..cfc4555ca03a0 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
@@ -18,10 +18,10 @@ impl Foo {
     }
 }
 
-struct S(Foo);
+struct S(#[allow(unused_tuple_struct_fields)] Foo);
 
 #[derive(Clone)]
-struct T(i32);
+struct T(#[allow(unused_tuple_struct_fields)] i32);
 
 struct U(S, T);
 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
index 63e4000e833eb..e99dbb5ab3a4a 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
@@ -13,7 +13,7 @@ impl Drop for Foo {
 }
 
 #[derive(Debug)]
-struct ConstainsDropField(Foo, Foo);
+struct ConstainsDropField(Foo, #[allow(unused_tuple_struct_fields)] Foo);
 
 // `t` needs Drop because one of its elements needs drop,
 // therefore precise capture might affect drop ordering
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
index 9d9c54298cf11..62a984c9eebdd 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
@@ -13,7 +13,7 @@ impl Drop for Foo {
 }
 
 #[derive(Debug)]
-struct ConstainsDropField(Foo, Foo);
+struct ConstainsDropField(Foo, #[allow(unused_tuple_struct_fields)] Foo);
 
 // `t` needs Drop because one of its elements needs drop,
 // therefore precise capture might affect drop ordering
diff --git a/src/test/ui/codegen/issue-16602-3.rs b/src/test/ui/codegen/issue-16602-3.rs
index dbfeef053daa1..ca1ab3cc7feb9 100644
--- a/src/test/ui/codegen/issue-16602-3.rs
+++ b/src/test/ui/codegen/issue-16602-3.rs
@@ -2,6 +2,7 @@
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
 #[derive(Debug)]
+#[allow(unused_tuple_struct_fields)]
 enum Foo {
     Bar(u32, u32),
     Baz(&'static u32, &'static u32)
diff --git a/src/test/ui/coercion/issue-14589.rs b/src/test/ui/coercion/issue-14589.rs
index 5d8aab2ce74ce..d35ee5c731ecf 100644
--- a/src/test/ui/coercion/issue-14589.rs
+++ b/src/test/ui/coercion/issue-14589.rs
@@ -20,5 +20,5 @@ impl<T> Test<T> {
 }
 
 trait Foo { fn dummy(&self) { }}
-struct Output(isize);
+struct Output(#[allow(unused_tuple_struct_fields)] isize);
 impl Foo for Output {}
diff --git a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs b/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs
index aa0f9131aa7f5..c9e26c302bf57 100644
--- a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs
+++ b/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs
@@ -9,6 +9,7 @@ trait Foo {
     const ASSOC: usize = 1;
 }
 
+#[allow(unused_tuple_struct_fields)]
 struct Iced<T: Foo>(T, [(); T::ASSOC])
 where
     [(); T::ASSOC]: ;
diff --git a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs b/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs
index d0864414cc1fd..3017920fc98c3 100644
--- a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs
+++ b/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs
@@ -9,6 +9,7 @@ trait Foo {
     const ASSOC: usize = 1;
 }
 
+#[allow(unused_tuple_struct_fields)]
 struct Iced<T: Foo>(T, [(); T::ASSOC])
 where
     [(); T::ASSOC]: ;
diff --git a/src/test/ui/const-generics/const-argument-cross-crate.rs b/src/test/ui/const-generics/const-argument-cross-crate.rs
index fda3ec3eef799..5693409e99205 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate.rs
+++ b/src/test/ui/const-generics/const-argument-cross-crate.rs
@@ -4,7 +4,7 @@
 
 extern crate const_generic_lib;
 
-struct Container(const_generic_lib::Alias);
+struct Container(#[allow(unused_tuple_struct_fields)] const_generic_lib::Alias);
 
 fn main() {
     let res = const_generic_lib::function(const_generic_lib::Struct([14u8, 1u8, 2u8]));
diff --git a/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs b/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs
index 4d89f188ad777..b839008d424e9 100644
--- a/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs
+++ b/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs
@@ -16,7 +16,7 @@ impl BlockCipher for BarCipher {
     const BLOCK_SIZE: usize = 32;
 }
 
-pub struct Block<C>(C);
+pub struct Block<C>(#[allow(unused_tuple_struct_fields)] C);
 
 pub fn test<C: BlockCipher, const M: usize>()
 where
diff --git a/src/test/ui/consts/assoc-const.rs b/src/test/ui/consts/assoc-const.rs
index b70479d255b5f..f542f2dcb523f 100644
--- a/src/test/ui/consts/assoc-const.rs
+++ b/src/test/ui/consts/assoc-const.rs
@@ -6,7 +6,7 @@ trait Nat {
 }
 
 struct Zero;
-struct Succ<N>(N);
+struct Succ<N>(#[allow(unused_tuple_struct_fields)] N);
 
 impl Nat for Zero {
     const VALUE: usize = 0;
diff --git a/src/test/ui/consts/const-needs_drop.rs b/src/test/ui/consts/const-needs_drop.rs
index 58e801164428f..11ee7084ce88b 100644
--- a/src/test/ui/consts/const-needs_drop.rs
+++ b/src/test/ui/consts/const-needs_drop.rs
@@ -2,8 +2,10 @@
 
 use std::mem;
 
+#[allow(unused_tuple_struct_fields)]
 struct Trivial(u8, f32);
 
+#[allow(unused_tuple_struct_fields)]
 struct NonTrivial(u8, String);
 
 const CONST_U8: bool = mem::needs_drop::<u8>();
diff --git a/src/test/ui/consts/const-size_of_val-align_of_val.rs b/src/test/ui/consts/const-size_of_val-align_of_val.rs
index c3de6dc2075f8..e8323e4ae6003 100644
--- a/src/test/ui/consts/const-size_of_val-align_of_val.rs
+++ b/src/test/ui/consts/const-size_of_val-align_of_val.rs
@@ -5,7 +5,7 @@
 
 use std::{mem, ptr};
 
-struct Foo(u32);
+struct Foo(#[allow(unused_tuple_struct_fields)] u32);
 
 #[derive(Clone, Copy)]
 struct Bar {
diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs
index 51e1af359cdcc..15cf3c84d85f9 100644
--- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs
+++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs
@@ -15,7 +15,7 @@
 #![warn(indirect_structural_match)]
 
 #[derive(Copy, Clone, Debug)]
-struct NoDerive(u32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] u32);
 
 // This impl makes `NoDerive` irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
diff --git a/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs
index 9d44aa1361cfc..dd56faa318570 100644
--- a/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs
+++ b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs
@@ -1,7 +1,7 @@
 // run-pass
 
 const HASH_LEN: usize = 20;
-struct Hash([u8; HASH_LEN]);
+struct Hash(#[allow(unused_tuple_struct_fields)] [u8; HASH_LEN]);
 fn init_hash(_: &mut [u8; HASH_LEN]) {}
 
 fn foo<'a>() -> &'a () {
diff --git a/src/test/ui/consts/rvalue-static-promotion.rs b/src/test/ui/consts/rvalue-static-promotion.rs
index 2d7e4ab39893d..c48d9eae92879 100644
--- a/src/test/ui/consts/rvalue-static-promotion.rs
+++ b/src/test/ui/consts/rvalue-static-promotion.rs
@@ -4,7 +4,7 @@ use std::cell::Cell;
 
 const NONE_CELL_STRING: Option<Cell<String>> = None;
 
-struct Foo<T>(T);
+struct Foo<T>(#[allow(unused_tuple_struct_fields)] T);
 impl<T> Foo<T> {
     const FOO: Option<Box<T>> = None;
 }
diff --git a/src/test/ui/consts/transmute-const.rs b/src/test/ui/consts/transmute-const.rs
index 5044d99ec5183..c5c3dfc4cc7bd 100644
--- a/src/test/ui/consts/transmute-const.rs
+++ b/src/test/ui/consts/transmute-const.rs
@@ -3,7 +3,7 @@
 use std::mem;
 
 #[repr(transparent)]
-struct Foo(u32);
+struct Foo(#[allow(unused_tuple_struct_fields)] u32);
 
 const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) };
 
diff --git a/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs
index 8b9840de172da..3480ccc10899e 100644
--- a/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs
+++ b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs
@@ -2,6 +2,7 @@
 // pretty-expanded FIXME #23616
 
 #[derive(Clone)]
+#[allow(unused_tuple_struct_fields)]
 struct S<T>(T, ());
 
 pub fn main() {
diff --git a/src/test/ui/deriving/deriving-copyclone.rs b/src/test/ui/deriving/deriving-copyclone.rs
index 78d74a11ffc8b..f8403b1feacbd 100644
--- a/src/test/ui/deriving/deriving-copyclone.rs
+++ b/src/test/ui/deriving/deriving-copyclone.rs
@@ -23,7 +23,7 @@ impl Clone for Liar {
 
 /// This struct is actually Copy... at least, it thinks it is!
 #[derive(Copy, Clone)]
-struct Innocent(Liar);
+struct Innocent(#[allow(unused_tuple_struct_fields)] Liar);
 
 impl Innocent {
     fn new() -> Self {
diff --git a/src/test/ui/deriving/issue-58319.rs b/src/test/ui/deriving/issue-58319.rs
index 757307d944f18..8041bd5bb3c65 100644
--- a/src/test/ui/deriving/issue-58319.rs
+++ b/src/test/ui/deriving/issue-58319.rs
@@ -3,6 +3,7 @@ fn main() {}
 #[derive(Clone)]
 pub struct Little;
 #[derive(Clone)]
+#[allow(unused_tuple_struct_fields)]
 pub struct Big(
     Little,
     Little,
diff --git a/src/test/ui/drop/dropck-eyepatch-reorder.rs b/src/test/ui/drop/dropck-eyepatch-reorder.rs
index b4605878a54e3..0d7af3d4f61a8 100644
--- a/src/test/ui/drop/dropck-eyepatch-reorder.rs
+++ b/src/test/ui/drop/dropck-eyepatch-reorder.rs
@@ -12,10 +12,10 @@ trait Foo { fn foo(&self, _: &str); }
 
 struct Dt<A: Foo>(&'static str, A);
 struct Dr<'a, B:'a+Foo>(&'static str, &'a B);
-struct Pt<A: Foo, B: Foo>(&'static str, A, B);
-struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, &'a B, &'b B);
-struct St<A: Foo>(&'static str, A);
-struct Sr<'a, B:'a+Foo>(&'static str, &'a B);
+struct Pt<A: Foo, B: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A, B);
+struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B, &'b B);
+struct St<A: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A);
+struct Sr<'a, B:'a+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B);
 
 impl<A: Foo> Drop for Dt<A> {
     fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); }
diff --git a/src/test/ui/drop/dropck-eyepatch.rs b/src/test/ui/drop/dropck-eyepatch.rs
index 9255391e41206..3c4840d5c7a30 100644
--- a/src/test/ui/drop/dropck-eyepatch.rs
+++ b/src/test/ui/drop/dropck-eyepatch.rs
@@ -35,10 +35,10 @@ trait Foo { fn foo(&self, _: &str); }
 
 struct Dt<A: Foo>(&'static str, A);
 struct Dr<'a, B:'a+Foo>(&'static str, &'a B);
-struct Pt<A,B: Foo>(&'static str, A, B);
-struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, &'a B, &'b B);
-struct St<A: Foo>(&'static str, A);
-struct Sr<'a, B:'a+Foo>(&'static str, &'a B);
+struct Pt<A,B: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A, B);
+struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B, &'b B);
+struct St<A: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A);
+struct Sr<'a, B:'a+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B);
 
 impl<A: Foo> Drop for Dt<A> {
     fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); }
diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs
index 736123ed1198f..e706867742337 100644
--- a/src/test/ui/drop/dynamic-drop.rs
+++ b/src/test/ui/drop/dynamic-drop.rs
@@ -103,7 +103,7 @@ fn dynamic_drop(a: &Allocator, c: bool) {
     };
 }
 
-struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>);
+struct TwoPtrs<'a>(Ptr<'a>, #[allow(unused_tuple_struct_fields)] Ptr<'a>);
 fn struct_dynamic_drop(a: &Allocator, c0: bool, c1: bool, c: bool) {
     for i in 0..2 {
         let x;
diff --git a/src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs
index 23fd86a093b59..04d0d32033a12 100644
--- a/src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs
+++ b/src/test/ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs
@@ -21,7 +21,7 @@ impl Drop for ScribbleOnDrop {
     }
 }
 
-struct Foo<T>(u32, T, Box<for <'r> fn(&'r T) -> String>);
+struct Foo<T>(u32, T, #[allow(unused_tuple_struct_fields)] Box<for <'r> fn(&'r T) -> String>);
 
 unsafe impl<#[may_dangle] T> Drop for Foo<T> {
     fn drop(&mut self) {
diff --git a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
index 65dc9166330d1..8e162d5c45512 100644
--- a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
+++ b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
@@ -4,6 +4,7 @@
 
 use std::mem;
 
+#[allow(unused_tuple_struct_fields)]
 enum ADT {
     First(u32, u32),
     Second(u64)
diff --git a/src/test/ui/enum-discriminant/discriminant_value.rs b/src/test/ui/enum-discriminant/discriminant_value.rs
index eb60aaf4b2d04..65ab411dbcbe6 100644
--- a/src/test/ui/enum-discriminant/discriminant_value.rs
+++ b/src/test/ui/enum-discriminant/discriminant_value.rs
@@ -27,13 +27,14 @@ enum CLike3 {
     D
 }
 
+#[allow(unused_tuple_struct_fields)]
 enum ADT {
     First(u32, u32),
     Second(u64)
 }
 
 enum NullablePointer {
-    Something(&'static u32),
+    Something(#[allow(unused_tuple_struct_fields)] &'static u32),
     Nothing
 }
 
diff --git a/src/test/ui/generator/size-moved-locals.rs b/src/test/ui/generator/size-moved-locals.rs
index 74c60d98154dd..3c756a86fc5a5 100644
--- a/src/test/ui/generator/size-moved-locals.rs
+++ b/src/test/ui/generator/size-moved-locals.rs
@@ -18,7 +18,7 @@
 use std::ops::Generator;
 
 const FOO_SIZE: usize = 1024;
-struct Foo([u8; FOO_SIZE]);
+struct Foo(#[allow(unused_tuple_struct_fields)] [u8; FOO_SIZE]);
 
 impl Drop for Foo {
     fn drop(&mut self) {}
diff --git a/src/test/ui/generics/generic-default-type-params-cross-crate.rs b/src/test/ui/generics/generic-default-type-params-cross-crate.rs
index 9e5eaa72c152f..834b15be1c59d 100644
--- a/src/test/ui/generics/generic-default-type-params-cross-crate.rs
+++ b/src/test/ui/generics/generic-default-type-params-cross-crate.rs
@@ -5,7 +5,7 @@
 
 extern crate default_type_params_xc;
 
-struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
+struct Vec<T, A = default_type_params_xc::Heap>(#[allow(unused_tuple_struct_fields)] Option<(T,A)>);
 
 struct Foo;
 
diff --git a/src/test/ui/generics/generic-ivec-leak.rs b/src/test/ui/generics/generic-ivec-leak.rs
index a8ea1d5069bcf..9610bdcb3382e 100644
--- a/src/test/ui/generics/generic-ivec-leak.rs
+++ b/src/test/ui/generics/generic-ivec-leak.rs
@@ -1,5 +1,5 @@
 // run-pass
 #![allow(non_camel_case_types)]
-enum wrapper<T> { wrapped(T), }
+enum wrapper<T> { wrapped(#[allow(unused_tuple_struct_fields)] T), }
 
 pub fn main() { let _w = wrapper::wrapped(vec![1, 2, 3, 4, 5]); }
diff --git a/src/test/ui/generics/generic-newtype-struct.rs b/src/test/ui/generics/generic-newtype-struct.rs
index 570c982cc8700..aa879f01a583f 100644
--- a/src/test/ui/generics/generic-newtype-struct.rs
+++ b/src/test/ui/generics/generic-newtype-struct.rs
@@ -1,7 +1,7 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-struct S<T>(T);
+struct S<T>(#[allow(unused_tuple_struct_fields)] T);
 
 pub fn main() {
     let _s = S(2);
diff --git a/src/test/ui/generics/generic-no-mangle.fixed b/src/test/ui/generics/generic-no-mangle.fixed
index 9126ac167cf2a..501acb6e1638a 100644
--- a/src/test/ui/generics/generic-no-mangle.fixed
+++ b/src/test/ui/generics/generic-no-mangle.fixed
@@ -76,7 +76,7 @@ impl<T> Trait2<T> for Foo {
     fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
 }
 
-pub struct Bar<T>(T);
+pub struct Bar<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T> Bar<T> {
     
@@ -111,7 +111,7 @@ impl<T> Trait3 for Bar<T> {
     fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
 }
 
-pub struct Baz<'a>(&'a i32);
+pub struct Baz<'a>(#[allow(unused_tuple_struct_fields)] &'a i32);
 
 impl<'a> Baz<'a> {
     #[no_mangle]
diff --git a/src/test/ui/generics/generic-no-mangle.rs b/src/test/ui/generics/generic-no-mangle.rs
index e283cf4bfe544..74e407078e8b1 100644
--- a/src/test/ui/generics/generic-no-mangle.rs
+++ b/src/test/ui/generics/generic-no-mangle.rs
@@ -76,7 +76,7 @@ impl<T> Trait2<T> for Foo {
     fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
 }
 
-pub struct Bar<T>(T);
+pub struct Bar<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T> Bar<T> {
     #[no_mangle]
@@ -111,7 +111,7 @@ impl<T> Trait3 for Bar<T> {
     fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
 }
 
-pub struct Baz<'a>(&'a i32);
+pub struct Baz<'a>(#[allow(unused_tuple_struct_fields)] &'a i32);
 
 impl<'a> Baz<'a> {
     #[no_mangle]
diff --git a/src/test/ui/generics/generic-recursive-tag.rs b/src/test/ui/generics/generic-recursive-tag.rs
index 74f5b701d98a5..b344da1c7ddeb 100644
--- a/src/test/ui/generics/generic-recursive-tag.rs
+++ b/src/test/ui/generics/generic-recursive-tag.rs
@@ -1,7 +1,7 @@
 // run-pass
 #![allow(non_camel_case_types)]
 
-enum list<T> { cons(Box<T>, Box<list<T>>), nil, }
+enum list<T> { #[allow(unused_tuple_struct_fields)] cons(Box<T>, Box<list<T>>), nil, }
 
 pub fn main() {
     let _a: list<isize> =
diff --git a/src/test/ui/generics/generic-tag-corruption.rs b/src/test/ui/generics/generic-tag-corruption.rs
index aa26183a0d491..35de3c1f71246 100644
--- a/src/test/ui/generics/generic-tag-corruption.rs
+++ b/src/test/ui/generics/generic-tag-corruption.rs
@@ -5,6 +5,6 @@
 // This used to cause memory corruption in stage 0.
 // pretty-expanded FIXME #23616
 
-enum thing<K> { some(K), }
+enum thing<K> { some(#[allow(unused_tuple_struct_fields)] K), }
 
 pub fn main() { let _x = thing::some("hi".to_string()); }
diff --git a/src/test/ui/generics/generic-tag-local.rs b/src/test/ui/generics/generic-tag-local.rs
index cc85e6e0f0a8d..c5772e84193ac 100644
--- a/src/test/ui/generics/generic-tag-local.rs
+++ b/src/test/ui/generics/generic-tag-local.rs
@@ -3,6 +3,6 @@
 
 // pretty-expanded FIXME #23616
 
-enum clam<T> { a(T), }
+enum clam<T> { a(#[allow(unused_tuple_struct_fields)] T), }
 
 pub fn main() { let _c = clam::a(3); }
diff --git a/src/test/ui/generics/generic-tag.rs b/src/test/ui/generics/generic-tag.rs
index 67f2ccdde34a1..31fc2178d6d63 100644
--- a/src/test/ui/generics/generic-tag.rs
+++ b/src/test/ui/generics/generic-tag.rs
@@ -6,7 +6,7 @@
 
 #![allow(unused_variables)]
 
-enum option<T> { some(Box<T>), none, }
+enum option<T> { some(#[allow(unused_tuple_struct_fields)] Box<T>), none, }
 
 pub fn main() {
     let mut a: option<isize> = option::some::<isize>(Box::new(10));
diff --git a/src/test/ui/impl-trait/bounds_regression.rs b/src/test/ui/impl-trait/bounds_regression.rs
index 0fdeb6bdee1cb..31fc46203d329 100644
--- a/src/test/ui/impl-trait/bounds_regression.rs
+++ b/src/test/ui/impl-trait/bounds_regression.rs
@@ -15,7 +15,7 @@ pub fn future_from_generator<
     GenFuture(x)
 }
 
-struct GenFuture<T: FakeGenerator<Yield = ()>>(T);
+struct GenFuture<T: FakeGenerator<Yield = ()>>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T: FakeGenerator<Yield = ()>> FakeFuture for GenFuture<T> {
     type Output = T::Return;
diff --git a/src/test/ui/issues/issue-13027.rs b/src/test/ui/issues/issue-13027.rs
index 1bab82a543f05..64bf2a11d0ecd 100644
--- a/src/test/ui/issues/issue-13027.rs
+++ b/src/test/ui/issues/issue-13027.rs
@@ -164,7 +164,7 @@ fn range_shadow_multi_pats() {
 
 fn misc() {
     enum Foo {
-        Bar(usize, bool)
+        Bar(#[allow(unused_tuple_struct_fields)] usize, bool)
     }
     // This test basically mimics how trace_macros! macro is implemented,
     // which is a rare combination of vector patterns, multiple wild-card
diff --git a/src/test/ui/issues/issue-14382.rs b/src/test/ui/issues/issue-14382.rs
index 671e7a2266742..dca24d0be8a2a 100644
--- a/src/test/ui/issues/issue-14382.rs
+++ b/src/test/ui/issues/issue-14382.rs
@@ -1,6 +1,6 @@
 // run-pass
 #[derive(Debug)]
-struct Matrix4<S>(S);
+struct Matrix4<S>(#[allow(unused_tuple_struct_fields)] S);
 trait POrd<S> {}
 
 fn translate<S: POrd<S>>(s: S) -> Matrix4<S> { Matrix4(s) }
diff --git a/src/test/ui/issues/issue-15858.rs b/src/test/ui/issues/issue-15858.rs
index 41d2f13952ae0..8d65afc4883d7 100644
--- a/src/test/ui/issues/issue-15858.rs
+++ b/src/test/ui/issues/issue-15858.rs
@@ -12,7 +12,7 @@ impl Bar for BarImpl {
 }
 
 
-struct Foo<B: Bar>(B);
+struct Foo<B: Bar>(#[allow(unused_tuple_struct_fields)] B);
 
 impl<B: Bar> Drop for Foo<B> {
     fn drop(&mut self) {
diff --git a/src/test/ui/issues/issue-17905.rs b/src/test/ui/issues/issue-17905.rs
index 95133a4584430..dae9648b9173f 100644
--- a/src/test/ui/issues/issue-17905.rs
+++ b/src/test/ui/issues/issue-17905.rs
@@ -1,6 +1,7 @@
 // run-pass
 
 #[derive(Debug)]
+#[allow(unused_tuple_struct_fields)]
 struct Pair<T, V> (T, V);
 
 impl Pair<
diff --git a/src/test/ui/issues/issue-2063.rs b/src/test/ui/issues/issue-2063.rs
index 9dbac6ccee1d1..f08f9d4cfe410 100644
--- a/src/test/ui/issues/issue-2063.rs
+++ b/src/test/ui/issues/issue-2063.rs
@@ -3,7 +3,7 @@
 // cause compiler to loop.  Note that no instances
 // of such a type could ever be constructed.
 
-struct T(Box<T>);
+struct T(#[allow(unused_tuple_struct_fields)] Box<T>);
 
 trait ToStr2 {
     fn my_to_string(&self) -> String;
diff --git a/src/test/ui/issues/issue-23491.rs b/src/test/ui/issues/issue-23491.rs
index d2ded88aeff19..1cb969731e29c 100644
--- a/src/test/ui/issues/issue-23491.rs
+++ b/src/test/ui/issues/issue-23491.rs
@@ -2,7 +2,7 @@
 #![allow(unused_variables)]
 #![feature(box_syntax)]
 
-struct Node<T: ?Sized>(T);
+struct Node<T: ?Sized>(#[allow(unused_tuple_struct_fields)] T);
 
 fn main() {
     let x: Box<Node<[isize]>> = box Node([]);
diff --git a/src/test/ui/issues/issue-24308.rs b/src/test/ui/issues/issue-24308.rs
index 9c39a5d22387d..4a582c68efc9b 100644
--- a/src/test/ui/issues/issue-24308.rs
+++ b/src/test/ui/issues/issue-24308.rs
@@ -4,7 +4,7 @@ pub trait Foo {
     fn method2();
 }
 
-struct Slice<'a, T: 'a>(&'a [T]);
+struct Slice<'a, T: 'a>(#[allow(unused_tuple_struct_fields)] &'a [T]);
 
 impl<'a, T: 'a> Foo for Slice<'a, T> {
     fn method2() {
diff --git a/src/test/ui/issues/issue-24805-dropck-itemless.rs b/src/test/ui/issues/issue-24805-dropck-itemless.rs
index 555eefeb3a1f8..45761b61c3e95 100644
--- a/src/test/ui/issues/issue-24805-dropck-itemless.rs
+++ b/src/test/ui/issues/issue-24805-dropck-itemless.rs
@@ -19,7 +19,7 @@ impl<'a, T> UserDefined for &'a T { }
 //   ```
 macro_rules! impl_drop {
     ($Bound:ident, $Id:ident) => {
-        struct $Id<T: $Bound>(T);
+        struct $Id<T: $Bound>(#[allow(unused_tuple_struct_fields)] T);
         unsafe impl <#[may_dangle] T: $Bound> Drop for $Id<T> {
             fn drop(&mut self) { }
         }
diff --git a/src/test/ui/issues/issue-25089.rs b/src/test/ui/issues/issue-25089.rs
index 0f0f78623a212..c988f8f55fa47 100644
--- a/src/test/ui/issues/issue-25089.rs
+++ b/src/test/ui/issues/issue-25089.rs
@@ -4,7 +4,7 @@
 
 use std::thread;
 
-struct Foo(i32);
+struct Foo(#[allow(unused_tuple_struct_fields)] i32);
 
 impl Drop for Foo {
     fn drop(&mut self) {
diff --git a/src/test/ui/issues/issue-25679.rs b/src/test/ui/issues/issue-25679.rs
index 89544c9eb88c9..b548da9888887 100644
--- a/src/test/ui/issues/issue-25679.rs
+++ b/src/test/ui/issues/issue-25679.rs
@@ -2,6 +2,7 @@
 trait Device {
     type Resources;
 }
+#[allow(unused_tuple_struct_fields)]
 struct Foo<D, R>(D, R);
 
 impl<D: Device> Foo<D, D::Resources> {
diff --git a/src/test/ui/issues/issue-25700-1.rs b/src/test/ui/issues/issue-25700-1.rs
index 7bc9673a5be36..5e71a52ba4e96 100644
--- a/src/test/ui/issues/issue-25700-1.rs
+++ b/src/test/ui/issues/issue-25700-1.rs
@@ -1,5 +1,5 @@
 // run-pass
-struct S<T: 'static>(Option<&'static T>);
+struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
 
 trait Tr { type Out; }
 impl<T> Tr for T { type Out = T; }
diff --git a/src/test/ui/issues/issue-25700-2.rs b/src/test/ui/issues/issue-25700-2.rs
index b161e68abafd0..89b1db496f95c 100644
--- a/src/test/ui/issues/issue-25700-2.rs
+++ b/src/test/ui/issues/issue-25700-2.rs
@@ -3,8 +3,9 @@ pub trait Parser {
     type Input;
 }
 
-pub struct Iter<P: Parser>(P, P::Input);
+pub struct Iter<P: Parser>(#[allow(unused_tuple_struct_fields)] P, P::Input);
 
+#[allow(unused_tuple_struct_fields)]
 pub struct Map<P, F>(P, F);
 impl<P, F> Parser for Map<P, F> where F: FnMut(P) {
     type Input = u8;
diff --git a/src/test/ui/issues/issue-25700.rs b/src/test/ui/issues/issue-25700.rs
index 45c452d618d84..e5b9a97523dfd 100644
--- a/src/test/ui/issues/issue-25700.rs
+++ b/src/test/ui/issues/issue-25700.rs
@@ -1,4 +1,4 @@
-struct S<T: 'static>(Option<&'static T>);
+struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
 
 trait Tr { type Out; }
 impl<T> Tr for T { type Out = T; }
diff --git a/src/test/ui/issues/issue-26127.rs b/src/test/ui/issues/issue-26127.rs
index cb479a2308599..f3f9c1d9ae821 100644
--- a/src/test/ui/issues/issue-26127.rs
+++ b/src/test/ui/issues/issue-26127.rs
@@ -1,7 +1,7 @@
 // run-pass
 trait Tr { type T; }
 impl Tr for u8 { type T=(); }
-struct S<I: Tr>(I::T);
+struct S<I: Tr>(#[allow(unused_tuple_struct_fields)] I::T);
 
 fn foo<I: Tr>(i: I::T) {
     S::<I>(i);
diff --git a/src/test/ui/issues/issue-26641.rs b/src/test/ui/issues/issue-26641.rs
index 4b6f2c2b3bc7d..e08edd0b5cb67 100644
--- a/src/test/ui/issues/issue-26641.rs
+++ b/src/test/ui/issues/issue-26641.rs
@@ -1,5 +1,5 @@
 // run-pass
-struct Parser<'a>(Box<dyn FnMut(Parser) + 'a>);
+struct Parser<'a>(#[allow(unused_tuple_struct_fields)] Box<dyn FnMut(Parser) + 'a>);
 
 fn main() {
     let _x = Parser(Box::new(|_|{}));
diff --git a/src/test/ui/issues/issue-26709.rs b/src/test/ui/issues/issue-26709.rs
index 281ae13399dd2..1bd2651dd6c12 100644
--- a/src/test/ui/issues/issue-26709.rs
+++ b/src/test/ui/issues/issue-26709.rs
@@ -1,5 +1,5 @@
 // run-pass
-struct Wrapper<'a, T: ?Sized>(&'a mut i32, T);
+struct Wrapper<'a, T: ?Sized>(&'a mut i32, #[allow(unused_tuple_struct_fields)] T);
 
 impl<'a, T: ?Sized> Drop for Wrapper<'a, T> {
     fn drop(&mut self) {
diff --git a/src/test/ui/issues/issue-27240.rs b/src/test/ui/issues/issue-27240.rs
index a22db76b9bc4d..eaf254f336193 100644
--- a/src/test/ui/issues/issue-27240.rs
+++ b/src/test/ui/issues/issue-27240.rs
@@ -2,12 +2,12 @@
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 use std::fmt;
-struct NoisyDrop<T: fmt::Debug>(T);
+struct NoisyDrop<T: fmt::Debug>(#[allow(unused_tuple_struct_fields)] T);
 impl<T: fmt::Debug> Drop for NoisyDrop<T> {
     fn drop(&mut self) {}
 }
 
-struct Bar<T: fmt::Debug>([*const NoisyDrop<T>; 2]);
+struct Bar<T: fmt::Debug>(#[allow(unused_tuple_struct_fields)] [*const NoisyDrop<T>; 2]);
 
 fn fine() {
     let (u,b);
@@ -15,6 +15,7 @@ fn fine() {
     b = Bar([&NoisyDrop(&u), &NoisyDrop(&u)]);
 }
 
+#[allow(unused_tuple_struct_fields)]
 struct Bar2<T: fmt::Debug>(*const NoisyDrop<T>, *const NoisyDrop<T>);
 
 fn lolwut() {
diff --git a/src/test/ui/issues/issue-28498-must-work-ex1.rs b/src/test/ui/issues/issue-28498-must-work-ex1.rs
index 4699d3352ad20..ab6d190e0a153 100644
--- a/src/test/ui/issues/issue-28498-must-work-ex1.rs
+++ b/src/test/ui/issues/issue-28498-must-work-ex1.rs
@@ -6,7 +6,7 @@
 
 use std::cell::Cell;
 
-struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
+struct Concrete<'a>(#[allow(unused_tuple_struct_fields)] u32, Cell<Option<&'a Concrete<'a>>>);
 
 fn main() {
     let mut data = Vec::new();
diff --git a/src/test/ui/issues/issue-28498-must-work-ex2.rs b/src/test/ui/issues/issue-28498-must-work-ex2.rs
index cadf62461fdf5..378d736ee3d9b 100644
--- a/src/test/ui/issues/issue-28498-must-work-ex2.rs
+++ b/src/test/ui/issues/issue-28498-must-work-ex2.rs
@@ -6,7 +6,7 @@
 
 use std::cell::Cell;
 
-struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
+struct Concrete<'a>(#[allow(unused_tuple_struct_fields)] u32, Cell<Option<&'a Concrete<'a>>>);
 
 struct Foo<T> { data: Vec<T> }
 
diff --git a/src/test/ui/issues/issue-28498-ugeh-ex1.rs b/src/test/ui/issues/issue-28498-ugeh-ex1.rs
index 90cf2cddcf02a..24bf706cef9da 100644
--- a/src/test/ui/issues/issue-28498-ugeh-ex1.rs
+++ b/src/test/ui/issues/issue-28498-ugeh-ex1.rs
@@ -8,7 +8,7 @@
 #![feature(dropck_eyepatch)]
 use std::cell::Cell;
 
-struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
+struct Concrete<'a>(#[allow(unused_tuple_struct_fields)] u32, Cell<Option<&'a Concrete<'a>>>);
 
 struct Foo<T> { data: Vec<T> }
 
diff --git a/src/test/ui/issues/issue-29147-rpass.rs b/src/test/ui/issues/issue-29147-rpass.rs
index 101bca307f1ab..439f8bb5308f2 100644
--- a/src/test/ui/issues/issue-29147-rpass.rs
+++ b/src/test/ui/issues/issue-29147-rpass.rs
@@ -1,5 +1,6 @@
 // run-pass
 #![recursion_limit="1024"]
+#![allow(dead_code)]
 
 use std::mem;
 
diff --git a/src/test/ui/issues/issue-29147.rs b/src/test/ui/issues/issue-29147.rs
index 271bc526033d4..190ecf46009ff 100644
--- a/src/test/ui/issues/issue-29147.rs
+++ b/src/test/ui/issues/issue-29147.rs
@@ -1,4 +1,5 @@
 #![recursion_limit="1024"]
+#![allow(dead_code)]
 
 pub struct S0<T>(T,T);
 pub struct S1<T>(Option<Box<S0<S0<T>>>>,Option<Box<S0<S0<T>>>>);
diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr
index 5570e887edce5..138d477dc6b29 100644
--- a/src/test/ui/issues/issue-29147.stderr
+++ b/src/test/ui/issues/issue-29147.stderr
@@ -1,11 +1,11 @@
 error[E0283]: type annotations needed
-  --> $DIR/issue-29147.rs:21:13
+  --> $DIR/issue-29147.rs:22:13
    |
 LL |     let _ = <S5<_>>::xxx;
    |             ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
    |
 note: multiple `impl`s satisfying `S5<_>: Foo` found
-  --> $DIR/issue-29147.rs:17:1
+  --> $DIR/issue-29147.rs:18:1
    |
 LL | impl Foo for S5<u32> { fn xxx(&self) {} }
    | ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-31267-additional.rs b/src/test/ui/issues/issue-31267-additional.rs
index 70dce2c949035..7f0cbd658f117 100644
--- a/src/test/ui/issues/issue-31267-additional.rs
+++ b/src/test/ui/issues/issue-31267-additional.rs
@@ -6,7 +6,7 @@ struct Bar;
 const BAZ: Bar = Bar;
 
 #[derive(Debug)]
-struct Foo([Bar; 1]);
+struct Foo(#[allow(unused_tuple_struct_fields)] [Bar; 1]);
 
 struct Biz;
 
diff --git a/src/test/ui/issues/issue-31299.rs b/src/test/ui/issues/issue-31299.rs
index d93ffcb2262eb..78c3252d32e81 100644
--- a/src/test/ui/issues/issue-31299.rs
+++ b/src/test/ui/issues/issue-31299.rs
@@ -25,9 +25,9 @@ impl<T> Front for Vec<T> {
     type Back = Vec<T>;
 }
 
-struct PtrBack<T: Front>(Vec<T::Back>);
+struct PtrBack<T: Front>(#[allow(unused_tuple_struct_fields)] Vec<T::Back>);
 
-struct M(PtrBack<Vec<M>>);
+struct M(#[allow(unused_tuple_struct_fields)] PtrBack<Vec<M>>);
 
 #[allow(unused_must_use)]
 fn main() {
diff --git a/src/test/ui/issues/issue-34571.rs b/src/test/ui/issues/issue-34571.rs
index bad1bebc69754..5498091da58e3 100644
--- a/src/test/ui/issues/issue-34571.rs
+++ b/src/test/ui/issues/issue-34571.rs
@@ -1,7 +1,7 @@
 // run-pass
 #[repr(u8)]
 enum Foo {
-    Foo(u8),
+    Foo(#[allow(unused_tuple_struct_fields)] u8),
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-36053.rs b/src/test/ui/issues/issue-36053.rs
index a61c02c0a12c9..5c6d078041600 100644
--- a/src/test/ui/issues/issue-36053.rs
+++ b/src/test/ui/issues/issue-36053.rs
@@ -7,7 +7,7 @@
 
 use std::iter::FusedIterator;
 
-struct Thing<'a>(&'a str);
+struct Thing<'a>(#[allow(unused_tuple_struct_fields)] &'a str);
 impl<'a> Iterator for Thing<'a> {
     type Item = &'a str;
     fn next(&mut self) -> Option<&'a str> {
diff --git a/src/test/ui/issues/issue-36278-prefix-nesting.rs b/src/test/ui/issues/issue-36278-prefix-nesting.rs
index 62d1f5f825886..a809f7f132937 100644
--- a/src/test/ui/issues/issue-36278-prefix-nesting.rs
+++ b/src/test/ui/issues/issue-36278-prefix-nesting.rs
@@ -5,6 +5,7 @@
 use std::mem;
 
 const SZ: usize = 100;
+#[allow(unused_tuple_struct_fields)]
 struct P<T: ?Sized>([u8; SZ], T);
 
 type Ack<T> = P<P<T>>;
diff --git a/src/test/ui/issues/issue-40003.rs b/src/test/ui/issues/issue-40003.rs
index 642de6b8fe352..5e61361f9877a 100644
--- a/src/test/ui/issues/issue-40003.rs
+++ b/src/test/ui/issues/issue-40003.rs
@@ -153,7 +153,7 @@ mod stream {
     }
 
     enum Slot<T> {
-        Next(usize),
+        Next(#[allow(unused_tuple_struct_fields)] usize),
         _Data { _a: T },
     }
 
diff --git a/src/test/ui/issues/issue-4252.rs b/src/test/ui/issues/issue-4252.rs
index 48e617fd7ebb5..0d47a7f0c16c2 100644
--- a/src/test/ui/issues/issue-4252.rs
+++ b/src/test/ui/issues/issue-4252.rs
@@ -7,7 +7,7 @@ trait X {
 }
 
 #[derive(Debug)]
-struct Y(isize);
+struct Y(#[allow(unused_tuple_struct_fields)] isize);
 
 #[derive(Debug)]
 struct Z<T: X+std::fmt::Debug> {
diff --git a/src/test/ui/issues/issue-46069.rs b/src/test/ui/issues/issue-46069.rs
index 1d4f789828d8b..c418128c1866f 100644
--- a/src/test/ui/issues/issue-46069.rs
+++ b/src/test/ui/issues/issue-46069.rs
@@ -2,7 +2,7 @@
 use std::iter::{Fuse, Cloned};
 use std::slice::Iter;
 
-struct Foo<'a, T: 'a>(&'a T);
+struct Foo<'a, T: 'a>(#[allow(unused_tuple_struct_fields)] &'a T);
 impl<'a, T: 'a> Copy for Foo<'a, T> {}
 impl<'a, T: 'a> Clone for Foo<'a, T> {
     fn clone(&self) -> Self { *self }
diff --git a/src/test/ui/issues/issue-5315.rs b/src/test/ui/issues/issue-5315.rs
index 38c98254b9350..0c121a5eee638 100644
--- a/src/test/ui/issues/issue-5315.rs
+++ b/src/test/ui/issues/issue-5315.rs
@@ -1,7 +1,7 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-struct A(bool);
+struct A(#[allow(unused_tuple_struct_fields)] bool);
 
 pub fn main() {
     let f = A;
diff --git a/src/test/ui/issues/issue-61894.rs b/src/test/ui/issues/issue-61894.rs
index c018ac73fb536..776fdbb7466f7 100644
--- a/src/test/ui/issues/issue-61894.rs
+++ b/src/test/ui/issues/issue-61894.rs
@@ -4,7 +4,7 @@
 
 use std::any::type_name;
 
-struct Bar<M>(M);
+struct Bar<M>(#[allow(unused_tuple_struct_fields)] M);
 
 impl<M> Bar<M> {
     fn foo(&self) -> &'static str {
diff --git a/src/test/ui/issues/issue-7911.rs b/src/test/ui/issues/issue-7911.rs
index de833324bd20f..f64887136cad6 100644
--- a/src/test/ui/issues/issue-7911.rs
+++ b/src/test/ui/issues/issue-7911.rs
@@ -6,7 +6,7 @@
 trait FooBar {
     fn dummy(&self) { }
 }
-struct Bar(i32);
+struct Bar(#[allow(unused_tuple_struct_fields)] i32);
 struct Foo { bar: Bar }
 
 impl FooBar for Bar {}
diff --git a/src/test/ui/layout/unsafe-cell-hides-niche.rs b/src/test/ui/layout/unsafe-cell-hides-niche.rs
index 73b32066fadcd..68bcc3c1aff0e 100644
--- a/src/test/ui/layout/unsafe-cell-hides-niche.rs
+++ b/src/test/ui/layout/unsafe-cell-hides-niche.rs
@@ -14,10 +14,10 @@ use std::mem::size_of;
 use std::num::NonZeroU32 as N32;
 use std::sync::{Mutex, RwLock};
 
-struct Wrapper<T>(T);
+struct Wrapper<T>(#[allow(unused_tuple_struct_fields)] T);
 
 #[repr(transparent)]
-struct Transparent<T>(T);
+struct Transparent<T>(#[allow(unused_tuple_struct_fields)] T);
 
 struct NoNiche<T>(UnsafeCell<T>);
 
diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs
index c8fd32c64d6db..b15d706368633 100644
--- a/src/test/ui/lint/dead-code/tuple-struct-field.rs
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs
@@ -1,12 +1,37 @@
-// check-pass
+#![deny(unused_tuple_struct_fields)]
+//~^ NOTE: the lint level is defined here
 
-#![deny(dead_code)]
+use std::marker::PhantomData;
 
 const LEN: usize = 4;
 
-#[derive(Debug)]
-struct Wrapper([u8; LEN]);
+struct SingleUnused(i32, [u8; LEN], String);
+//~^ ERROR: field `1` is never read
+//~| NOTE: field in this struct
+//~| HELP: consider changing the field to be of unit type
+
+struct MultipleUnused(i32, f32, String, u8);
+//~^ ERROR: fields `0`, `1`, `2` and `3` are never read
+//~| NOTE: fields in this struct
+//~| HELP: consider changing the fields to be of unit type
+
+struct GoodUnit(());
+
+struct GoodPhantom(PhantomData<i32>);
+
+struct Void;
+struct GoodVoid(Void);
 
 fn main() {
-    println!("{:?}", Wrapper([0, 1, 2, 3]));
+    let w = SingleUnused(42, [0, 1, 2, 3], "abc".to_string());
+    let _ = w.0;
+    let _ = w.2;
+
+    let m = MultipleUnused(42, 3.14, "def".to_string(), 4u8);
+
+    let gu = GoodUnit(());
+    let gp = GoodPhantom(PhantomData);
+    let gv = GoodVoid(Void);
+
+    let _ = (gu, gp, gv, m);
 }
diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.stderr b/src/test/ui/lint/dead-code/tuple-struct-field.stderr
new file mode 100644
index 0000000000000..ca0989f5b987f
--- /dev/null
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.stderr
@@ -0,0 +1,33 @@
+error: field `1` is never read
+  --> $DIR/tuple-struct-field.rs:8:26
+   |
+LL | struct SingleUnused(i32, [u8; LEN], String);
+   |        ------------      ^^^^^^^^^
+   |        |
+   |        field in this struct
+   |
+note: the lint level is defined here
+  --> $DIR/tuple-struct-field.rs:1:9
+   |
+LL | #![deny(unused_tuple_struct_fields)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
+   |
+LL | struct SingleUnused(i32, (), String);
+   |                          ~~
+
+error: fields `0`, `1`, `2` and `3` are never read
+  --> $DIR/tuple-struct-field.rs:13:23
+   |
+LL | struct MultipleUnused(i32, f32, String, u8);
+   |        -------------- ^^^  ^^^  ^^^^^^  ^^
+   |        |
+   |        fields in this struct
+   |
+help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
+   |
+LL | struct MultipleUnused((), (), (), ());
+   |                       ~~  ~~  ~~  ~~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lint/dead-code/with-impl.rs b/src/test/ui/lint/dead-code/with-impl.rs
index 84829c98e5739..812fcdd09b6cf 100644
--- a/src/test/ui/lint/dead-code/with-impl.rs
+++ b/src/test/ui/lint/dead-code/with-impl.rs
@@ -2,7 +2,7 @@
 
 #![deny(dead_code)]
 
-pub struct GenericFoo<T>(T);
+pub struct GenericFoo<T>(#[allow(unused_tuple_struct_fields)] T);
 
 type Foo = GenericFoo<u32>;
 
diff --git a/src/test/ui/list.rs b/src/test/ui/list.rs
index cb83d4103dced..ffe9f93860a31 100644
--- a/src/test/ui/list.rs
+++ b/src/test/ui/list.rs
@@ -3,7 +3,7 @@
 #![allow(non_camel_case_types)]
 // pretty-expanded FIXME #23616
 
-enum list { cons(isize, Box<list>), nil, }
+enum list { #[allow(unused_tuple_struct_fields)] cons(isize, Box<list>), nil, }
 
 pub fn main() {
     list::cons(10, Box::new(list::cons(11, Box::new(list::cons(12, Box::new(list::nil))))));
diff --git a/src/test/ui/macros/html-literals.rs b/src/test/ui/macros/html-literals.rs
index ae45e97c8b070..26f00fed9c45a 100644
--- a/src/test/ui/macros/html-literals.rs
+++ b/src/test/ui/macros/html-literals.rs
@@ -88,6 +88,7 @@ pub fn main() {
     );
 }
 
+#[allow(unused_tuple_struct_fields)]
 enum HTMLFragment {
     tag(String, Vec<HTMLFragment> ),
     text(String),
diff --git a/src/test/ui/macros/macro-tt-followed-by-seq.rs b/src/test/ui/macros/macro-tt-followed-by-seq.rs
index 90131ebd9203c..080dbcfdd41db 100644
--- a/src/test/ui/macros/macro-tt-followed-by-seq.rs
+++ b/src/test/ui/macros/macro-tt-followed-by-seq.rs
@@ -5,6 +5,7 @@
 use self::Join::*;
 
 #[derive(Debug)]
+#[allow(unused_tuple_struct_fields)]
 enum Join<A,B> {
   Keep(A,B),
   Skip(A,B),
diff --git a/src/test/ui/methods/method-argument-inference-associated-type.rs b/src/test/ui/methods/method-argument-inference-associated-type.rs
index acd4a8465b075..a3c31fab1c2c8 100644
--- a/src/test/ui/methods/method-argument-inference-associated-type.rs
+++ b/src/test/ui/methods/method-argument-inference-associated-type.rs
@@ -7,7 +7,7 @@ pub trait Service {
     fn call(&self, _req: Self::Request);
 }
 
-pub struct S<T>(T);
+pub struct S<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl Service for ClientMap {
     type Request = S<Box<dyn Fn(i32)>>;
diff --git a/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs b/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs
index af362efe15c35..ec41b71170970 100644
--- a/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs
+++ b/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs
@@ -15,7 +15,7 @@ trait MyTrait1 {
 
 impl MyTrait1 for Foo<u32> {}
 
-struct Foo<T>(T);
+struct Foo<T>(#[allow(unused_tuple_struct_fields)] T);
 
 impl Deref for Foo<()> {
     type Target = dyn MyTrait1 + 'static;
@@ -33,7 +33,7 @@ trait MyTrait2 {
 }
 
 impl MyTrait2 for u32 {}
-struct Bar<T>(T, u32);
+struct Bar<T>(#[allow(unused_tuple_struct_fields)] T, u32);
 impl Deref for Bar<u8> {
     type Target = dyn MyTrait2 + 'static;
     fn deref(&self) -> &(dyn MyTrait2 + 'static) {
diff --git a/src/test/ui/mir/mir_codegen_switch.rs b/src/test/ui/mir/mir_codegen_switch.rs
index d2589ae4ad297..9c93499d94803 100644
--- a/src/test/ui/mir/mir_codegen_switch.rs
+++ b/src/test/ui/mir/mir_codegen_switch.rs
@@ -1,7 +1,7 @@
 // run-pass
 enum Abc {
-    A(u8),
-    B(i8),
+    A(#[allow(unused_tuple_struct_fields)] u8),
+    B(#[allow(unused_tuple_struct_fields)] i8),
     C,
     D,
 }
diff --git a/src/test/ui/mir/mir_fat_ptr.rs b/src/test/ui/mir/mir_fat_ptr.rs
index fb34de62f3113..7c3e07c9e346f 100644
--- a/src/test/ui/mir/mir_fat_ptr.rs
+++ b/src/test/ui/mir/mir_fat_ptr.rs
@@ -1,7 +1,7 @@
 // run-pass
 // test that ordinary fat pointer operations work.
 
-struct Wrapper<T: ?Sized>(u32, T);
+struct Wrapper<T: ?Sized>(#[allow(unused_tuple_struct_fields)] u32, T);
 
 struct FatPtrContainer<'a> {
     ptr: &'a [u8]
diff --git a/src/test/ui/mir/mir_raw_fat_ptr.rs b/src/test/ui/mir/mir_raw_fat_ptr.rs
index aa2b499b027dc..6aceefbe7159d 100644
--- a/src/test/ui/mir/mir_raw_fat_ptr.rs
+++ b/src/test/ui/mir/mir_raw_fat_ptr.rs
@@ -103,6 +103,7 @@ impl<T> Foo for T {
     }
 }
 
+#[allow(unused_tuple_struct_fields)]
 struct S<T:?Sized>(u32, T);
 
 fn main_ref() {
diff --git a/src/test/ui/mir/mir_refs_correct.rs b/src/test/ui/mir/mir_refs_correct.rs
index 729db2d25f5af..6cd9526b749f3 100644
--- a/src/test/ui/mir/mir_refs_correct.rs
+++ b/src/test/ui/mir/mir_refs_correct.rs
@@ -3,7 +3,7 @@
 
 extern crate mir_external_refs as ext;
 
-struct S(u8);
+struct S(#[allow(unused_tuple_struct_fields)] u8);
 #[derive(Debug, PartialEq, Eq)]
 struct Unit;
 
@@ -46,7 +46,7 @@ impl<I, O> T<I, O> for O {}
 impl X for S {}
 
 enum E {
-    U(u8)
+    U(#[allow(unused_tuple_struct_fields)] u8)
 }
 
 #[derive(PartialEq, Debug, Eq)]
diff --git a/src/test/ui/nullable-pointer-iotareduction.rs b/src/test/ui/nullable-pointer-iotareduction.rs
index f9edba6743499..d345fec811854 100644
--- a/src/test/ui/nullable-pointer-iotareduction.rs
+++ b/src/test/ui/nullable-pointer-iotareduction.rs
@@ -8,7 +8,7 @@
 // trying to get assert failure messages that at least identify which case
 // failed.
 
-enum E<T> { Thing(isize, T), Nothing((), ((), ()), [i8; 0]) }
+enum E<T> { Thing(isize, T), #[allow(unused_tuple_struct_fields)] Nothing((), ((), ()), [i8; 0]) }
 impl<T> E<T> {
     fn is_none(&self) -> bool {
         match *self {
diff --git a/src/test/ui/optimization-fuel-0.rs b/src/test/ui/optimization-fuel-0.rs
index a97c5750f94c3..2643dbea1c434 100644
--- a/src/test/ui/optimization-fuel-0.rs
+++ b/src/test/ui/optimization-fuel-0.rs
@@ -6,7 +6,9 @@ use std::mem::size_of;
 
 // compile-flags: -Z fuel=foo=0
 
+#[allow(unused_tuple_struct_fields)]
 struct S1(u8, u16, u8);
+#[allow(unused_tuple_struct_fields)]
 struct S2(u8, u16, u8);
 
 fn main() {
diff --git a/src/test/ui/optimization-fuel-1.rs b/src/test/ui/optimization-fuel-1.rs
index a09f91c68abe7..d5e2255d9f06f 100644
--- a/src/test/ui/optimization-fuel-1.rs
+++ b/src/test/ui/optimization-fuel-1.rs
@@ -6,7 +6,9 @@ use std::mem::size_of;
 
 // compile-flags: -Z fuel=foo=1
 
+#[allow(unused_tuple_struct_fields)]
 struct S1(u8, u16, u8);
+#[allow(unused_tuple_struct_fields)]
 struct S2(u8, u16, u8);
 
 fn main() {
diff --git a/src/test/ui/packed/packed-struct-drop-aligned.rs b/src/test/ui/packed/packed-struct-drop-aligned.rs
index b95cdbbbaad3b..9f9f41e251564 100644
--- a/src/test/ui/packed/packed-struct-drop-aligned.rs
+++ b/src/test/ui/packed/packed-struct-drop-aligned.rs
@@ -24,7 +24,7 @@ impl<'a> Drop for Aligned<'a> {
 }
 
 #[repr(transparent)]
-struct NotCopy(u8);
+struct NotCopy(#[allow(unused_tuple_struct_fields)] u8);
 
 #[repr(packed)]
 struct Packed<'a>(NotCopy, Aligned<'a>);
diff --git a/src/test/ui/packed/packed-struct-optimized-enum.rs b/src/test/ui/packed/packed-struct-optimized-enum.rs
index 7ce62464ef02c..5e1a1f518c570 100644
--- a/src/test/ui/packed/packed-struct-optimized-enum.rs
+++ b/src/test/ui/packed/packed-struct-optimized-enum.rs
@@ -1,6 +1,6 @@
 // run-pass
 #[repr(packed)]
-struct Packed<T: Copy>(T);
+struct Packed<T: Copy>(#[allow(unused_tuple_struct_fields)] T);
 
 impl<T: Copy> Copy for Packed<T> {}
 impl<T: Copy> Clone for Packed<T> {
diff --git a/src/test/ui/packed/packed-tuple-struct-layout.rs b/src/test/ui/packed/packed-tuple-struct-layout.rs
index b88637fbe5658..931be5b941443 100644
--- a/src/test/ui/packed/packed-tuple-struct-layout.rs
+++ b/src/test/ui/packed/packed-tuple-struct-layout.rs
@@ -2,9 +2,11 @@
 use std::mem;
 
 #[repr(packed)]
+#[allow(unused_tuple_struct_fields)]
 struct S4(u8,[u8; 3]);
 
 #[repr(packed)]
+#[allow(unused_tuple_struct_fields)]
 struct S5(u8,u32);
 
 pub fn main() {
diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.fixed b/src/test/ui/parser/issues/issue-70388-without-witness.fixed
index 464e78fd03595..8d981405ea1ca 100644
--- a/src/test/ui/parser/issues/issue-70388-without-witness.fixed
+++ b/src/test/ui/parser/issues/issue-70388-without-witness.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 // This is for checking if we can apply suggestions as-is.
 
-pub struct Foo(i32);
+pub struct Foo(#[allow(unused_tuple_struct_fields)] i32);
 
 fn main() {
     let Foo(..) = Foo(0); //~ ERROR unexpected `...`
diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.rs b/src/test/ui/parser/issues/issue-70388-without-witness.rs
index 9e35e4c38aa87..bf36073083a39 100644
--- a/src/test/ui/parser/issues/issue-70388-without-witness.rs
+++ b/src/test/ui/parser/issues/issue-70388-without-witness.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 // This is for checking if we can apply suggestions as-is.
 
-pub struct Foo(i32);
+pub struct Foo(#[allow(unused_tuple_struct_fields)] i32);
 
 fn main() {
     let Foo(...) = Foo(0); //~ ERROR unexpected `...`
diff --git a/src/test/ui/range_inclusive.rs b/src/test/ui/range_inclusive.rs
index 7e7a15924b765..c9107d24ed092 100644
--- a/src/test/ui/range_inclusive.rs
+++ b/src/test/ui/range_inclusive.rs
@@ -11,7 +11,7 @@ fn foo() -> isize { 42 }
 pub fn return_range_to() -> RangeToInclusive<i32> { return ..=1; }
 
 #[derive(Debug)]
-struct P(u8);
+struct P(#[allow(unused_tuple_struct_fields)] u8);
 
 pub fn main() {
     let mut count = 0;
diff --git a/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs b/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs
index 366ea7d3b3fda..91958dffcf4df 100644
--- a/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs
+++ b/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs
@@ -1,9 +1,8 @@
-//~ ERROR cycle detected when computing layout of `S`
+//~ ERROR cycle detected when computing layout of `core::option::Option<S>`
+//~| NOTE ...which requires computing layout of `S`...
 //~| NOTE ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
-//~| NOTE ...which requires computing layout of `core::option::Option<S>`...
-//~| NOTE ...which again requires computing layout of `S`, completing the cycle
-
-// build-fail
+//~| NOTE ...which again requires computing layout of `core::option::Option<S>`, completing the cycle
+//~| NOTE cycle used when computing layout of `core::option::Option<<S as Mirror>::It>`
 
 trait Mirror {
     type It: ?Sized;
@@ -14,6 +13,5 @@ impl<T: ?Sized> Mirror for T {
 struct S(Option<<S as Mirror>::It>);
 
 fn main() {
-    //~^ NOTE cycle used when elaborating drops for `main`
     let _s = S(None);
 }
diff --git a/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr
index 5b675dc9f81fc..a75097cdbfbda 100644
--- a/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr
+++ b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr
@@ -1,13 +1,9 @@
-error[E0391]: cycle detected when computing layout of `S`
+error[E0391]: cycle detected when computing layout of `core::option::Option<S>`
    |
+   = note: ...which requires computing layout of `S`...
    = note: ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
-   = note: ...which requires computing layout of `core::option::Option<S>`...
-   = note: ...which again requires computing layout of `S`, completing the cycle
-note: cycle used when elaborating drops for `main`
-  --> $DIR/issue-26548-recursion-via-normalize.rs:16:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
+   = note: ...which again requires computing layout of `core::option::Option<S>`, completing the cycle
+   = note: cycle used when computing layout of `core::option::Option<<S as Mirror>::It>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs
index c6d7166e74065..1914e15549307 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs
@@ -5,7 +5,7 @@
 
 #![warn(pointer_structural_match)]
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive
 // (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs
index cc7ea6cde8d7f..e713b003b0059 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs
@@ -5,7 +5,7 @@
 
 #![warn(pointer_structural_match)]
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive
 // (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs
index 86db09cc08fc8..04da14c54194a 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs
@@ -5,7 +5,7 @@
 
 #![warn(pointer_structural_match)]
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive
 // (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs
index 99c574d078045..8313c25e7538d 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs
@@ -5,7 +5,7 @@
 
 #![warn(pointer_structural_match)]
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive
 // (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs
index 4a8a09493798e..7623839fdd13a 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs
@@ -5,7 +5,7 @@
 //
 // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs
index fe62774d220d4..894739ff705c3 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs
@@ -7,7 +7,7 @@
 #![warn(indirect_structural_match)]
 // run-pass
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs
index c3a30674ea387..1699dae46247e 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs
@@ -7,7 +7,7 @@
 #![warn(indirect_structural_match)]
 // run-pass
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs
index 4d0e80d5af312..2672bdd9e5669 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs
@@ -7,7 +7,7 @@
 #![warn(indirect_structural_match)]
 // run-pass
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs
index 432f196ec8127..3489995ae71a0 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs
@@ -7,7 +7,7 @@
 #![warn(indirect_structural_match)]
 // run-pass
 
-struct NoDerive(i32);
+struct NoDerive(#[allow(unused_tuple_struct_fields)] i32);
 
 // This impl makes NoDerive irreflexive.
 impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
index f50e70939dfd5..04462c0a11b89 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
@@ -96,7 +96,7 @@ implements_const_drop! {
 }
 
 fn main() {
-    struct HasDropGlue(Box<u8>);
+    struct HasDropGlue(#[allow(unused_tuple_struct_fields)] Box<u8>);
     struct HasDropImpl;
     impl Drop for HasDropImpl {
         fn drop(&mut self) {
diff --git a/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs
index 2fe1e05e509f8..d359067f627e3 100644
--- a/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs
+++ b/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs
@@ -7,7 +7,7 @@ struct Test {
 }
 
 #[r#derive(r#Debug)]
-struct Test2(u32);
+struct Test2(#[allow(unused_tuple_struct_fields)] u32);
 
 pub fn main() {
     assert_eq!(mem::size_of::<Test>(), 9);
diff --git a/src/test/ui/specialization/specialization-cross-crate.rs b/src/test/ui/specialization/specialization-cross-crate.rs
index 4171505aa374c..d9381d6615226 100644
--- a/src/test/ui/specialization/specialization-cross-crate.rs
+++ b/src/test/ui/specialization/specialization-cross-crate.rs
@@ -14,7 +14,7 @@ struct NotClone;
 struct MarkedAndClone;
 impl MyMarker for MarkedAndClone {}
 
-struct MyType<T>(T);
+struct MyType<T>(#[allow(unused_tuple_struct_fields)] T);
 impl<T> Foo for MyType<T> {
     default fn foo(&self) -> &'static str {
         "generic MyType"
diff --git a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs
index 5c2781a9c63a6..904aeaa088b76 100644
--- a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs
+++ b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs
@@ -14,7 +14,7 @@ impl<'a> WithAssoc for &'a () {
     type Item = &'a u32;
 }
 
-struct Cloned<I>(I);
+struct Cloned<I>(#[allow(unused_tuple_struct_fields)] I);
 
 impl<'a, I, T: 'a> Iterator for Cloned<I>
     where I: WithAssoc<Item=&'a T>, T: Clone
diff --git a/src/test/ui/stdlib-unit-tests/raw-fat-ptr.rs b/src/test/ui/stdlib-unit-tests/raw-fat-ptr.rs
index 9f50659ed60d0..6b0b09c98945c 100644
--- a/src/test/ui/stdlib-unit-tests/raw-fat-ptr.rs
+++ b/src/test/ui/stdlib-unit-tests/raw-fat-ptr.rs
@@ -39,6 +39,7 @@ impl<T> Foo for T {
     }
 }
 
+#[allow(unused_tuple_struct_fields)]
 struct S<T:?Sized>(u32, T);
 
 fn main() {
diff --git a/src/test/ui/struct-ctor-mangling.rs b/src/test/ui/struct-ctor-mangling.rs
index f242cb8457f99..ba6abbf03a539 100644
--- a/src/test/ui/struct-ctor-mangling.rs
+++ b/src/test/ui/struct-ctor-mangling.rs
@@ -4,7 +4,7 @@ fn size_of_val<T>(_: &T) -> usize {
     std::mem::size_of::<T>()
 }
 
-struct Foo(i64);
+struct Foo(#[allow(unused_tuple_struct_fields)] i64);
 
 // Test that the (symbol) mangling of `Foo` (the `struct` type) and that of
 // `typeof Foo` (the function type of the `struct` constructor) don't collide.
diff --git a/src/test/ui/structs-enums/enum-null-pointer-opt.rs b/src/test/ui/structs-enums/enum-null-pointer-opt.rs
index 32fdbf620a98d..85fa1eac2e2a6 100644
--- a/src/test/ui/structs-enums/enum-null-pointer-opt.rs
+++ b/src/test/ui/structs-enums/enum-null-pointer-opt.rs
@@ -10,8 +10,8 @@ use std::sync::Arc;
 trait Trait { fn dummy(&self) { } }
 trait Mirror { type Image; }
 impl<T> Mirror for T { type Image = T; }
-struct ParamTypeStruct<T>(T);
-struct AssocTypeStruct<T>(<T as Mirror>::Image);
+struct ParamTypeStruct<T>(#[allow(unused_tuple_struct_fields)] T);
+struct AssocTypeStruct<T>(#[allow(unused_tuple_struct_fields)] <T as Mirror>::Image);
 #[repr(transparent)]
 union MaybeUninitUnion<T: Copy> {
     _value: T,
@@ -46,7 +46,7 @@ fn main() {
     struct Foo {
         _a: Box<isize>
     }
-    struct Bar(Box<isize>);
+    struct Bar(#[allow(unused_tuple_struct_fields)] Box<isize>);
 
     // Should apply through structs
     assert_eq!(size_of::<Foo>(), size_of::<Option<Foo>>());
diff --git a/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs b/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs
index 53892a4e0aeb4..a05cf8b93d5bd 100644
--- a/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs
+++ b/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs
@@ -6,7 +6,7 @@
  * represented with nullable pointers could be misoptimized in some cases.
  */
 
-enum List<X> { Nil, Cons(X, Box<List<X>>) }
+enum List<X> { Nil, Cons(X, #[allow(unused_tuple_struct_fields)] Box<List<X>>) }
 pub fn main() {
     match List::Cons(10, Box::new(List::Nil)) {
         List::Cons(10, _) => {}
diff --git a/src/test/ui/structs-enums/resource-in-struct.rs b/src/test/ui/structs-enums/resource-in-struct.rs
index 35a4b14bc3f87..9613ca62a49e6 100644
--- a/src/test/ui/structs-enums/resource-in-struct.rs
+++ b/src/test/ui/structs-enums/resource-in-struct.rs
@@ -25,7 +25,7 @@ fn close_res(i: closable) -> close_res {
     }
 }
 
-enum option<T> { none, some(T), }
+enum option<T> { none, some(#[allow(unused_tuple_struct_fields)] T), }
 
 fn sink(_res: option<close_res>) { }
 
diff --git a/src/test/ui/structs-enums/tuple-struct-construct.rs b/src/test/ui/structs-enums/tuple-struct-construct.rs
index 972fc9dc04a90..fbf97e6b22558 100644
--- a/src/test/ui/structs-enums/tuple-struct-construct.rs
+++ b/src/test/ui/structs-enums/tuple-struct-construct.rs
@@ -1,4 +1,5 @@
 // run-pass
+#[allow(unused_tuple_struct_fields)]
 #[derive(Debug)]
 struct Foo(isize, isize);
 
diff --git a/src/test/ui/structs-enums/uninstantiable-struct.rs b/src/test/ui/structs-enums/uninstantiable-struct.rs
index b1ef525614ea5..b24effe5a9c48 100644
--- a/src/test/ui/structs-enums/uninstantiable-struct.rs
+++ b/src/test/ui/structs-enums/uninstantiable-struct.rs
@@ -1,4 +1,4 @@
 // run-pass
-pub struct Z(&'static Z);
+pub struct Z(#[allow(unused_tuple_struct_fields)] &'static Z);
 
 pub fn main() {}
diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs
index 97006ae50a0bf..90adba99e542b 100644
--- a/src/test/ui/trailing-comma.rs
+++ b/src/test/ui/trailing-comma.rs
@@ -3,7 +3,7 @@
 
 fn f<T,>(_: T,) {}
 
-struct Foo<T,>(T);
+struct Foo<T,>(#[allow(unused_tuple_struct_fields)] T);
 
 struct Bar;
 
@@ -14,7 +14,7 @@ impl Bar {
 }
 
 enum Baz {
-    Qux(isize,),
+    Qux(#[allow(unused_tuple_struct_fields)] isize,),
 }
 
 #[allow(unused,)]
diff --git a/src/test/ui/traits/augmented-assignments-trait.rs b/src/test/ui/traits/augmented-assignments-trait.rs
index 8c418daffdf5e..747a5393f1257 100644
--- a/src/test/ui/traits/augmented-assignments-trait.rs
+++ b/src/test/ui/traits/augmented-assignments-trait.rs
@@ -1,7 +1,7 @@
 // run-pass
 use std::ops::AddAssign;
 
-struct Int(i32);
+struct Int(#[allow(unused_tuple_struct_fields)] i32);
 
 impl AddAssign for Int {
     fn add_assign(&mut self, _: Int) {
diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs b/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs
index 010dbf2466403..a1042f8310a98 100644
--- a/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs
+++ b/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs
@@ -7,7 +7,7 @@ use std::marker::Send;
 pub struct WaitToken;
 impl !Send for WaitToken {}
 
-pub struct Test<T>(T);
+pub struct Test<T>(#[allow(unused_tuple_struct_fields)] T);
 unsafe impl<T: 'static> Send for Test<T> {}
 
 pub fn spawn<F>(_: F) -> () where F: FnOnce(), F: Send + 'static {}
diff --git a/src/test/ui/traits/object/exclusion.rs b/src/test/ui/traits/object/exclusion.rs
index 0b8b0e2f5ef4d..766dceeaffe00 100644
--- a/src/test/ui/traits/object/exclusion.rs
+++ b/src/test/ui/traits/object/exclusion.rs
@@ -8,7 +8,7 @@ trait Future: 'static {
     }
 }
 
-struct Map<A>(A);
+struct Map<A>(#[allow(unused_tuple_struct_fields)] A);
 impl<A: Future> Future for Map<A> {}
 
 pub struct Promise;
diff --git a/src/test/ui/traits/object/generics.rs b/src/test/ui/traits/object/generics.rs
index e5a96af3810de..5a4a6aecc6b95 100644
--- a/src/test/ui/traits/object/generics.rs
+++ b/src/test/ui/traits/object/generics.rs
@@ -25,7 +25,7 @@ impl<A1, A2, A3> Impl<A1, A2, A3> {
 
 // test for #8601
 
-enum Type<T> { Constant(T) }
+enum Type<T> { Constant(#[allow(unused_tuple_struct_fields)] T) }
 
 trait Trait<K,V> {
     fn method(&self, _: Type<(K,V)>) -> isize;
diff --git a/src/test/ui/traits/pointee-deduction.rs b/src/test/ui/traits/pointee-deduction.rs
index f888246967d3d..c333b0129c8d4 100644
--- a/src/test/ui/traits/pointee-deduction.rs
+++ b/src/test/ui/traits/pointee-deduction.rs
@@ -13,8 +13,8 @@ impl Foo for () {
     type Bar = ();
 }
 
-struct Wrapper1<T: Foo>(<T as Foo>::Bar);
-struct Wrapper2<T: Foo>(<Wrapper1<T> as Pointee>::Metadata);
+struct Wrapper1<T: Foo>(#[allow(unused_tuple_struct_fields)] <T as Foo>::Bar);
+struct Wrapper2<T: Foo>(#[allow(unused_tuple_struct_fields)] <Wrapper1<T> as Pointee>::Metadata);
 
 fn main() {
     let _: Wrapper2<()> = Wrapper2(());
diff --git a/src/test/ui/traits/principal-less-objects.rs b/src/test/ui/traits/principal-less-objects.rs
index 82c76eb693a0d..62bad0d7d77ab 100644
--- a/src/test/ui/traits/principal-less-objects.rs
+++ b/src/test/ui/traits/principal-less-objects.rs
@@ -7,7 +7,7 @@ use std::mem;
 // Array is to make sure the size is not exactly pointer-size, so
 // we can be sure we are measuring the right size in the
 // `size_of_val` test.
-struct SetOnDrop<'a>(&'a AtomicUsize, [u8; 64]);
+struct SetOnDrop<'a>(&'a AtomicUsize, #[allow(unused_tuple_struct_fields)] [u8; 64]);
 impl<'a> Drop for SetOnDrop<'a> {
     fn drop(&mut self) {
         self.0.store(self.0.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
index 19fcc78721ab1..0aa644db052f0 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
@@ -9,7 +9,7 @@
 
 #![allow(irrefutable_let_patterns)]
 
-enum Enum<T> { TSVariant(T), SVariant { _v: T }, UVariant }
+enum Enum<T> { TSVariant(#[allow(unused_tuple_struct_fields)] T), SVariant { _v: T }, UVariant }
 type Alias<T> = Enum<T>;
 type AliasFixed = Enum<()>;
 
diff --git a/src/test/ui/unboxed-closures/type-id-higher-rank.rs b/src/test/ui/unboxed-closures/type-id-higher-rank.rs
index 355d11099419c..1f8aec205fbeb 100644
--- a/src/test/ui/unboxed-closures/type-id-higher-rank.rs
+++ b/src/test/ui/unboxed-closures/type-id-higher-rank.rs
@@ -4,7 +4,7 @@
 
 use std::any::{Any, TypeId};
 
-struct Struct<'a>(&'a ());
+struct Struct<'a>(#[allow(unused_tuple_struct_fields)] &'a ());
 trait Trait<'a> {}
 
 fn main() {
diff --git a/src/test/ui/unsized-locals/unsized-exprs-rpass.rs b/src/test/ui/unsized-locals/unsized-exprs-rpass.rs
index 8fcb6d93d391c..175b02fcb8175 100644
--- a/src/test/ui/unsized-locals/unsized-exprs-rpass.rs
+++ b/src/test/ui/unsized-locals/unsized-exprs-rpass.rs
@@ -2,7 +2,7 @@
 #![allow(incomplete_features, unused_braces, unused_parens)]
 #![feature(unsized_tuple_coercion, unsized_locals, unsized_fn_params)]
 
-struct A<X: ?Sized>(X);
+struct A<X: ?Sized>(#[allow(unused_tuple_struct_fields)] X);
 
 fn udrop<T: ?Sized>(_x: T) {}
 fn foo() -> Box<[u8]> {
diff --git a/src/test/ui/unsized/unchanged-param.rs b/src/test/ui/unsized/unchanged-param.rs
index 93c7af68ac388..6bdc89310ebae 100644
--- a/src/test/ui/unsized/unchanged-param.rs
+++ b/src/test/ui/unsized/unchanged-param.rs
@@ -1,8 +1,8 @@
 // run-pass
 // Test that we allow unsizing even if there is an unchanged param in the
 // field getting unsized.
-struct A<T, U: ?Sized + 'static>(T, B<T, U>);
-struct B<T, U: ?Sized>(T, U);
+struct A<T, U: ?Sized + 'static>(#[allow(unused_tuple_struct_fields)] T, B<T, U>);
+struct B<T, U: ?Sized>(#[allow(unused_tuple_struct_fields)] T, U);
 
 fn main() {
     let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
index b6affdee52364..4caab6230909c 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
@@ -19,6 +19,9 @@ declare_clippy_lint! {
     /// ### Why is this bad?
     /// An assertion failure cannot output an useful message of the error.
     ///
+    /// ### Known problems
+    /// The suggested replacement decreases the readability of code and log output.
+    ///
     /// ### Example
     /// ```rust,ignore
     /// # let r = Ok::<_, ()>(());
@@ -28,7 +31,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.64.0"]
     pub ASSERTIONS_ON_RESULT_STATES,
-    style,
+    restriction,
     "`assert!(r.is_ok())`/`assert!(r.is_err())` gives worse error message than directly calling `r.unwrap()`/`r.unwrap_err()`"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_all.rs b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
index 5be1c417bf8f6..0ba9b7ae7e581 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
@@ -6,7 +6,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
     LintId::of(approx_const::APPROX_CONSTANT),
     LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
-    LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
     LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
     LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
     LintId::of(attrs::DEPRECATED_CFG_ATTR),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
index 495abd8387e85..a7339ef272174 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
@@ -7,6 +7,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
     LintId::of(as_underscore::AS_UNDERSCORE),
     LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
     LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
+    LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
     LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
     LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
     LintId::of(create_dir::CREATE_DIR),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_style.rs b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
index e029a5235e720..e95bab1d0454d 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_style.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
@@ -4,7 +4,6 @@
 
 store.register_group(true, "clippy::style", Some("clippy_style"), vec![
     LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
-    LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
     LintId::of(blacklisted_name::BLACKLISTED_NAME),
     LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
     LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 3a99d1b417fee..32718200c0b3a 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -441,7 +441,7 @@ impl SimpleFormatArgs {
         };
 
         match arg.position {
-            ArgumentIs(n, _) | ArgumentImplicitlyIs(n) => {
+            ArgumentIs(n) | ArgumentImplicitlyIs(n) => {
                 if self.unnamed.len() <= n {
                     // Use a dummy span to mark all unseen arguments.
                     self.unnamed.resize_with(n, || vec![DUMMY_SP]);
@@ -462,7 +462,7 @@ impl SimpleFormatArgs {
                     }
                 }
             },
-            ArgumentNamed(n, _) => {
+            ArgumentNamed(n) => {
                 let n = Symbol::intern(n);
                 if let Some(x) = self.named.iter_mut().find(|x| x.0 == n) {
                     match x.1.as_slice() {
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs
index 2289f7875f04c..f13733af3d0d1 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs
@@ -2,6 +2,7 @@
 // As the most common case is the `http` crate, it replicates `http::HeadewrName`'s structure.
 
 #![allow(clippy::declare_interior_mutable_const)]
+#![allow(unused_tuple_struct_fields)]
 
 use std::sync::atomic::AtomicUsize;
 
diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed
index f4db2d20c713c..6b754f3bd7103 100644
--- a/src/tools/clippy/tests/ui/format.fixed
+++ b/src/tools/clippy/tests/ui/format.fixed
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![allow(
+    unused_tuple_struct_fields,
     clippy::print_literal,
     clippy::redundant_clone,
     clippy::to_string_in_format_args,
diff --git a/src/tools/clippy/tests/ui/format.rs b/src/tools/clippy/tests/ui/format.rs
index bf687cb1e96c7..ca9826b356ec8 100644
--- a/src/tools/clippy/tests/ui/format.rs
+++ b/src/tools/clippy/tests/ui/format.rs
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![allow(
+    unused_tuple_struct_fields,
     clippy::print_literal,
     clippy::redundant_clone,
     clippy::to_string_in_format_args,
diff --git a/src/tools/clippy/tests/ui/format.stderr b/src/tools/clippy/tests/ui/format.stderr
index a0f8e7d193791..aca75bb207abe 100644
--- a/src/tools/clippy/tests/ui/format.stderr
+++ b/src/tools/clippy/tests/ui/format.stderr
@@ -1,5 +1,5 @@
 error: useless use of `format!`
-  --> $DIR/format.rs:18:5
+  --> $DIR/format.rs:19:5
    |
 LL |     format!("foo");
    |     ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
@@ -7,19 +7,19 @@ LL |     format!("foo");
    = note: `-D clippy::useless-format` implied by `-D warnings`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:19:5
+  --> $DIR/format.rs:20:5
    |
 LL |     format!("{{}}");
    |     ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:20:5
+  --> $DIR/format.rs:21:5
    |
 LL |     format!("{{}} abc {{}}");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:21:5
+  --> $DIR/format.rs:22:5
    |
 LL | /     format!(
 LL | |         r##"foo {{}}
@@ -34,79 +34,79 @@ LL ~ " bar"##.to_string();
    |
 
 error: useless use of `format!`
-  --> $DIR/format.rs:26:13
+  --> $DIR/format.rs:27:13
    |
 LL |     let _ = format!("");
    |             ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:28:5
+  --> $DIR/format.rs:29:5
    |
 LL |     format!("{}", "foo");
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:32:5
+  --> $DIR/format.rs:33:5
    |
 LL |     format!("{:+}", "foo"); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:33:5
+  --> $DIR/format.rs:34:5
    |
 LL |     format!("{:<}", "foo"); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:38:5
+  --> $DIR/format.rs:39:5
    |
 LL |     format!("{}", arg);
    |     ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:42:5
+  --> $DIR/format.rs:43:5
    |
 LL |     format!("{:+}", arg); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:43:5
+  --> $DIR/format.rs:44:5
    |
 LL |     format!("{:<}", arg); // Warn when the format makes no difference.
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:70:5
+  --> $DIR/format.rs:71:5
    |
 LL |     format!("{}", 42.to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:72:5
+  --> $DIR/format.rs:73:5
    |
 LL |     format!("{}", x.display().to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:76:18
+  --> $DIR/format.rs:77:18
    |
 LL |     let _ = Some(format!("{}", a + "bar"));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:80:22
+  --> $DIR/format.rs:81:22
    |
 LL |     let _s: String = format!("{}", &*v.join("/n"));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:86:13
+  --> $DIR/format.rs:87:13
    |
 LL |     let _ = format!("{x}");
    |             ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:88:13
+  --> $DIR/format.rs:89:13
    |
 LL |     let _ = format!("{y}", y = x);
    |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
index 403c3b3e44380..48f8093311cbd 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::from_iter_instead_of_collect)]
-#![allow(unused_imports)]
+#![allow(unused_imports, unused_tuple_struct_fields)]
 
 use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
 
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
index fefc7b01a65bb..ebe0ad278be30 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::from_iter_instead_of_collect)]
-#![allow(unused_imports)]
+#![allow(unused_imports, unused_tuple_struct_fields)]
 
 use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
 
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed
index 9556f6f82cc63..04a74a009e092 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.fixed
+++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 #![feature(never_type)]
-#![allow(unused_mut, clippy::redundant_allocation)]
+#![allow(unused_mut, unused_tuple_struct_fields, clippy::redundant_allocation)]
 #![warn(clippy::must_use_candidate)]
 use std::rc::Rc;
 use std::sync::atomic::{AtomicBool, Ordering};
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs
index 3732422017104..f04122f4eeab6 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.rs
+++ b/src/tools/clippy/tests/ui/must_use_candidates.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 #![feature(never_type)]
-#![allow(unused_mut, clippy::redundant_allocation)]
+#![allow(unused_mut, unused_tuple_struct_fields, clippy::redundant_allocation)]
 #![warn(clippy::must_use_candidate)]
 use std::rc::Rc;
 use std::sync::atomic::{AtomicBool, Ordering};
diff --git a/src/tools/clippy/tests/ui/numbered_fields.fixed b/src/tools/clippy/tests/ui/numbered_fields.fixed
index 3710b3e9c81e0..68c987eb4c677 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.fixed
+++ b/src/tools/clippy/tests/ui/numbered_fields.fixed
@@ -1,5 +1,6 @@
 //run-rustfix
 #![warn(clippy::init_numbered_fields)]
+#![allow(unused_tuple_struct_fields)]
 
 #[derive(Default)]
 struct TupleStruct(u32, u32, u8);
diff --git a/src/tools/clippy/tests/ui/numbered_fields.rs b/src/tools/clippy/tests/ui/numbered_fields.rs
index 2af84bc0642a5..2ef4fb4de5370 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.rs
+++ b/src/tools/clippy/tests/ui/numbered_fields.rs
@@ -1,5 +1,6 @@
 //run-rustfix
 #![warn(clippy::init_numbered_fields)]
+#![allow(unused_tuple_struct_fields)]
 
 #[derive(Default)]
 struct TupleStruct(u32, u32, u8);
diff --git a/src/tools/clippy/tests/ui/numbered_fields.stderr b/src/tools/clippy/tests/ui/numbered_fields.stderr
index 01691c8b141e8..60c0d7898063f 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.stderr
+++ b/src/tools/clippy/tests/ui/numbered_fields.stderr
@@ -1,5 +1,5 @@
 error: used a field initializer for a tuple struct
-  --> $DIR/numbered_fields.rs:18:13
+  --> $DIR/numbered_fields.rs:19:13
    |
 LL |       let _ = TupleStruct {
    |  _____________^
@@ -12,7 +12,7 @@ LL | |     };
    = note: `-D clippy::init-numbered-fields` implied by `-D warnings`
 
 error: used a field initializer for a tuple struct
-  --> $DIR/numbered_fields.rs:25:13
+  --> $DIR/numbered_fields.rs:26:13
    |
 LL |       let _ = TupleStruct {
    |  _____________^
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index e12e13a57f1f0..b6d5e106f057a 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -1,6 +1,7 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
 #![allow(
+    unused_tuple_struct_fields,
     clippy::redundant_closure,
     clippy::ref_option_ref,
     clippy::equatable_if_let,
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index b5206fc26a9e1..35bae15934358 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -1,6 +1,7 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
 #![allow(
+    unused_tuple_struct_fields,
     clippy::redundant_closure,
     clippy::ref_option_ref,
     clippy::equatable_if_let,
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index 40aef977b989b..daba606004e11 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -1,5 +1,5 @@
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:11:5
+  --> $DIR/option_if_let_else.rs:12:5
    |
 LL | /     if let Some(x) = string {
 LL | |         (true, x)
@@ -11,19 +11,19 @@ LL | |     }
    = note: `-D clippy::option-if-let-else` implied by `-D warnings`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:29:13
+  --> $DIR/option_if_let_else.rs:30:13
    |
 LL |     let _ = if let Some(s) = *string { s.len() } else { 0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:30:13
+  --> $DIR/option_if_let_else.rs:31:13
    |
 LL |     let _ = if let Some(s) = &num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:31:13
+  --> $DIR/option_if_let_else.rs:32:13
    |
 LL |       let _ = if let Some(s) = &mut num {
    |  _____________^
@@ -43,13 +43,13 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:37:13
+  --> $DIR/option_if_let_else.rs:38:13
    |
 LL |     let _ = if let Some(ref s) = num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:38:13
+  --> $DIR/option_if_let_else.rs:39:13
    |
 LL |       let _ = if let Some(mut s) = num {
    |  _____________^
@@ -69,7 +69,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:44:13
+  --> $DIR/option_if_let_else.rs:45:13
    |
 LL |       let _ = if let Some(ref mut s) = num {
    |  _____________^
@@ -89,7 +89,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:53:5
+  --> $DIR/option_if_let_else.rs:54:5
    |
 LL | /     if let Some(x) = arg {
 LL | |         let y = x * x;
@@ -108,7 +108,7 @@ LL +     })
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:66:13
+  --> $DIR/option_if_let_else.rs:67:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -120,7 +120,7 @@ LL | |     };
    | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:75:13
+  --> $DIR/option_if_let_else.rs:76:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -143,7 +143,7 @@ LL ~     }, |x| x * x * x * x);
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:108:13
+  --> $DIR/option_if_let_else.rs:109:13
    |
 LL | /             if let Some(idx) = s.find('.') {
 LL | |                 vec![s[..idx].to_string(), s[idx..].to_string()]
@@ -153,13 +153,13 @@ LL | |             }
    | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:132:13
+  --> $DIR/option_if_let_else.rs:133:13
    |
 LL |     let _ = if let Some(x) = optional { x + 2 } else { 5 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:141:13
+  --> $DIR/option_if_let_else.rs:142:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
@@ -181,13 +181,13 @@ LL ~         });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:169:13
+  --> $DIR/option_if_let_else.rs:170:13
    |
 LL |     let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:173:13
+  --> $DIR/option_if_let_else.rs:174:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
diff --git a/src/tools/clippy/tests/ui/unreadable_literal.fixed b/src/tools/clippy/tests/ui/unreadable_literal.fixed
index e726b652ef1ed..a67363b09ea5a 100644
--- a/src/tools/clippy/tests/ui/unreadable_literal.fixed
+++ b/src/tools/clippy/tests/ui/unreadable_literal.fixed
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::unreadable_literal)]
+#![allow(unused_tuple_struct_fields)]
 
 struct Foo(u64);
 
diff --git a/src/tools/clippy/tests/ui/unreadable_literal.rs b/src/tools/clippy/tests/ui/unreadable_literal.rs
index 5bbb2fc9dc137..82f04e7ced527 100644
--- a/src/tools/clippy/tests/ui/unreadable_literal.rs
+++ b/src/tools/clippy/tests/ui/unreadable_literal.rs
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::unreadable_literal)]
+#![allow(unused_tuple_struct_fields)]
 
 struct Foo(u64);
 
diff --git a/src/tools/clippy/tests/ui/unreadable_literal.stderr b/src/tools/clippy/tests/ui/unreadable_literal.stderr
index ee5466fd517fd..b51130c6a6aba 100644
--- a/src/tools/clippy/tests/ui/unreadable_literal.stderr
+++ b/src/tools/clippy/tests/ui/unreadable_literal.stderr
@@ -1,5 +1,5 @@
 error: digits of hex or binary literal not grouped by four
-  --> $DIR/unreadable_literal.rs:25:9
+  --> $DIR/unreadable_literal.rs:26:9
    |
 LL |         0x1_234_567,
    |         ^^^^^^^^^^^ help: consider: `0x0123_4567`
@@ -7,7 +7,7 @@ LL |         0x1_234_567,
    = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:33:17
+  --> $DIR/unreadable_literal.rs:34:17
    |
 LL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
    |                 ^^^^^^^^^^^^ help: consider: `0b11_0110_i64`
@@ -15,55 +15,55 @@ LL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
    = note: `-D clippy::unreadable-literal` implied by `-D warnings`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:33:31
+  --> $DIR/unreadable_literal.rs:34:31
    |
 LL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
    |                               ^^^^^^^^^^^^^^^^ help: consider: `0x1234_5678_usize`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:33:49
+  --> $DIR/unreadable_literal.rs:34:49
    |
 LL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
    |                                                 ^^^^^^^^^^ help: consider: `123_456_f32`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:33:61
+  --> $DIR/unreadable_literal.rs:34:61
    |
 LL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
    |                                                             ^^^^^^^^^^^^ help: consider: `1.234_567_f32`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:35:20
+  --> $DIR/unreadable_literal.rs:36:20
    |
 LL |     let _bad_sci = 1.123456e1;
    |                    ^^^^^^^^^^ help: consider: `1.123_456e1`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:37:18
+  --> $DIR/unreadable_literal.rs:38:18
    |
 LL |     let _fail1 = 0xabcdef;
    |                  ^^^^^^^^ help: consider: `0x00ab_cdef`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:38:23
+  --> $DIR/unreadable_literal.rs:39:23
    |
 LL |     let _fail2: u32 = 0xBAFEBAFE;
    |                       ^^^^^^^^^^ help: consider: `0xBAFE_BAFE`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:39:18
+  --> $DIR/unreadable_literal.rs:40:18
    |
 LL |     let _fail3 = 0xabcdeff;
    |                  ^^^^^^^^^ help: consider: `0x0abc_deff`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:40:24
+  --> $DIR/unreadable_literal.rs:41:24
    |
 LL |     let _fail4: i128 = 0xabcabcabcabcabcabc;
    |                        ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`
 
 error: long literal lacking separators
-  --> $DIR/unreadable_literal.rs:41:18
+  --> $DIR/unreadable_literal.rs:42:18
    |
 LL |     let _fail5 = 1.100300400;
    |                  ^^^^^^^^^^^ help: consider: `1.100_300_400`