about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-09-02 05:12:42 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-09-02 05:12:42 +0000
commit9fe4539fa79358f4817503322c5cbb3fd6af5f09 (patch)
tree0cabce5bc2445f5bd2bea6ed174d54736d5bd0e0
parent6c09243724aae85f3109a12913347d8affb1939b (diff)
parente71f9529121ca8f687e4b725e3c9adc3f1ebab4d (diff)
downloadrust-9fe4539fa79358f4817503322c5cbb3fd6af5f09.tar.gz
rust-9fe4539fa79358f4817503322c5cbb3fd6af5f09.zip
Merge from rustc
-rw-r--r--Cargo.lock6
-rw-r--r--compiler/rustc_ast/src/visit.rs16
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs36
-rw-r--r--compiler/rustc_ast_lowering/src/lifetime_collector.rs2
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs125
-rw-r--r--compiler/rustc_data_structures/Cargo.toml2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs19
-rw-r--r--compiler/rustc_errors/src/lib.rs12
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/def.rs44
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl4
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs13
-rw-r--r--compiler/rustc_lint/src/expect.rs53
-rw-r--r--compiler/rustc_lint/src/levels.rs353
-rw-r--r--compiler/rustc_lint/src/lints.rs10
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs33
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs38
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_middle/src/lint.rs3
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_mir_build/messages.ftl16
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs46
-rw-r--r--compiler/rustc_mir_build/src/errors.rs35
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs33
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs116
-rw-r--r--compiler/rustc_resolve/src/late.rs81
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs11
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs38
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs37
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--library/Cargo.toml2
-rw-r--r--library/alloc/src/alloc.rs1
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/raw_vec.rs1
-rw-r--r--library/alloc/src/string.rs2
-rw-r--r--library/alloc/src/vec/mod.rs4
-rw-r--r--library/core/src/char/mod.rs2
-rw-r--r--library/core/src/fmt/rt.rs20
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/net/parser.rs56
-rw-r--r--library/core/src/panicking.rs14
-rw-r--r--library/core/src/slice/cmp.rs43
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/panicking.rs8
-rw-r--r--library/std/src/sync/once_lock.rs1
-rw-r--r--library/std/src/sys/pal/unix/fs.rs2
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs11
-rw-r--r--library/unwind/src/lib.rs11
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/nto-qnx.md18
-rw-r--r--src/doc/unstable-book/src/language-features/struct-target-features.md7
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr13
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.stderr11
-rw-r--r--src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr4
-rw-r--r--src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body.rs2
-rw-r--r--tests/assembly/struct-target-features.rs37
-rw-r--r--tests/assembly/targets/targets-elf.rs3
-rw-r--r--tests/crashes/117460.rs8
-rw-r--r--tests/crashes/119095.rs48
-rw-r--r--tests/crashes/126443.rs15
-rw-r--r--tests/crashes/128097.rs6
-rw-r--r--tests/debuginfo/option-like-enum.rs39
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir8
-rw-r--r--tests/ui/async-await/issues/issue-63388-1.rs2
-rw-r--r--tests/ui/async-await/issues/issue-63388-1.stderr13
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.full.stderr10
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.min.stderr10
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.rs1
-rw-r--r--tests/ui/consts/min_const_fn/min_const_fn.rs4
-rw-r--r--tests/ui/consts/min_const_fn/min_const_fn.stderr22
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-1.stderr6
-rw-r--r--tests/ui/error-codes/E0602.stderr7
-rw-r--r--tests/ui/feature-gates/feature-gate-struct-target-features.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-struct-target-features.stderr10
-rw-r--r--tests/ui/generics/generic-no-mangle.fixed2
-rw-r--r--tests/ui/generics/generic-no-mangle.rs2
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.rs1
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr12
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs1
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr14
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs1
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr10
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs1
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs1
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr16
-rw-r--r--tests/ui/lint/cli-unknown-force-warn.stderr7
-rw-r--r--tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs12
-rw-r--r--tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr14
-rw-r--r--tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs27
-rw-r--r--tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr40
-rw-r--r--tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs17
-rw-r--r--tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr26
-rw-r--r--tests/ui/lint/elided-named-lifetimes/static.rs46
-rw-r--r--tests/ui/lint/elided-named-lifetimes/static.stderr32
-rw-r--r--tests/ui/lint/lint-removed-cmdline-deny.stderr7
-rw-r--r--tests/ui/lint/lint-removed-cmdline.stderr7
-rw-r--r--tests/ui/lint/lint-renamed-cmdline-deny.stderr8
-rw-r--r--tests/ui/lint/lint-renamed-cmdline.stderr8
-rw-r--r--tests/ui/lint/lint-unexported-no-mangle.stderr12
-rw-r--r--tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr13
-rw-r--r--tests/ui/lint/lint-unknown-lint-cmdline.stderr13
-rw-r--r--tests/ui/nll/ty-outlives/impl-trait-captures.stderr8
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-elision.rs2
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-elision.stderr14
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.rs2
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.stderr16
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.fixed2
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.rs2
-rw-r--r--tests/ui/self/self_lifetime-async.rs2
-rw-r--r--tests/ui/self/self_lifetime-async.stderr18
-rw-r--r--tests/ui/self/self_lifetime.rs2
-rw-r--r--tests/ui/self/self_lifetime.stderr18
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs1
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr10
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs1
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr10
-rw-r--r--tests/ui/target-feature/struct-target-features.rs98
-rw-r--r--tests/ui/target-feature/struct-target-features.stderr47
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr12
135 files changed, 1184 insertions, 1176 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 23c7a5bc60f..7244ae14fb8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4978,15 +4978,15 @@ dependencies = [
 
 [[package]]
 name = "stacker"
-version = "0.1.15"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
+checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b"
 dependencies = [
  "cc",
  "cfg-if",
  "libc",
  "psm",
- "winapi",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index fe07ec48f1f..7b041768983 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -69,14 +69,14 @@ pub enum FnKind<'a> {
     Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>),
 
     /// E.g., `|x, y| body`.
-    Closure(&'a ClosureBinder, &'a FnDecl, &'a Expr),
+    Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr),
 }
 
 impl<'a> FnKind<'a> {
     pub fn header(&self) -> Option<&'a FnHeader> {
         match *self {
             FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header),
-            FnKind::Closure(_, _, _) => None,
+            FnKind::Closure(..) => None,
         }
     }
 
@@ -90,7 +90,7 @@ impl<'a> FnKind<'a> {
     pub fn decl(&self) -> &'a FnDecl {
         match self {
             FnKind::Fn(_, _, sig, _, _, _) => &sig.decl,
-            FnKind::Closure(_, decl, _) => decl,
+            FnKind::Closure(_, _, decl, _) => decl,
         }
     }
 
@@ -839,7 +839,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
             try_visit!(walk_fn_decl(visitor, decl));
             visit_opt!(visitor, visit_block, body);
         }
-        FnKind::Closure(binder, decl, body) => {
+        FnKind::Closure(binder, _coroutine_kind, decl, body) => {
             try_visit!(visitor.visit_closure_binder(binder));
             try_visit!(walk_fn_decl(visitor, decl));
             try_visit!(visitor.visit_expr(body));
@@ -1107,7 +1107,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
         ExprKind::Closure(box Closure {
             binder,
             capture_clause,
-            coroutine_kind: _,
+            coroutine_kind,
             constness: _,
             movability: _,
             fn_decl,
@@ -1116,7 +1116,11 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
             fn_arg_span: _,
         }) => {
             try_visit!(visitor.visit_capture_by(capture_clause));
-            try_visit!(visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), *span, *id))
+            try_visit!(visitor.visit_fn(
+                FnKind::Closure(binder, coroutine_kind, fn_decl, body),
+                *span,
+                *id
+            ))
         }
         ExprKind::Block(block, opt_label) => {
             visit_opt!(visitor, visit_label, opt_label);
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index bcc2c29a2ff..754fbae4d02 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -45,7 +45,6 @@ use std::collections::hash_map::Entry;
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, *};
-use rustc_ast_pretty::pprust;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxIndexSet;
@@ -837,7 +836,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
             }
-            LifetimeRes::Static | LifetimeRes::Error => return None,
+            LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
             res => panic!(
                 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
                 res, ident, ident.span
@@ -1399,24 +1398,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
                         }
 
-                        let span = t.span;
-
-                        // HACK: pprust breaks strings with newlines when the type
-                        // gets too long. We don't want these to show up in compiler
-                        // output or built artifacts, so replace them here...
-                        // Perhaps we should instead format APITs more robustly.
-                        let ident = Ident::from_str_and_span(
-                            &pprust::ty_to_string(t).replace('\n', " "),
-                            span,
-                        );
-
-                        self.create_def(
-                            self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent?
-                            *def_node_id,
-                            ident.name,
-                            DefKind::TyParam,
-                            span,
-                        );
+                        let def_id = self.local_def_id(*def_node_id);
+                        let name = self.tcx.item_name(def_id.to_def_id());
+                        let ident = Ident::new(name, span);
                         let (param, bounds, path) = self.lower_universal_param_and_bounds(
                             *def_node_id,
                             span,
@@ -1618,13 +1602,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         opaque_ty_span: Span,
         lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
     ) -> hir::TyKind<'hir> {
-        let opaque_ty_def_id = self.create_def(
-            self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent?
-            opaque_ty_node_id,
-            kw::Empty,
-            DefKind::OpaqueTy,
-            opaque_ty_span,
-        );
+        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
         debug!(?opaque_ty_def_id);
 
         // Map from captured (old) lifetime to synthetic (new) lifetime.
@@ -1656,7 +1634,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
 
                 // Opaques do not capture `'static`
-                LifetimeRes::Static | LifetimeRes::Error => {
+                LifetimeRes::Static { .. } | LifetimeRes::Error => {
                     continue;
                 }
 
@@ -2069,7 +2047,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 hir::LifetimeName::Param(param)
             }
             LifetimeRes::Infer => hir::LifetimeName::Infer,
-            LifetimeRes::Static => hir::LifetimeName::Static,
+            LifetimeRes::Static { .. } => hir::LifetimeName::Static,
             LifetimeRes::Error => hir::LifetimeName::Error,
             res => panic!(
                 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
index 77cc2a36a53..76c957afa54 100644
--- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs
+++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
@@ -27,7 +27,7 @@ impl<'ast> LifetimeCollectVisitor<'ast> {
                     self.collected_lifetimes.insert(lifetime);
                 }
             }
-            LifetimeRes::Static | LifetimeRes::Error => {
+            LifetimeRes::Static { .. } | LifetimeRes::Error => {
                 self.collected_lifetimes.insert(lifetime);
             }
             LifetimeRes::Infer => {}
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a9b65456b8c..ed9672a9e79 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1485,7 +1485,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
         let disallowed = (!tilde_const_allowed).then(|| match fk {
             FnKind::Fn(_, ident, _, _, _, _) => TildeConstReason::Function { ident: ident.span },
-            FnKind::Closure(_, _, _) => TildeConstReason::Closure,
+            FnKind::Closure(..) => TildeConstReason::Closure,
         });
         self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
     }
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 209750d6ba6..4ab20c154cc 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -1,6 +1,5 @@
 use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
-use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{struct_span_code_err, DiagMessage, SubdiagMessage};
 use rustc_hir as hir;
@@ -9,7 +8,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
 use rustc_hir::{lang_items, LangItem};
 use rustc_middle::middle::codegen_fn_attrs::{
-    CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, TargetFeature,
+    CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
 };
 use rustc_middle::mir::mono::Linkage;
 use rustc_middle::query::Providers;
@@ -18,7 +17,6 @@ use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span};
-use rustc_target::abi::VariantIdx;
 use rustc_target::spec::{abi, SanitizerSet};
 
 use crate::errors;
@@ -80,13 +78,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     let mut link_ordinal_span = None;
     let mut no_sanitize_span = None;
 
-    let fn_sig_outer = || {
-        use DefKind::*;
-
-        let def_kind = tcx.def_kind(did);
-        if let Fn | AssocFn | Variant | Ctor(..) = def_kind { Some(tcx.fn_sig(did)) } else { None }
-    };
-
     for attr in attrs.iter() {
         // In some cases, attribute are only valid on functions, but it's the `check_attr`
         // pass that check that they aren't used anywhere else, rather this module.
@@ -94,12 +85,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         // functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
         // report a delayed bug, just in case `check_attr` isn't doing its job.
         let fn_sig = || {
-            let sig = fn_sig_outer();
-            if sig.is_none() {
+            use DefKind::*;
+
+            let def_kind = tcx.def_kind(did);
+            if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
+                Some(tcx.fn_sig(did))
+            } else {
                 tcx.dcx()
                     .span_delayed_bug(attr.span, "this attribute can only be applied to functions");
+                None
             }
-            sig
         };
 
         let Some(Ident { name, .. }) = attr.ident() else {
@@ -618,93 +613,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         }
     }
 
-    if let Some(sig) = fn_sig_outer() {
-        // Collect target features from types reachable from arguments.
-        // We define a type as "reachable" if:
-        //  - it is a function argument
-        //  - it is a field of a reachable struct
-        //  - there is a reachable reference to it
-        // FIXME(struct_target_features): we may want to cache the result of this computation.
-        let mut visited_types = FxHashSet::default();
-        let mut reachable_types: Vec<_> = sig.skip_binder().inputs().skip_binder().to_owned();
-        let mut additional_tf = vec![];
-
-        while let Some(ty) = reachable_types.pop() {
-            if visited_types.contains(&ty) {
-                continue;
-            }
-            visited_types.insert(ty);
-            match ty.kind() {
-                ty::Alias(..) => {
-                    if let Ok(t) =
-                        tcx.try_normalize_erasing_regions(tcx.param_env(did.to_def_id()), ty)
-                    {
-                        reachable_types.push(t)
-                    }
-                }
-
-                ty::Ref(_, inner, _) => reachable_types.push(*inner),
-                ty::Tuple(tys) => reachable_types.extend(tys.iter()),
-                ty::Adt(adt_def, args) => {
-                    additional_tf.extend_from_slice(tcx.struct_target_features(adt_def.did()));
-                    // This only recurses into structs as i.e. an Option<TargetFeature> is an ADT
-                    // that doesn't actually always contain a TargetFeature.
-                    if adt_def.is_struct() {
-                        reachable_types.extend(
-                            adt_def
-                                .variant(VariantIdx::from_usize(0))
-                                .fields
-                                .iter()
-                                .map(|field| field.ty(tcx, args)),
-                        );
-                    }
-                }
-                ty::Bool
-                | ty::Char
-                | ty::Int(..)
-                | ty::Uint(..)
-                | ty::Float(..)
-                | ty::Foreign(..)
-                | ty::Str
-                | ty::Array(..)
-                | ty::Pat(..)
-                | ty::Slice(..)
-                | ty::RawPtr(..)
-                | ty::FnDef(..)
-                | ty::FnPtr(..)
-                | ty::Dynamic(..)
-                | ty::Closure(..)
-                | ty::CoroutineClosure(..)
-                | ty::Coroutine(..)
-                | ty::CoroutineWitness(..)
-                | ty::Never
-                | ty::Param(..)
-                | ty::Bound(..)
-                | ty::Placeholder(..)
-                | ty::Infer(..)
-                | ty::Error(..) => (),
-            }
-        }
-
-        // FIXME(struct_target_features): is this really necessary?
-        if !additional_tf.is_empty() && sig.skip_binder().abi() != abi::Abi::Rust {
-            tcx.dcx().span_err(
-                tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
-                "cannot use a struct with target features in a function with non-Rust ABI",
-            );
-        }
-        if !additional_tf.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
-            tcx.dcx().span_err(
-                tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
-                "cannot use a struct with target features in a #[inline(always)] function",
-            );
-        }
-        codegen_fn_attrs
-            .target_features
-            .extend(additional_tf.iter().map(|tf| TargetFeature { implied: true, ..*tf }));
-    }
-
-    // If a function uses non-default target_features it can't be inlined into general
+    // If a function uses #[target_feature] it can't be inlined into general
     // purpose functions as they wouldn't have the right target features
     // enabled. For that reason we also forbid #[inline(always)] as it can't be
     // respected.
@@ -849,20 +758,6 @@ fn check_link_name_xor_ordinal(
     }
 }
 
-fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeature] {
-    let mut features = vec![];
-    let supported_features = tcx.supported_target_features(LOCAL_CRATE);
-    for attr in tcx.get_attrs(def_id, sym::target_feature) {
-        from_target_feature(tcx, attr, supported_features, &mut features);
-    }
-    tcx.arena.alloc_slice(&features)
-}
-
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        codegen_fn_attrs,
-        should_inherit_track_caller,
-        struct_target_features,
-        ..*providers
-    };
+    *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
 }
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 69cbf8c4161..38c6c8a8d11 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -22,7 +22,7 @@ rustc_index = { path = "../rustc_index", package = "rustc_index" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] }
-stacker = "0.1.15"
+stacker = "0.1.17"
 tempfile = "3.2"
 thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 3303e4ee752..34aebadfdad 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -12,7 +12,7 @@ use rustc_lint_defs::{Applicability, LintExpectationId};
 use rustc_macros::{Decodable, Encodable};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{AttrId, Span, DUMMY_SP};
 use tracing::debug;
 
 use crate::snippet::Style;
@@ -356,24 +356,19 @@ impl DiagInner {
 
     pub(crate) fn update_unstable_expectation_id(
         &mut self,
-        unstable_to_stable: &FxIndexMap<LintExpectationId, LintExpectationId>,
+        unstable_to_stable: &FxIndexMap<AttrId, LintExpectationId>,
     ) {
         if let Level::Expect(expectation_id) | Level::ForceWarning(Some(expectation_id)) =
             &mut self.level
+            && let LintExpectationId::Unstable { attr_id, lint_index } = *expectation_id
         {
-            if expectation_id.is_stable() {
-                return;
-            }
-
             // The unstable to stable map only maps the unstable `AttrId` to a stable `HirId` with an attribute index.
             // The lint index inside the attribute is manually transferred here.
-            let lint_index = expectation_id.get_lint_index();
-            expectation_id.set_lint_index(None);
-            let mut stable_id = unstable_to_stable
-                .get(expectation_id)
-                .expect("each unstable `LintExpectationId` must have a matching stable id")
-                .normalize();
+            let Some(stable_id) = unstable_to_stable.get(&attr_id) else {
+                panic!("{expectation_id:?} must have a matching stable id")
+            };
 
+            let mut stable_id = *stable_id;
             stable_id.set_lint_index(lint_index);
             *expectation_id = stable_id;
         }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 99ee8fb17d7..e08d28a156c 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -69,7 +69,7 @@ use rustc_macros::{Decodable, Encodable};
 pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
 use rustc_span::source_map::SourceMap;
 pub use rustc_span::ErrorGuaranteed;
-use rustc_span::{Loc, Span, DUMMY_SP};
+use rustc_span::{AttrId, Loc, Span, DUMMY_SP};
 pub use snippet::Style;
 // Used by external projects such as `rust-gpu`.
 // See https://github.com/rust-lang/rust/pull/115393.
@@ -1096,7 +1096,7 @@ impl<'a> DiagCtxtHandle<'a> {
 
     pub fn update_unstable_expectation_id(
         &self,
-        unstable_to_stable: &FxIndexMap<LintExpectationId, LintExpectationId>,
+        unstable_to_stable: FxIndexMap<AttrId, LintExpectationId>,
     ) {
         let mut inner = self.inner.borrow_mut();
         let diags = std::mem::take(&mut inner.unstable_expect_diagnostics);
@@ -1105,7 +1105,7 @@ impl<'a> DiagCtxtHandle<'a> {
         if !diags.is_empty() {
             inner.suppressed_expected_diag = true;
             for mut diag in diags.into_iter() {
-                diag.update_unstable_expectation_id(unstable_to_stable);
+                diag.update_unstable_expectation_id(&unstable_to_stable);
 
                 // Here the diagnostic is given back to `emit_diagnostic` where it was first
                 // intercepted. Now it should be processed as usual, since the unstable expectation
@@ -1117,11 +1117,11 @@ impl<'a> DiagCtxtHandle<'a> {
         inner
             .stashed_diagnostics
             .values_mut()
-            .for_each(|(diag, _guar)| diag.update_unstable_expectation_id(unstable_to_stable));
+            .for_each(|(diag, _guar)| diag.update_unstable_expectation_id(&unstable_to_stable));
         inner
             .future_breakage_diagnostics
             .iter_mut()
-            .for_each(|diag| diag.update_unstable_expectation_id(unstable_to_stable));
+            .for_each(|diag| diag.update_unstable_expectation_id(&unstable_to_stable));
     }
 
     /// This methods steals all [`LintExpectationId`]s that are stored inside
@@ -1567,7 +1567,7 @@ impl DiagCtxtInner {
                 if let LintExpectationId::Unstable { .. } = expect_id {
                     unreachable!(); // this case was handled at the top of this function
                 }
-                self.fulfilled_expectations.insert(expect_id.normalize());
+                self.fulfilled_expectations.insert(expect_id);
                 if let Expect(_) = diagnostic.level {
                     // Nothing emitted here for expected lints.
                     TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 7ea037ca8b2..ffeaa861220 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -597,8 +597,6 @@ declare_features! (
     (unstable, strict_provenance, "1.61.0", Some(95228)),
     /// Allows string patterns to dereference values to match them.
     (unstable, string_deref_patterns, "1.67.0", Some(87121)),
-    /// Allows structs to carry target_feature information.
-    (incomplete, struct_target_features, "CURRENT_RUSTC_VERSION", Some(129107)),
     /// Allows the use of `#[target_feature]` on safe functions.
     (unstable, target_feature_11, "1.45.0", Some(69098)),
     /// Allows using `#[thread_local]` on `static` items.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 36e29d2dcb2..bd55617d84e 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -326,41 +326,6 @@ impl DefKind {
             | DefKind::ExternCrate => false,
         }
     }
-
-    /// Whether `query struct_target_features` should be used with this definition.
-    pub fn has_struct_target_features(self) -> bool {
-        match self {
-            DefKind::Struct | DefKind::Union | DefKind::Enum => true,
-            DefKind::Fn
-            | DefKind::AssocFn
-            | DefKind::Ctor(..)
-            | DefKind::Closure
-            | DefKind::Static { .. }
-            | DefKind::Mod
-            | DefKind::Variant
-            | DefKind::Trait
-            | DefKind::TyAlias
-            | DefKind::ForeignTy
-            | DefKind::TraitAlias
-            | DefKind::AssocTy
-            | DefKind::Const
-            | DefKind::AssocConst
-            | DefKind::Macro(..)
-            | DefKind::Use
-            | DefKind::ForeignMod
-            | DefKind::OpaqueTy
-            | DefKind::Impl { .. }
-            | DefKind::Field
-            | DefKind::TyParam
-            | DefKind::ConstParam
-            | DefKind::LifetimeParam
-            | DefKind::AnonConst
-            | DefKind::InlineConst
-            | DefKind::SyntheticCoroutineBody
-            | DefKind::GlobalAsm
-            | DefKind::ExternCrate => false,
-        }
-    }
 }
 
 /// The resolution of a path or export.
@@ -863,8 +828,13 @@ pub enum LifetimeRes {
     /// This variant is used for anonymous lifetimes that we did not resolve during
     /// late resolution. Those lifetimes will be inferred by typechecking.
     Infer,
-    /// Explicit `'static` lifetime.
-    Static,
+    /// `'static` lifetime.
+    Static {
+        /// We do not want to emit `elided_named_lifetimes`
+        /// when we are inside of a const item or a static,
+        /// because it would get too annoying.
+        suppress_elision_warning: bool,
+    },
     /// Resolution failure.
     Error,
     /// HACK: This is used to recover the NodeId of an elided lifetime.
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 865e9be0a67..d97c590bd41 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -851,8 +851,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     }
 
                     // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
-                    // FIXME(struct_target_features): should this be true also for functions that inherit
-                    // target features from structs?
 
                     if b_hdr.safety == hir::Safety::Safe
                         && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 08a50050a36..31b7eb5ee7d 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -252,6 +252,10 @@ lint_duplicate_macro_attribute =
 
 lint_duplicate_matcher_binding = duplicate matcher binding
 
+lint_elided_named_lifetime = elided lifetime has a name
+    .label_elided = this elided lifetime gets resolved as `{$name}`
+    .label_named = lifetime `{$name}` declared here
+
 lint_enum_intrinsics_mem_discriminant =
     the return value of `mem::discriminant` is unspecified when called with a non-enum type
     .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index f289d4c81b3..fd43afa1743 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -10,6 +10,7 @@ use rustc_errors::{
 use rustc_middle::middle::stability;
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::Session;
+use rustc_span::symbol::kw;
 use rustc_span::BytePos;
 use tracing::debug;
 
@@ -441,5 +442,17 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
         BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
             lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
         }
+        BuiltinLintDiag::ElidedIsStatic { elided } => {
+            lints::ElidedNamedLifetime { elided, name: kw::StaticLifetime, named_declaration: None }
+                .decorate_lint(diag)
+        }
+        BuiltinLintDiag::ElidedIsParam { elided, param: (param_name, param_span) } => {
+            lints::ElidedNamedLifetime {
+                elided,
+                name: param_name,
+                named_declaration: Some(param_span),
+            }
+            .decorate_lint(diag)
+        }
     }
 }
diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs
index 42b33f9882d..d8afba3d505 100644
--- a/compiler/rustc_lint/src/expect.rs
+++ b/compiler/rustc_lint/src/expect.rs
@@ -1,21 +1,66 @@
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_hir::{HirId, CRATE_OWNER_ID};
+use rustc_middle::lint::LintExpectation;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
-use rustc_session::lint::LintExpectationId;
+use rustc_session::lint::{Level, LintExpectationId};
 use rustc_span::Symbol;
 
 use crate::lints::{Expectation, ExpectationNote};
 
 pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers { check_expectations, ..*providers };
+    *providers = Providers { lint_expectations, check_expectations, ..*providers };
+}
+
+fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> {
+    let krate = tcx.hir_crate_items(());
+
+    let mut expectations = Vec::new();
+    let mut unstable_to_stable_ids = FxIndexMap::default();
+
+    let mut record_stable = |attr_id, hir_id, attr_index| {
+        let expect_id = LintExpectationId::Stable { hir_id, attr_index, lint_index: None };
+        unstable_to_stable_ids.entry(attr_id).or_insert(expect_id);
+    };
+    let mut push_expectations = |owner| {
+        let lints = tcx.shallow_lint_levels_on(owner);
+        if lints.expectations.is_empty() {
+            return;
+        }
+
+        expectations.extend_from_slice(&lints.expectations);
+
+        let attrs = tcx.hir_attrs(owner);
+        for &(local_id, attrs) in attrs.map.iter() {
+            // Some attributes appear multiple times in HIR, to ensure they are correctly taken
+            // into account where they matter. This means we cannot just associate the AttrId to
+            // the first HirId where we see it, but need to check it actually appears in a lint
+            // level.
+            // FIXME(cjgillot): Can this cause an attribute to appear in multiple expectation ids?
+            if !lints.specs.contains_key(&local_id) {
+                continue;
+            }
+            for (attr_index, attr) in attrs.iter().enumerate() {
+                let Some(Level::Expect(_)) = Level::from_attr(attr) else { continue };
+                record_stable(attr.id, HirId { owner, local_id }, attr_index.try_into().unwrap());
+            }
+        }
+    };
+
+    push_expectations(CRATE_OWNER_ID);
+    for owner in krate.owners() {
+        push_expectations(owner);
+    }
+
+    tcx.dcx().update_unstable_expectation_id(unstable_to_stable_ids);
+    expectations
 }
 
 fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
     let lint_expectations = tcx.lint_expectations(());
     let fulfilled_expectations = tcx.dcx().steal_fulfilled_expectation_ids();
 
-    tracing::debug!(?lint_expectations, ?fulfilled_expectations);
-
     for (id, expectation) in lint_expectations {
         // This check will always be true, since `lint_expectations` only
         // holds stable ids
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 07ac63ec96c..65289de980e 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -115,34 +115,6 @@ impl LintLevelSets {
     }
 }
 
-fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> {
-    let store = unerased_lint_store(tcx.sess);
-
-    let mut builder = LintLevelsBuilder {
-        sess: tcx.sess,
-        features: tcx.features(),
-        provider: QueryMapExpectationsWrapper {
-            tcx,
-            cur: hir::CRATE_HIR_ID,
-            specs: ShallowLintLevelMap::default(),
-            expectations: Vec::new(),
-            unstable_to_stable_ids: FxIndexMap::default(),
-            empty: FxIndexMap::default(),
-        },
-        lint_added_lints: false,
-        store,
-        registered_tools: tcx.registered_tools(()),
-    };
-
-    builder.add_command_line();
-    builder.add_id(hir::CRATE_HIR_ID);
-    tcx.hir().walk_toplevel_module(&mut builder);
-
-    tcx.dcx().update_unstable_expectation_id(&builder.provider.unstable_to_stable_ids);
-
-    builder.provider.expectations
-}
-
 #[instrument(level = "trace", skip(tcx), ret)]
 fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap {
     let store = unerased_lint_store(tcx.sess);
@@ -207,7 +179,7 @@ pub trait LintLevelsProvider {
     fn current_specs(&self) -> &FxIndexMap<LintId, LevelAndSource>;
     fn insert(&mut self, id: LintId, lvl: LevelAndSource);
     fn get_lint_level(&self, lint: &'static Lint, sess: &Session) -> LevelAndSource;
-    fn push_expectation(&mut self, _id: LintExpectationId, _expectation: LintExpectation) {}
+    fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation);
 }
 
 impl LintLevelsProvider for TopDown {
@@ -222,6 +194,8 @@ impl LintLevelsProvider for TopDown {
     fn get_lint_level(&self, lint: &'static Lint, sess: &Session) -> LevelAndSource {
         self.sets.get_lint_level(lint, self.cur, Some(self.current_specs()), sess)
     }
+
+    fn push_expectation(&mut self, _: LintExpectationId, _: LintExpectation) {}
 }
 
 struct LintLevelQueryMap<'tcx> {
@@ -243,47 +217,8 @@ impl LintLevelsProvider for LintLevelQueryMap<'_> {
     fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource {
         self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur)
     }
-}
-
-struct QueryMapExpectationsWrapper<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    /// HirId of the currently investigated element.
-    cur: HirId,
-    /// Level map for `cur`.
-    specs: ShallowLintLevelMap,
-    expectations: Vec<(LintExpectationId, LintExpectation)>,
-    unstable_to_stable_ids: FxIndexMap<LintExpectationId, LintExpectationId>,
-    /// Empty hash map to simplify code.
-    empty: FxIndexMap<LintId, LevelAndSource>,
-}
-
-impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> {
-    fn current_specs(&self) -> &FxIndexMap<LintId, LevelAndSource> {
-        self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty)
-    }
-    fn insert(&mut self, id: LintId, lvl: LevelAndSource) {
-        self.specs.specs.get_mut_or_insert_default(self.cur.local_id).insert(id, lvl);
-    }
-    fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource {
-        // We cannot use `tcx.lint_level_at_node` because we want to know in which order the
-        // attributes have been inserted, in particular whether an `expect` follows a `forbid`.
-        self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur)
-    }
     fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation) {
-        let LintExpectationId::Stable { attr_id: Some(attr_id), hir_id, attr_index, .. } = id
-        else {
-            bug!("unstable expectation id should already be mapped")
-        };
-        let key = LintExpectationId::Unstable { attr_id, lint_index: None };
-
-        self.unstable_to_stable_ids.entry(key).or_insert(LintExpectationId::Stable {
-            hir_id,
-            attr_index,
-            lint_index: None,
-            attr_id: None,
-        });
-
-        self.expectations.push((id.normalize(), expectation));
+        self.specs.expectations.push((id, expectation))
     }
 }
 
@@ -368,80 +303,6 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
     }
 }
 
-impl<'tcx> LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> {
-    fn add_id(&mut self, hir_id: HirId) {
-        // Change both the `HirId` and the associated specs.
-        self.provider.cur = hir_id;
-        self.provider.specs.specs.clear();
-        self.add(self.provider.tcx.hir().attrs(hir_id), hir_id == hir::CRATE_HIR_ID, Some(hir_id));
-    }
-}
-
-impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> {
-    type NestedFilter = nested_filter::All;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.provider.tcx.hir()
-    }
-
-    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
-        self.add_id(param.hir_id);
-        intravisit::walk_param(self, param);
-    }
-
-    fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
-        self.add_id(it.hir_id());
-        intravisit::walk_item(self, it);
-    }
-
-    fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
-        self.add_id(it.hir_id());
-        intravisit::walk_foreign_item(self, it);
-    }
-
-    fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) {
-        // We will call `add_id` when we walk
-        // the `StmtKind`. The outer statement itself doesn't
-        // define the lint levels.
-        intravisit::walk_stmt(self, e);
-    }
-
-    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
-        self.add_id(e.hir_id);
-        intravisit::walk_expr(self, e);
-    }
-
-    fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
-        self.add_id(s.hir_id);
-        intravisit::walk_field_def(self, s);
-    }
-
-    fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
-        self.add_id(v.hir_id);
-        intravisit::walk_variant(self, v);
-    }
-
-    fn visit_local(&mut self, l: &'tcx hir::LetStmt<'tcx>) {
-        self.add_id(l.hir_id);
-        intravisit::walk_local(self, l);
-    }
-
-    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
-        self.add_id(a.hir_id);
-        intravisit::walk_arm(self, a);
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
-        self.add_id(trait_item.hir_id());
-        intravisit::walk_trait_item(self, trait_item);
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
-        self.add_id(impl_item.hir_id());
-        intravisit::walk_impl_item(self, impl_item);
-    }
-}
-
 pub struct LintLevelsBuilder<'s, P> {
     sess: &'s Session,
     features: &'s Features,
@@ -625,13 +486,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful
     /// (e.g. if a forbid was already inserted on the same scope), then emits a
     /// diagnostic with no change to `specs`.
-    fn insert_spec(&mut self, id: LintId, (mut level, src): LevelAndSource) {
+    fn insert_spec(&mut self, id: LintId, (level, src): LevelAndSource) {
         let (old_level, old_src) = self.provider.get_lint_level(id.lint, self.sess);
-        if let Level::Expect(id) = &mut level
-            && let LintExpectationId::Stable { .. } = id
-        {
-            *id = id.normalize();
-        }
+
         // Setting to a non-forbid level is an error if the lint previously had
         // a forbid level. Note that this is not necessarily true even with a
         // `#[forbid(..)]` attribute present, as that is overridden by `--cap-lints`.
@@ -743,17 +600,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 // This is the only lint level with a `LintExpectationId` that can be created from
                 // an attribute.
                 Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {
-                    let LintExpectationId::Unstable { attr_id, lint_index } = unstable_id else {
+                    let LintExpectationId::Unstable { lint_index: None, attr_id: _ } = unstable_id
+                    else {
                         bug!("stable id Level::from_attr")
                     };
 
                     let stable_id = LintExpectationId::Stable {
                         hir_id,
                         attr_index: attr_index.try_into().unwrap(),
-                        lint_index,
-                        // We pass the previous unstable attr_id such that we can trace the ast id
-                        // when building a map to go from unstable to stable id.
-                        attr_id: Some(attr_id),
+                        lint_index: None,
                     };
 
                     Level::Expect(stable_id)
@@ -840,59 +695,20 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 let name = pprust::path_to_string(&meta_item.path);
                 let lint_result =
                     self.store.check_lint_name(&name, tool_name, self.registered_tools);
-                match &lint_result {
+
+                let (ids, name) = match lint_result {
                     CheckLintNameResult::Ok(ids) => {
-                        // This checks for instances where the user writes
-                        // `#[expect(unfulfilled_lint_expectations)]` in that case we want to avoid
-                        // overriding the lint level but instead add an expectation that can't be
-                        // fulfilled. The lint message will include an explanation, that the
-                        // `unfulfilled_lint_expectations` lint can't be expected.
-                        if let Level::Expect(expect_id) = level {
-                            // The `unfulfilled_lint_expectations` lint is not part of any lint
-                            // groups. Therefore. we only need to check the slice if it contains a
-                            // single lint.
-                            let is_unfulfilled_lint_expectations = match ids {
-                                [lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS),
-                                _ => false,
-                            };
-                            self.provider.push_expectation(
-                                expect_id,
-                                LintExpectation::new(
-                                    reason,
-                                    sp,
-                                    is_unfulfilled_lint_expectations,
-                                    tool_name,
-                                ),
-                            );
-                        }
-                        let src = LintLevelSource::Node {
-                            name: meta_item
-                                .path
-                                .segments
-                                .last()
-                                .expect("empty lint name")
-                                .ident
-                                .name,
-                            span: sp,
-                            reason,
-                        };
-                        for &id in *ids {
-                            if self.check_gated_lint(id, attr.span, false) {
-                                self.insert_spec(id, (level, src));
-                            }
-                        }
+                        let name =
+                            meta_item.path.segments.last().expect("empty lint name").ident.name;
+                        (ids, name)
                     }
 
                     CheckLintNameResult::Tool(ids, new_lint_name) => {
-                        let src = match new_lint_name {
+                        let name = match new_lint_name {
                             None => {
                                 let complete_name =
                                     &format!("{}::{}", tool_ident.unwrap().name, name);
-                                LintLevelSource::Node {
-                                    name: Symbol::intern(complete_name),
-                                    span: sp,
-                                    reason,
-                                }
+                                Symbol::intern(complete_name)
                             }
                             Some(new_lint_name) => {
                                 self.emit_span_lint(
@@ -901,27 +717,13 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                                     DeprecatedLintName {
                                         name,
                                         suggestion: sp,
-                                        replace: new_lint_name,
+                                        replace: &new_lint_name,
                                     },
                                 );
-                                LintLevelSource::Node {
-                                    name: Symbol::intern(new_lint_name),
-                                    span: sp,
-                                    reason,
-                                }
+                                Symbol::intern(&new_lint_name)
                             }
                         };
-                        for &id in *ids {
-                            if self.check_gated_lint(id, attr.span, false) {
-                                self.insert_spec(id, (level, src));
-                            }
-                        }
-                        if let Level::Expect(expect_id) = level {
-                            self.provider.push_expectation(
-                                expect_id,
-                                LintExpectation::new(reason, sp, false, tool_name),
-                            );
-                        }
+                        (ids, name)
                     }
 
                     CheckLintNameResult::MissingTool => {
@@ -929,9 +731,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                         // exist in the tool or the code was not compiled with the tool and
                         // therefore the lint was never added to the `LintStore`. To detect
                         // this is the responsibility of the lint tool.
+                        continue;
                     }
 
-                    &CheckLintNameResult::NoTool => {
+                    CheckLintNameResult::NoTool => {
                         sess.dcx().emit_err(UnknownToolInScopedLint {
                             span: tool_ident.map(|ident| ident.span),
                             tool_name: tool_name.unwrap(),
@@ -941,58 +744,88 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                         continue;
                     }
 
-                    _ if !self.lint_added_lints => {}
-
                     CheckLintNameResult::Renamed(ref replace) => {
-                        let suggestion =
-                            RenamedLintSuggestion::WithSpan { suggestion: sp, replace };
-                        let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
-                        let lint = RenamedLint { name: name.as_str(), suggestion };
-                        self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
+                        if self.lint_added_lints {
+                            let suggestion =
+                                RenamedLintSuggestion::WithSpan { suggestion: sp, replace };
+                            let name =
+                                tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
+                            let lint = RenamedLint { name: name.as_str(), suggestion };
+                            self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
+                        }
+
+                        // If this lint was renamed, apply the new lint instead of ignoring the
+                        // attribute. Ignore any errors or warnings that happen because the new
+                        // name is inaccurate.
+                        // NOTE: `new_name` already includes the tool name, so we don't
+                        // have to add it again.
+                        let CheckLintNameResult::Ok(ids) =
+                            self.store.check_lint_name(replace, None, self.registered_tools)
+                        else {
+                            panic!("renamed lint does not exist: {replace}");
+                        };
+
+                        (ids, Symbol::intern(&replace))
                     }
 
                     CheckLintNameResult::Removed(ref reason) => {
-                        let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
-                        let lint = RemovedLint { name: name.as_str(), reason };
-                        self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
+                        if self.lint_added_lints {
+                            let name =
+                                tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
+                            let lint = RemovedLint { name: name.as_str(), reason };
+                            self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
+                        }
+                        continue;
                     }
 
                     CheckLintNameResult::NoLint(suggestion) => {
-                        let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
-                        let suggestion = suggestion.map(|(replace, from_rustc)| {
-                            UnknownLintSuggestion::WithSpan { suggestion: sp, replace, from_rustc }
-                        });
-                        let lint = UnknownLint { name, suggestion };
-                        self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint);
-                    }
-                }
-                // If this lint was renamed, apply the new lint instead of ignoring the attribute.
-                // This happens outside of the match because the new lint should be applied even if
-                // we don't warn about the name change.
-                if let CheckLintNameResult::Renamed(new_name) = lint_result {
-                    // Ignore any errors or warnings that happen because the new name is inaccurate
-                    // NOTE: `new_name` already includes the tool name, so we don't have to add it
-                    // again.
-                    let CheckLintNameResult::Ok(ids) =
-                        self.store.check_lint_name(&new_name, None, self.registered_tools)
-                    else {
-                        panic!("renamed lint does not exist: {new_name}");
-                    };
-
-                    let src =
-                        LintLevelSource::Node { name: Symbol::intern(&new_name), span: sp, reason };
-                    for &id in ids {
-                        if self.check_gated_lint(id, attr.span, false) {
-                            self.insert_spec(id, (level, src));
+                        if self.lint_added_lints {
+                            let name =
+                                tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
+                            let suggestion = suggestion.map(|(replace, from_rustc)| {
+                                UnknownLintSuggestion::WithSpan {
+                                    suggestion: sp,
+                                    replace,
+                                    from_rustc,
+                                }
+                            });
+                            let lint = UnknownLint { name, suggestion };
+                            self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint);
                         }
+                        continue;
                     }
-                    if let Level::Expect(expect_id) = level {
-                        self.provider.push_expectation(
-                            expect_id,
-                            LintExpectation::new(reason, sp, false, tool_name),
-                        );
+                };
+
+                let src = LintLevelSource::Node { name, span: sp, reason };
+                for &id in ids {
+                    if self.check_gated_lint(id, attr.span, false) {
+                        self.insert_spec(id, (level, src));
                     }
                 }
+
+                // This checks for instances where the user writes
+                // `#[expect(unfulfilled_lint_expectations)]` in that case we want to avoid
+                // overriding the lint level but instead add an expectation that can't be
+                // fulfilled. The lint message will include an explanation, that the
+                // `unfulfilled_lint_expectations` lint can't be expected.
+                if let Level::Expect(expect_id) = level {
+                    // The `unfulfilled_lint_expectations` lint is not part of any lint
+                    // groups. Therefore. we only need to check the slice if it contains a
+                    // single lint.
+                    let is_unfulfilled_lint_expectations = match ids {
+                        [lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS),
+                        _ => false,
+                    };
+                    self.provider.push_expectation(
+                        expect_id,
+                        LintExpectation::new(
+                            reason,
+                            sp,
+                            is_unfulfilled_lint_expectations,
+                            tool_name,
+                        ),
+                    );
+                }
             }
         }
 
@@ -1100,7 +933,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers };
+    *providers = Providers { shallow_lint_levels_on, ..*providers };
 }
 
 pub(crate) fn parse_lint_and_tool_name(lint_name: &str) -> (Option<Symbol>, &str) {
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index c6bcb1f3e83..2712e25668a 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2612,6 +2612,16 @@ pub(crate) struct ElidedLifetimesInPaths {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_elided_named_lifetime)]
+pub(crate) struct ElidedNamedLifetime {
+    #[label(lint_label_elided)]
+    pub elided: Span,
+    pub name: Symbol,
+    #[label(lint_label_named)]
+    pub named_declaration: Option<Span>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(lint_invalid_crate_type_value)]
 pub(crate) struct UnknownCrateTypes {
     #[subdiagnostic]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 04fd7c9c627..7063f488209 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -42,6 +42,7 @@ declare_lint_pass! {
         DUPLICATE_MACRO_ATTRIBUTES,
         ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
         ELIDED_LIFETIMES_IN_PATHS,
+        ELIDED_NAMED_LIFETIMES,
         EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
         EXPORTED_PRIVATE_DEPENDENCIES,
         FFI_UNWIND_CALLS,
@@ -1863,6 +1864,38 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `elided_named_lifetimes` lint detects when an elided
+    /// lifetime ends up being a named lifetime, such as `'static`
+    /// or some lifetime parameter `'a`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(elided_named_lifetimes)]
+    /// struct Foo;
+    /// impl Foo {
+    ///     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
+    ///         unsafe { &mut *(x as *mut _) }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Lifetime elision is quite useful, because it frees you from having
+    /// to give each lifetime its own name, but sometimes it can produce
+    /// somewhat surprising resolutions. In safe code, it is mostly okay,
+    /// because the borrow checker prevents any unsoundness, so the worst
+    /// case scenario is you get a confusing error message in some other place.
+    /// But with `unsafe` code, such unexpected resolutions may lead to unsound code.
+    pub ELIDED_NAMED_LIFETIMES,
+    Warn,
+    "detects when an elided lifetime gets resolved to be `'static` or some named parameter"
+}
+
+declare_lint! {
     /// The `bare_trait_objects` lint suggests using `dyn Trait` for trait
     /// objects.
     ///
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index c17b85db3b0..6ee33041623 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -98,7 +98,7 @@ pub enum LintExpectationId {
     /// stable and can be cached. The additional index ensures that nodes with
     /// several expectations can correctly match diagnostics to the individual
     /// expectation.
-    Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16>, attr_id: Option<AttrId> },
+    Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16> },
 }
 
 impl LintExpectationId {
@@ -122,31 +122,13 @@ impl LintExpectationId {
 
         *lint_index = new_lint_index
     }
-
-    /// Prepares the id for hashing. Removes references to the ast.
-    /// Should only be called when the id is stable.
-    pub fn normalize(self) -> Self {
-        match self {
-            Self::Stable { hir_id, attr_index, lint_index, .. } => {
-                Self::Stable { hir_id, attr_index, lint_index, attr_id: None }
-            }
-            Self::Unstable { .. } => {
-                unreachable!("`normalize` called when `ExpectationId` is unstable")
-            }
-        }
-    }
 }
 
 impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId {
     #[inline]
     fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
         match self {
-            LintExpectationId::Stable {
-                hir_id,
-                attr_index,
-                lint_index: Some(lint_index),
-                attr_id: _,
-            } => {
+            LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
                 hir_id.hash_stable(hcx, hasher);
                 attr_index.hash_stable(hcx, hasher);
                 lint_index.hash_stable(hcx, hasher);
@@ -166,12 +148,9 @@ impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectation
     #[inline]
     fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
         match self {
-            LintExpectationId::Stable {
-                hir_id,
-                attr_index,
-                lint_index: Some(lint_index),
-                attr_id: _,
-            } => (*hir_id, *attr_index, *lint_index),
+            LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
+                (*hir_id, *attr_index, *lint_index)
+            }
             _ => {
                 unreachable!("HashStable should only be called for a filled `LintExpectationId`")
             }
@@ -589,6 +568,13 @@ pub enum BuiltinLintDiag {
     },
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
     ElidedLifetimesInPaths(usize, Span, bool, Span),
+    ElidedIsStatic {
+        elided: Span,
+    },
+    ElidedIsParam {
+        elided: Span,
+        param: (Symbol, Span),
+    },
     UnknownCrateTypes {
         span: Span,
         candidate: Option<Symbol>,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index a82340e3d61..0f46cacc27a 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -254,7 +254,6 @@ provide! { tcx, def_id, other, cdata,
     variances_of => { table }
     fn_sig => { table }
     codegen_fn_attrs => { table }
-    struct_target_features => { table }
     impl_trait_header => { table }
     const_param_default => { table }
     object_lifetime_default => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 919623cff60..88256c4db04 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1392,9 +1392,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if def_kind.has_codegen_attrs() {
                 record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
             }
-            if def_kind.has_struct_target_features() {
-                record_array!(self.tables.struct_target_features[def_id] <- self.tcx.struct_target_features(def_id));
-            }
             if should_encode_visibility(def_kind) {
                 let vis =
                     self.tcx.local_visibility(local_id).map_id(|def_id| def_id.local_def_index);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 987ee3f07e9..a84923130c3 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -19,7 +19,7 @@ use rustc_macros::{
     Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, TyEncodable,
 };
 use rustc_middle::metadata::ModChild;
-use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::middle::lib_features::FeatureStability;
@@ -427,7 +427,6 @@ define_tables! {
     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
     fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
     codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
-    struct_target_features: Table<DefIndex, LazyArray<TargetFeature>>,
     impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
     const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, rustc_middle::ty::Const<'static>>>>,
     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 8c27cac1ea8..70da66af64b 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -6,7 +6,7 @@ use rustc_errors::{Diag, MultiSpan};
 use rustc_hir::{HirId, ItemLocalId};
 use rustc_macros::HashStable;
 use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
-use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintId};
+use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
 use rustc_session::Session;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::{symbol, DesugaringKind, Span, Symbol, DUMMY_SP};
@@ -61,6 +61,7 @@ pub type LevelAndSource = (Level, LintLevelSource);
 /// by the attributes for *a single HirId*.
 #[derive(Default, Debug, HashStable)]
 pub struct ShallowLintLevelMap {
+    pub expectations: Vec<(LintExpectationId, LintExpectation)>,
     pub specs: SortedMap<ItemLocalId, FxIndexMap<LintId, LevelAndSource>>,
 }
 
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index c098a739592..b7d290e58d2 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -26,8 +26,8 @@ pub struct CodegenFnAttrs {
     /// be set when `link_name` is set. This is for foreign items with the
     /// "raw-dylib" kind.
     pub link_ordinal: Option<u16>,
-    /// All the target features that are enabled for this function. Some features might be enabled
-    /// implicitly.
+    /// The `#[target_feature(enable = "...")]` attribute and the enabled
+    /// features (only enabled features are supported right now).
     pub target_features: Vec<TargetFeature>,
     /// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
     pub linkage: Option<Linkage>,
@@ -55,8 +55,8 @@ pub struct CodegenFnAttrs {
 pub struct TargetFeature {
     /// The name of the target feature (e.g. "avx")
     pub name: Symbol,
-    /// The feature is implied by another feature or by an argument, rather than explicitly
-    /// added by the `#[target_feature]` attribute
+    /// The feature is implied by another feature, rather than explicitly added by the
+    /// `#[target_feature]` attribute
     pub implied: bool,
 }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b6443778c93..d6bdc1af0d2 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -47,7 +47,7 @@ use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
 use crate::infer::canonical::{self, Canonical};
 use crate::lint::LintExpectation;
 use crate::metadata::ModChild;
-use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
+use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use crate::middle::lib_features::LibFeatures;
@@ -1249,11 +1249,6 @@ rustc_queries! {
         feedable
     }
 
-    query struct_target_features(def_id: DefId) -> &'tcx [TargetFeature] {
-        separate_provide_extern
-        desc { |tcx| "computing target features for struct `{}`", tcx.def_path_str(def_id) }
-    }
-
     query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> {
         desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
     }
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index be611e19b49..7e1255f606c 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -59,7 +59,6 @@ trivially_parameterized_over_tcx! {
     std::string::String,
     crate::metadata::ModChild,
     crate::middle::codegen_fn_attrs::CodegenFnAttrs,
-    crate::middle::codegen_fn_attrs::TargetFeature,
     crate::middle::debugger_visualizer::DebuggerVisualizerFile,
     crate::middle::exported_symbols::SymbolExportInfo,
     crate::middle::lib_features::FeatureStability,
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index a42e8ff0168..7a10e627ccd 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -125,17 +125,6 @@ mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
-mir_build_initializing_type_with_target_feature_requires_unsafe =
-    initializing type with `target_feature` attr is unsafe and requires unsafe block
-    .note = this struct can only be constructed if the corresponding `target_feature`s are available
-    .label = initializing type with `target_feature` attr
-
-mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
-    initializing type with `target_feature` attr is unsafe and requires unsafe function or block
-    .note = this struct can only be constructed if the corresponding `target_feature`s are available
-    .label = initializing type with `target_feature` attr
-
-
 mir_build_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
@@ -398,11 +387,6 @@ mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
-mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe =
-    initializing type with `target_feature` attr is unsafe and requires unsafe block
-    .note = this struct can only be constructed if the corresponding `target_feature`s are available
-    .label = initializing type with `target_feature` attr
-
 mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 4ce796cea7a..c7fcfe3ce2a 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -461,18 +461,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     };
                     self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
                 } else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
-                    // If the called function has explicit target features the calling function hasn't,
+                    // If the called function has target features the calling function hasn't,
                     // the call requires `unsafe`. Don't check this on wasm
                     // targets, though. For more information on wasm see the
                     // is_like_wasm check in hir_analysis/src/collect.rs
-                    // Implicit target features are OK because they are either a consequence of some
-                    // explicit target feature (which is checked to be present in the caller) or
-                    // come from a witness argument.
                     let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
                     if !self.tcx.sess.target.options.is_like_wasm
                         && !callee_features.iter().all(|feature| {
-                            feature.implied
-                                || self.body_target_features.iter().any(|f| f.name == feature.name)
+                            self.body_target_features.iter().any(|f| f.name == feature.name)
                         })
                     {
                         let missing: Vec<_> = callee_features
@@ -546,16 +542,10 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 user_ty: _,
                 fields: _,
                 base: _,
-            }) => {
-                match self.tcx.layout_scalar_valid_range(adt_def.did()) {
-                    (Bound::Unbounded, Bound::Unbounded) => {}
-                    _ => self.requires_unsafe(expr.span, InitializingTypeWith),
-                }
-                if !self.tcx.struct_target_features(adt_def.did()).is_empty() {
-                    self.requires_unsafe(expr.span, ConstructingTargetFeaturesType)
-                }
-            }
-
+            }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
+                (Bound::Unbounded, Bound::Unbounded) => {}
+                _ => self.requires_unsafe(expr.span, InitializingTypeWith),
+            },
             ExprKind::Closure(box ClosureExpr {
                 closure_id,
                 args: _,
@@ -657,7 +647,6 @@ enum UnsafeOpKind {
     CallToUnsafeFunction(Option<DefId>),
     UseOfInlineAssembly,
     InitializingTypeWith,
-    ConstructingTargetFeaturesType,
     UseOfMutableStatic,
     UseOfExternStatic,
     DerefOfRawPointer,
@@ -739,15 +728,6 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
-            ConstructingTargetFeaturesType => tcx.emit_node_span_lint(
-                UNSAFE_OP_IN_UNSAFE_FN,
-                hir_id,
-                span,
-                UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
-                    span,
-                    unsafe_not_inherited_note,
-                },
-            ),
             UseOfMutableStatic => tcx.emit_node_span_lint(
                 UNSAFE_OP_IN_UNSAFE_FN,
                 hir_id,
@@ -905,20 +885,6 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 });
             }
-            ConstructingTargetFeaturesType if unsafe_op_in_unsafe_fn_allowed => {
-                dcx.emit_err(
-                    InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
-                        span,
-                        unsafe_not_inherited_note,
-                    },
-                );
-            }
-            ConstructingTargetFeaturesType => {
-                dcx.emit_err(InitializingTypeWithTargetFeatureRequiresUnsafe {
-                    span,
-                    unsafe_not_inherited_note,
-                });
-            }
             UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
                 dcx.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index e7d6239aa9b..7f9eefd1d52 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -87,16 +87,6 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
-#[note]
-pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
-    #[label]
-    pub(crate) span: Span,
-    #[subdiagnostic]
-    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
@@ -261,17 +251,6 @@ pub(crate) struct InitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
-#[note]
-pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafe {
-    #[primary_span]
-    #[label]
-    pub(crate) span: Span,
-    #[subdiagnostic]
-    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
-}
-
-#[derive(Diagnostic)]
 #[diag(
     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
     code = E0133
@@ -286,20 +265,6 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(
-    mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = E0133
-)]
-#[note]
-pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
-    #[primary_span]
-    #[label]
-    pub(crate) span: Span,
-    #[subdiagnostic]
-    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
-}
-
-#[derive(Diagnostic)]
 #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UseOfMutableStaticRequiresUnsafe {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 38450fc288a..e7f208d5ad5 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -672,10 +672,6 @@ passes_should_be_applied_to_fn =
         *[false] not a function definition
     }
 
-passes_should_be_applied_to_fn_or_unit_struct =
-    attribute should be applied to a function definition or unit struct
-    .label = not a function definition or a unit struct
-
 passes_should_be_applied_to_static =
     attribute should be applied to a static
     .label = not a static
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 5dbb3854c8f..21478a44b0e 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -747,35 +747,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             Target::Field | Target::Arm | Target::MacroDef => {
                 self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature");
             }
-            Target::Struct if self.tcx.features().struct_target_features => {
-                let ty = self.tcx.hir_node(hir_id).expect_item();
-                match ty.kind {
-                    ItemKind::Struct(data, _) => {
-                        if data.fields().len() != 0 {
-                            self.dcx().emit_err(errors::AttrShouldBeAppliedToFnOrUnitStruct {
-                                attr_span: attr.span,
-                                defn_span: span,
-                            });
-                        }
-                    }
-                    _ => {
-                        panic!("Target::Struct for a non-struct");
-                    }
-                }
-            }
             _ => {
-                if self.tcx.features().struct_target_features {
-                    self.dcx().emit_err(errors::AttrShouldBeAppliedToFnOrUnitStruct {
-                        attr_span: attr.span,
-                        defn_span: span,
-                    });
-                } else {
-                    self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                        attr_span: attr.span,
-                        defn_span: span,
-                        on_crate: hir_id == CRATE_HIR_ID,
-                    });
-                }
+                self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
+                    attr_span: attr.span,
+                    defn_span: span,
+                    on_crate: hir_id == CRATE_HIR_ID,
+                });
             }
         }
     }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 1e9ab7af9be..f5d982e1a5c 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -83,15 +83,6 @@ pub(crate) struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_fn_or_unit_struct)]
-pub(crate) struct AttrShouldBeAppliedToFnOrUnitStruct {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_fn, code = E0739)]
 pub(crate) struct TrackedCallerWrongLocation {
     #[primary_span]
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 3595db78e93..a70d51606f7 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -2,6 +2,7 @@ use std::mem;
 
 use rustc_ast::visit::FnKind;
 use rustc_ast::*;
+use rustc_ast_pretty::pprust;
 use rustc_expand::expand::AstFragment;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind};
@@ -120,8 +121,6 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
 
 impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
     fn visit_item(&mut self, i: &'a Item) {
-        debug!("visit_item: {:?}", i);
-
         // Pick the def data. This need not be unique, but the more
         // information we encapsulate into, the better
         let mut opt_macro_data = None;
@@ -183,38 +182,51 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
     }
 
     fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
-        if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
-            match sig.header.coroutine_kind {
-                Some(coroutine_kind) => {
-                    self.visit_generics(generics);
-
-                    // For async functions, we need to create their inner defs inside of a
-                    // closure to match their desugared representation. Besides that,
-                    // we must mirror everything that `visit::walk_fn` below does.
-                    self.visit_fn_header(&sig.header);
-                    for param in &sig.decl.inputs {
-                        self.visit_param(param);
-                    }
-                    self.visit_fn_ret_ty(&sig.decl.output);
-                    // If this async fn has no body (i.e. it's an async fn signature in a trait)
-                    // then the closure_def will never be used, and we should avoid generating a
-                    // def-id for it.
-                    if let Some(body) = body {
-                        let closure_def = self.create_def(
-                            coroutine_kind.closure_id(),
-                            kw::Empty,
-                            DefKind::Closure,
-                            span,
-                        );
-                        self.with_parent(closure_def, |this| this.visit_block(body));
-                    }
-                    return;
+        match fn_kind {
+            FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body)
+                if let Some(coroutine_kind) = header.coroutine_kind =>
+            {
+                self.visit_fn_header(header);
+                self.visit_generics(generics);
+
+                // For async functions, we need to create their inner defs inside of a
+                // closure to match their desugared representation. Besides that,
+                // we must mirror everything that `visit::walk_fn` below does.
+                let FnDecl { inputs, output } = &**decl;
+                for param in inputs {
+                    self.visit_param(param);
+                }
+
+                let (return_id, return_span) = coroutine_kind.return_id();
+                let return_def =
+                    self.create_def(return_id, kw::Empty, DefKind::OpaqueTy, return_span);
+                self.with_parent(return_def, |this| this.visit_fn_ret_ty(output));
+
+                // If this async fn has no body (i.e. it's an async fn signature in a trait)
+                // then the closure_def will never be used, and we should avoid generating a
+                // def-id for it.
+                if let Some(body) = body {
+                    let closure_def = self.create_def(
+                        coroutine_kind.closure_id(),
+                        kw::Empty,
+                        DefKind::Closure,
+                        span,
+                    );
+                    self.with_parent(closure_def, |this| this.visit_block(body));
                 }
-                None => {}
             }
-        }
+            FnKind::Closure(binder, Some(coroutine_kind), decl, body) => {
+                self.visit_closure_binder(binder);
+                visit::walk_fn_decl(self, decl);
 
-        visit::walk_fn(self, fn_kind);
+                // Async closures desugar to closures inside of closures, so
+                // we must create two defs.
+                let coroutine_def =
+                    self.create_def(coroutine_kind.closure_id(), kw::Empty, DefKind::Closure, span);
+                self.with_parent(coroutine_def, |this| visit::walk_expr(this, body));
+            }
+            _ => visit::walk_fn(self, fn_kind),
+        }
     }
 
     fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
@@ -334,27 +346,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
     fn visit_expr(&mut self, expr: &'a Expr) {
         let parent_def = match expr.kind {
             ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id),
-            ExprKind::Closure(ref closure) => {
-                // Async closures desugar to closures inside of closures, so
-                // we must create two defs.
-                let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
-                match closure.coroutine_kind {
-                    Some(coroutine_kind) => {
-                        self.with_parent(closure_def, |this| {
-                            let coroutine_def = this.create_def(
-                                coroutine_kind.closure_id(),
-                                kw::Empty,
-                                DefKind::Closure,
-                                expr.span,
-                            );
-                            this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr));
-                        });
-                        return;
-                    }
-                    None => closure_def,
-                }
-            }
-            ExprKind::Gen(_, _, _, _) => {
+            ExprKind::Closure(..) | ExprKind::Gen(..) => {
                 self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
             }
             ExprKind::ConstBlock(ref constant) => {
@@ -381,6 +373,26 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
             TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
             // Anonymous structs or unions are visited later after defined.
             TyKind::AnonStruct(..) | TyKind::AnonUnion(..) => {}
+            TyKind::ImplTrait(id, _) => {
+                // HACK: pprust breaks strings with newlines when the type
+                // gets too long. We don't want these to show up in compiler
+                // output or built artifacts, so replace them here...
+                // Perhaps we should instead format APITs more robustly.
+                let name = Symbol::intern(&pprust::ty_to_string(ty).replace('\n', " "));
+                let kind = match self.impl_trait_context {
+                    ImplTraitContext::Universal => DefKind::TyParam,
+                    ImplTraitContext::Existential => DefKind::OpaqueTy,
+                };
+                let id = self.create_def(*id, name, kind, ty.span);
+                match self.impl_trait_context {
+                    // Do not nest APIT, as we desugar them as `impl_trait: bounds`,
+                    // so the `impl_trait` node is not a parent to `bounds`.
+                    ImplTraitContext::Universal => visit::walk_ty(self, ty),
+                    ImplTraitContext::Existential => {
+                        self.with_parent(id, |this| visit::walk_ty(this, ty))
+                    }
+                };
+            }
             _ => visit::walk_ty(self, ty),
         }
     }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 40fdb01a72c..a0386ddcbb3 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1010,7 +1010,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                             this.in_func_body = previous_state;
                         }
                     }
-                    FnKind::Closure(binder, declaration, body) => {
+                    FnKind::Closure(binder, _, declaration, body) => {
                         this.visit_closure_binder(binder);
 
                         this.with_lifetime_rib(
@@ -1557,14 +1557,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         if ident.name == kw::StaticLifetime {
             self.record_lifetime_res(
                 lifetime.id,
-                LifetimeRes::Static,
+                LifetimeRes::Static { suppress_elision_warning: false },
                 LifetimeElisionCandidate::Named,
             );
             return;
         }
 
         if ident.name == kw::UnderscoreLifetime {
-            return self.resolve_anonymous_lifetime(lifetime, false);
+            return self.resolve_anonymous_lifetime(lifetime, lifetime.id, false);
         }
 
         let mut lifetime_rib_iter = self.lifetime_ribs.iter().rev();
@@ -1667,13 +1667,23 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn resolve_anonymous_lifetime(&mut self, lifetime: &Lifetime, elided: bool) {
+    fn resolve_anonymous_lifetime(
+        &mut self,
+        lifetime: &Lifetime,
+        id_for_lint: NodeId,
+        elided: bool,
+    ) {
         debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
 
         let kind =
             if elided { MissingLifetimeKind::Ampersand } else { MissingLifetimeKind::Underscore };
-        let missing_lifetime =
-            MissingLifetime { id: lifetime.id, span: lifetime.ident.span, kind, count: 1 };
+        let missing_lifetime = MissingLifetime {
+            id: lifetime.id,
+            span: lifetime.ident.span,
+            kind,
+            count: 1,
+            id_for_lint,
+        };
         let elision_candidate = LifetimeElisionCandidate::Missing(missing_lifetime);
         for (i, rib) in self.lifetime_ribs.iter().enumerate().rev() {
             debug!(?rib.kind);
@@ -1697,7 +1707,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     if lifetimes_in_scope.is_empty() {
                         self.record_lifetime_res(
                             lifetime.id,
-                            LifetimeRes::Static,
+                            // We are inside a const item, so do not warn.
+                            LifetimeRes::Static { suppress_elision_warning: true },
                             elision_candidate,
                         );
                         return;
@@ -1800,7 +1811,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             LifetimeRes::ElidedAnchor { start: id, end: NodeId::from_u32(id.as_u32() + 1) },
             LifetimeElisionCandidate::Ignore,
         );
-        self.resolve_anonymous_lifetime(&lt, true);
+        self.resolve_anonymous_lifetime(&lt, anchor_id, true);
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -1916,6 +1927,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             };
             let missing_lifetime = MissingLifetime {
                 id: node_ids.start,
+                id_for_lint: segment_id,
                 span: elided_lifetime_span,
                 kind,
                 count: expected_lifetimes,
@@ -2039,8 +2051,44 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
             panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)")
         }
+
+        match candidate {
+            LifetimeElisionCandidate::Missing(missing @ MissingLifetime { .. }) => {
+                debug_assert_eq!(id, missing.id);
+                match res {
+                    LifetimeRes::Static { suppress_elision_warning } => {
+                        if !suppress_elision_warning {
+                            self.r.lint_buffer.buffer_lint(
+                                lint::builtin::ELIDED_NAMED_LIFETIMES,
+                                missing.id_for_lint,
+                                missing.span,
+                                BuiltinLintDiag::ElidedIsStatic { elided: missing.span },
+                            );
+                        }
+                    }
+                    LifetimeRes::Param { param, binder: _ } => {
+                        let tcx = self.r.tcx();
+                        self.r.lint_buffer.buffer_lint(
+                            lint::builtin::ELIDED_NAMED_LIFETIMES,
+                            missing.id_for_lint,
+                            missing.span,
+                            BuiltinLintDiag::ElidedIsParam {
+                                elided: missing.span,
+                                param: (tcx.item_name(param.into()), tcx.source_span(param)),
+                            },
+                        );
+                    }
+                    LifetimeRes::Fresh { .. }
+                    | LifetimeRes::Infer
+                    | LifetimeRes::Error
+                    | LifetimeRes::ElidedAnchor { .. } => {}
+                }
+            }
+            LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {}
+        }
+
         match res {
-            LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => {
+            LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => {
                 if let Some(ref mut candidates) = self.lifetime_elision_candidates {
                     candidates.push((res, candidate));
                 }
@@ -2558,9 +2606,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
             ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
                 self.with_static_rib(def_kind, |this| {
-                    this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
-                        this.visit_ty(ty);
-                    });
+                    this.with_lifetime_rib(
+                        LifetimeRibKind::Elided(LifetimeRes::Static {
+                            suppress_elision_warning: true,
+                        }),
+                        |this| {
+                            this.visit_ty(ty);
+                        },
+                    );
                     if let Some(expr) = expr {
                         // We already forbid generic params because of the above item rib,
                         // so it doesn't matter whether this is a trivial constant.
@@ -2589,7 +2642,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         this.visit_generics(generics);
 
                         this.with_lifetime_rib(
-                            LifetimeRibKind::Elided(LifetimeRes::Static),
+                            LifetimeRibKind::Elided(LifetimeRes::Static {
+                                suppress_elision_warning: true,
+                            }),
                             |this| this.visit_ty(ty),
                         );
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index f778b0ee3ac..8f516c2db09 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -102,6 +102,13 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str
 pub(super) struct MissingLifetime {
     /// Used to overwrite the resolution with the suggestion, to avoid cascading errors.
     pub id: NodeId,
+    /// As we cannot yet emit lints in this crate and have to buffer them instead,
+    /// we need to associate each lint with some `NodeId`,
+    /// however for some `MissingLifetime`s their `NodeId`s are "fake",
+    /// in a sense that they are temporary and not get preserved down the line,
+    /// which means that the lints for those nodes will not get emitted.
+    /// To combat this, we can try to use some other `NodeId`s as a fallback option.
+    pub id_for_lint: NodeId,
     /// Where to suggest adding the lifetime.
     pub span: Span,
     /// How the lifetime was introduced, to have the correct space and comma.
@@ -3028,7 +3035,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                     maybe_static = true;
                     in_scope_lifetimes = vec![(
                         Ident::with_dummy_span(kw::StaticLifetime),
-                        (DUMMY_NODE_ID, LifetimeRes::Static),
+                        (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }),
                     )];
                 }
             } else if elided_len == 0 {
@@ -3040,7 +3047,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                     maybe_static = true;
                     in_scope_lifetimes = vec![(
                         Ident::with_dummy_span(kw::StaticLifetime),
-                        (DUMMY_NODE_ID, LifetimeRes::Static),
+                        (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }),
                     )];
                 }
             } else if num_params == 1 {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 16f5e55835e..34765209605 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1858,7 +1858,6 @@ symbols! {
         stringify,
         struct_field_attributes,
         struct_inherit,
-        struct_target_features,
         struct_variant,
         structural_match,
         structural_peq,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index d5f227a84a4..37665018219 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1837,6 +1837,7 @@ supported_targets! {
 
     ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl),
 
+    ("aarch64-unknown-nto-qnx700", aarch64_unknown_nto_qnx700),
     ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710),
     ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710),
     ("i586-pc-nto-qnx700", i586_pc_nto_qnx700),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs
new file mode 100644
index 00000000000..ac1bec02ec8
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs
@@ -0,0 +1,38 @@
+use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
+
+pub fn target() -> Target {
+    // In QNX, libc does not provide a compatible ABI between versions.
+    // To distinguish between QNX versions, we needed a stable conditional compilation switch,
+    // which is why we needed to implement different targets in the compiler.
+    Target {
+        llvm_target: "aarch64-unknown-unknown".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("ARM64 QNX Neutrino 7.0 RTOS".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(true),
+        },
+        pointer_width: 64,
+        // from: https://llvm.org/docs/LangRef.html#data-layout
+        // e         = little endian
+        // m:e       = ELF mangling: Private symbols get a .L prefix
+        // i8:8:32   = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
+        // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
+        // i64:64    = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
+        // i128:128  = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
+        // n32:64    = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
+        // S128      = 128 bits are the natural alignment of the stack in bits.
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
+        arch: "aarch64".into(),
+        options: TargetOptions {
+            features: "+v8a".into(),
+            max_atomic_width: Some(128),
+            pre_link_args: TargetOptions::link_args(
+                LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+                &["-Vgcc_ntoaarch64le_cxx"],
+            ),
+            env: "nto70".into(),
+            ..base::nto_qnx::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs
index 0e5a0b9b9a5..65a1863eb39 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs
@@ -1,35 +1,8 @@
-use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
+use crate::spec::Target;
 
 pub fn target() -> Target {
-    Target {
-        llvm_target: "aarch64-unknown-unknown".into(),
-        metadata: crate::spec::TargetMetadata {
-            description: Some("ARM64 QNX Neutrino 7.1 RTOS".into()),
-            tier: Some(3),
-            host_tools: Some(false),
-            std: Some(true),
-        },
-        pointer_width: 64,
-        // from: https://llvm.org/docs/LangRef.html#data-layout
-        // e         = little endian
-        // m:e       = ELF mangling: Private symbols get a .L prefix
-        // i8:8:32   = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
-        // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
-        // i64:64    = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
-        // i128:128  = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
-        // n32:64    = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
-        // S128      = 128 bits are the natural alignment of the stack in bits.
-        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: "aarch64".into(),
-        options: TargetOptions {
-            features: "+v8a".into(),
-            max_atomic_width: Some(128),
-            pre_link_args: TargetOptions::link_args(
-                LinkerFlavor::Gnu(Cc::Yes, Lld::No),
-                &["-Vgcc_ntoaarch64le_cxx"],
-            ),
-            env: "nto71".into(),
-            ..base::nto_qnx::opts()
-        },
-    }
+    let mut base = super::aarch64_unknown_nto_qnx700::target();
+    base.metadata.description = Some("ARM64 QNX Neutrino 7.1 RTOS".into());
+    base.options.env = "nto71".into();
+    base
 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 3fdfca50dce..effd9f8cb0c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -439,8 +439,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let is_target_feature_fn = if let ty::FnDef(def_id, _) =
                             *leaf_trait_ref.skip_binder().self_ty().kind()
                         {
-                            // FIXME(struct_target_features): should a function that inherits
-                            // target_features through arguments implement Fn traits?
                             !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                         } else {
                             false
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 7895a420476..96faa5236b1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -546,8 +546,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
             ty::FnDef(def_id, args) => {
                 let tcx = self.tcx();
-                // FIXME(struct_target_features): should a function that inherits target_features
-                // through an argument implement Fn traits?
                 if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
                     && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                 {
diff --git a/library/Cargo.toml b/library/Cargo.toml
index d8ece6b0ebd..e744cfe5e0f 100644
--- a/library/Cargo.toml
+++ b/library/Cargo.toml
@@ -31,8 +31,10 @@ codegen-units = 10000
 # helps to improve link times a little bit.
 [profile.release.package]
 addr2line.debug = 0
+addr2line.opt-level = "s"
 adler.debug = 0
 gimli.debug = 0
+gimli.opt-level = "s"
 miniz_oxide.debug = 0
 object.debug = 0
 rustc-demangle.debug = 0
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index db2d752cfde..cddf4f6f399 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -372,6 +372,7 @@ extern "Rust" {
 #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
 #[cfg(all(not(no_global_oom_handling), not(test)))]
 #[cold]
+#[optimize(size)]
 pub const fn handle_alloc_error(layout: Layout) -> ! {
     const fn ct_error(_: Layout) -> ! {
         panic!("allocation failed");
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index c459a8da820..7aaa4e73df7 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -183,6 +183,7 @@
 #![feature(multiple_supertrait_upcastable)]
 #![feature(negative_impls)]
 #![feature(never_type)]
+#![feature(optimize_attribute)]
 #![feature(rustc_allow_const_fn_unstable)]
 #![feature(rustc_attrs)]
 #![feature(slice_internals)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 9c8fa7ceff4..a651ba067e4 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -782,6 +782,7 @@ where
 // Central function for reserve error handling.
 #[cfg(not(no_global_oom_handling))]
 #[cold]
+#[optimize(size)]
 fn handle_error(e: TryReserveError) -> ! {
     match e.kind() {
         CapacityOverflow => capacity_overflow(),
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index e628be1546f..bc8b7e24bf1 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2313,7 +2313,7 @@ impl<'b> Pattern for &'b String {
     }
 
     #[inline]
-    fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&str>
+    fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
     where
         Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
     {
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index cfd2e4a1512..162791ba59d 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1519,6 +1519,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("swap_remove index (is {index}) should be < len (is {len})");
         }
@@ -1567,6 +1568,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("insertion index (is {index}) should be <= len (is {len})");
         }
@@ -1629,6 +1631,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("removal index (is {index}) should be < len (is {len})");
         }
@@ -2317,6 +2320,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(at: usize, len: usize) -> ! {
             panic!("`at` split index (is {at}) should be <= len (is {len})");
         }
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index e6574ac3c72..fa3c2075423 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -122,7 +122,7 @@ pub const fn from_u32(i: u32) -> Option<char> {
     self::convert::from_u32(i)
 }
 
-/// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`].
+/// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`]
 /// instead.
 #[stable(feature = "char_from_unchecked", since = "1.5.0")]
 #[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")]
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index f29ac99b292..eee4a9e4c6c 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -110,43 +110,43 @@ impl<'a> Argument<'a> {
     }
 
     #[inline(always)]
-    pub fn new_display<'b, T: Display>(x: &'b T) -> Argument<'_> {
+    pub fn new_display<'b, T: Display>(x: &'b T) -> Argument<'b> {
         Self::new(x, Display::fmt)
     }
     #[inline(always)]
-    pub fn new_debug<'b, T: Debug>(x: &'b T) -> Argument<'_> {
+    pub fn new_debug<'b, T: Debug>(x: &'b T) -> Argument<'b> {
         Self::new(x, Debug::fmt)
     }
     #[inline(always)]
-    pub fn new_debug_noop<'b, T: Debug>(x: &'b T) -> Argument<'_> {
+    pub fn new_debug_noop<'b, T: Debug>(x: &'b T) -> Argument<'b> {
         Self::new(x, |_, _| Ok(()))
     }
     #[inline(always)]
-    pub fn new_octal<'b, T: Octal>(x: &'b T) -> Argument<'_> {
+    pub fn new_octal<'b, T: Octal>(x: &'b T) -> Argument<'b> {
         Self::new(x, Octal::fmt)
     }
     #[inline(always)]
-    pub fn new_lower_hex<'b, T: LowerHex>(x: &'b T) -> Argument<'_> {
+    pub fn new_lower_hex<'b, T: LowerHex>(x: &'b T) -> Argument<'b> {
         Self::new(x, LowerHex::fmt)
     }
     #[inline(always)]
-    pub fn new_upper_hex<'b, T: UpperHex>(x: &'b T) -> Argument<'_> {
+    pub fn new_upper_hex<'b, T: UpperHex>(x: &'b T) -> Argument<'b> {
         Self::new(x, UpperHex::fmt)
     }
     #[inline(always)]
-    pub fn new_pointer<'b, T: Pointer>(x: &'b T) -> Argument<'_> {
+    pub fn new_pointer<'b, T: Pointer>(x: &'b T) -> Argument<'b> {
         Self::new(x, Pointer::fmt)
     }
     #[inline(always)]
-    pub fn new_binary<'b, T: Binary>(x: &'b T) -> Argument<'_> {
+    pub fn new_binary<'b, T: Binary>(x: &'b T) -> Argument<'b> {
         Self::new(x, Binary::fmt)
     }
     #[inline(always)]
-    pub fn new_lower_exp<'b, T: LowerExp>(x: &'b T) -> Argument<'_> {
+    pub fn new_lower_exp<'b, T: LowerExp>(x: &'b T) -> Argument<'b> {
         Self::new(x, LowerExp::fmt)
     }
     #[inline(always)]
-    pub fn new_upper_exp<'b, T: UpperExp>(x: &'b T) -> Argument<'_> {
+    pub fn new_upper_exp<'b, T: UpperExp>(x: &'b T) -> Argument<'b> {
         Self::new(x, UpperExp::fmt)
     }
     #[inline(always)]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 06a745b690a..e60bcf3aa5d 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -234,6 +234,7 @@
 #![feature(never_type)]
 #![feature(no_core)]
 #![feature(no_sanitize)]
+#![feature(optimize_attribute)]
 #![feature(prelude_import)]
 #![feature(repr_simd)]
 #![feature(rustc_allow_const_fn_unstable)]
diff --git a/library/core/src/net/parser.rs b/library/core/src/net/parser.rs
index a8ec71f0dd8..73230f6ee5b 100644
--- a/library/core/src/net/parser.rs
+++ b/library/core/src/net/parser.rs
@@ -112,18 +112,18 @@ impl<'a> Parser<'a> {
         max_digits: Option<usize>,
         allow_zero_prefix: bool,
     ) -> Option<T> {
-        // If max_digits.is_some(), then we are parsing a `u8` or `u16` and
-        // don't need to use checked arithmetic since it fits within a `u32`.
-        if let Some(max_digits) = max_digits {
-            // u32::MAX = 4_294_967_295u32, which is 10 digits long.
-            // `max_digits` must be less than 10 to not overflow a `u32`.
-            debug_assert!(max_digits < 10);
-
-            self.read_atomically(move |p| {
-                let mut result = 0_u32;
-                let mut digit_count = 0;
-                let has_leading_zero = p.peek_char() == Some('0');
+        self.read_atomically(move |p| {
+            let mut digit_count = 0;
+            let has_leading_zero = p.peek_char() == Some('0');
+
+            // If max_digits.is_some(), then we are parsing a `u8` or `u16` and
+            // don't need to use checked arithmetic since it fits within a `u32`.
+            let result = if let Some(max_digits) = max_digits {
+                // u32::MAX = 4_294_967_295u32, which is 10 digits long.
+                // `max_digits` must be less than 10 to not overflow a `u32`.
+                debug_assert!(max_digits < 10);
 
+                let mut result = 0_u32;
                 while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
                     result *= radix;
                     result += digit;
@@ -134,19 +134,9 @@ impl<'a> Parser<'a> {
                     }
                 }
 
-                if digit_count == 0 {
-                    None
-                } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
-                    None
-                } else {
-                    result.try_into().ok()
-                }
-            })
-        } else {
-            self.read_atomically(move |p| {
+                result.try_into().ok()
+            } else {
                 let mut result = T::ZERO;
-                let mut digit_count = 0;
-                let has_leading_zero = p.peek_char() == Some('0');
 
                 while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
                     result = result.checked_mul(radix)?;
@@ -154,15 +144,17 @@ impl<'a> Parser<'a> {
                     digit_count += 1;
                 }
 
-                if digit_count == 0 {
-                    None
-                } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
-                    None
-                } else {
-                    Some(result)
-                }
-            })
-        }
+                Some(result)
+            };
+
+            if digit_count == 0 {
+                None
+            } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
+                None
+            } else {
+                result
+            }
+        })
     }
 
     /// Reads an IPv4 address.
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 7affe638257..e4a62304087 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -264,7 +264,7 @@ pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
     panic_fmt(format_args!("{}", *x));
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
@@ -276,7 +276,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
     panic!("index out of bounds: the len is {len} but the index is {index}")
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref
@@ -301,7 +301,7 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
 ///
 /// This function is called directly by the codegen backend, and must not have
 /// any extra arguments (including those synthesized by track_caller).
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
@@ -317,7 +317,7 @@ fn panic_cannot_unwind() -> ! {
 ///
 /// This function is called directly by the codegen backend, and must not have
 /// any extra arguments (including those synthesized by track_caller).
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
@@ -350,7 +350,7 @@ pub enum AssertKind {
 }
 
 /// Internal function for `assert_eq!` and `assert_ne!` macros
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[doc(hidden)]
@@ -368,7 +368,7 @@ where
 }
 
 /// Internal function for `assert_match!`
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[doc(hidden)]
@@ -388,7 +388,7 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
 }
 
 /// Non-generic version of the above functions, to avoid code bloat.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 fn assert_failed_inner(
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs
index d19d0eae166..1769612def0 100644
--- a/library/core/src/slice/cmp.rs
+++ b/library/core/src/slice/cmp.rs
@@ -3,7 +3,8 @@
 use super::{from_raw_parts, memchr};
 use crate::cmp::{self, BytewiseEq, Ordering};
 use crate::intrinsics::compare_bytes;
-use crate::mem;
+use crate::num::NonZero;
+use crate::{ascii, mem};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, U> PartialEq<[U]> for [T]
@@ -182,19 +183,41 @@ impl<A: Ord> SliceOrd for A {
     }
 }
 
-// `compare_bytes` compares a sequence of unsigned bytes lexicographically.
-// this matches the order we want for [u8], but no others (not even [i8]).
-impl SliceOrd for u8 {
+/// Marks that a type should be treated as an unsigned byte for comparisons.
+///
+/// # Safety
+/// * The type must be readable as an `u8`, meaning it has to have the same
+///   layout as `u8` and always be initialized.
+/// * For every `x` and `y` of this type, `Ord(x, y)` must return the same
+///   value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`.
+#[rustc_specialization_trait]
+unsafe trait UnsignedBytewiseOrd {}
+
+unsafe impl UnsignedBytewiseOrd for bool {}
+unsafe impl UnsignedBytewiseOrd for u8 {}
+unsafe impl UnsignedBytewiseOrd for NonZero<u8> {}
+unsafe impl UnsignedBytewiseOrd for Option<NonZero<u8>> {}
+unsafe impl UnsignedBytewiseOrd for ascii::Char {}
+
+// `compare_bytes` compares a sequence of unsigned bytes lexicographically, so
+// use it if the requirements for `UnsignedBytewiseOrd` are fulfilled.
+impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
     #[inline]
     fn compare(left: &[Self], right: &[Self]) -> Ordering {
-        // Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
+        // Since the length of a slice is always less than or equal to
+        // isize::MAX, this never underflows.
         let diff = left.len() as isize - right.len() as isize;
-        // This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
+        // This comparison gets optimized away (on x86_64 and ARM) because the
+        // subtraction updates flags.
         let len = if left.len() < right.len() { left.len() } else { right.len() };
-        // SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
-        // We use the minimum of both lengths which guarantees that both regions are
-        // valid for reads in that interval.
-        let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
+        let left = left.as_ptr().cast();
+        let right = right.as_ptr().cast();
+        // SAFETY: `left` and `right` are references and are thus guaranteed to
+        // be valid. `UnsignedBytewiseOrd` is only implemented for types that
+        // are valid u8s and can be compared the same way. We use the minimum
+        // of both lengths which guarantees that both regions are valid for
+        // reads in that interval.
+        let mut order = unsafe { compare_bytes(left, right, len) as isize };
         if order == 0 {
             order = diff;
         }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 5f0144922ca..82cfd603a21 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -35,7 +35,7 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
 addr2line = { version = "0.22.0", optional = true, default-features = false }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
-libc = { version = "0.2.153", default-features = false, features = [
+libc = { version = "0.2.156", default-features = false, features = [
     'rustc-dep-of-std',
 ], public = true }
 
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index bea8eda2619..606d75668c4 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -306,10 +306,12 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(no_sanitize)]
+#![feature(optimize_attribute)]
 #![feature(prelude_import)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(staged_api)]
+#![feature(stmt_expr_attributes)]
 #![feature(thread_local)]
 #![feature(try_blocks)]
 #![feature(type_alias_impl_trait)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 190eed94555..1c972d38100 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -231,6 +231,7 @@ where
 }
 
 /// The default panic handler.
+#[optimize(size)]
 fn default_hook(info: &PanicHookInfo<'_>) {
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
@@ -249,7 +250,8 @@ fn default_hook(info: &PanicHookInfo<'_>) {
     let thread = thread::try_current();
     let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
 
-    let write = |err: &mut dyn crate::io::Write| {
+    let write = #[optimize(size)]
+    |err: &mut dyn crate::io::Write| {
         // Use a lock to prevent mixed output in multithreading context.
         // Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows.
         let mut lock = backtrace::lock();
@@ -527,6 +529,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // optimizer (in most cases this function is not inlined even as a normal,
     // non-cold function, though, as of the writing of this comment).
     #[cold]
+    #[optimize(size)]
     unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
         // SAFETY: The whole unsafe block hinges on a correct implementation of
         // the panic handler `__rust_panic_cleanup`. As such we can only
@@ -686,7 +689,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
 // lang item for CTFE panic support
 // never inline unless panic_immediate_abort to avoid code
 // bloat at the call sites as much as possible
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[rustc_do_not_const_check] // hooked by const-eval
@@ -756,6 +759,7 @@ fn payload_as_str(payload: &dyn Any) -> &str {
 /// Executes the primary logic for a panic, including checking for recursive
 /// panics, panic hooks, and finally dispatching to the panic runtime to either
 /// abort or unwind.
+#[optimize(size)]
 fn rust_panic_with_hook(
     payload: &mut dyn PanicPayload,
     location: &Location<'_>,
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 56cf877ddc6..a51e5c1b76b 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -498,6 +498,7 @@ impl<T> OnceLock<T> {
     }
 
     #[cold]
+    #[optimize(size)]
     fn initialize<F, E>(&self, f: F) -> Result<(), E>
     where
         F: FnOnce() -> Result<T, E>,
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index fc9d7e98883..7fa147c9754 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1717,7 +1717,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
     run_path_with_cstr(original, &|original| {
         run_path_with_cstr(link, &|link| {
             cfg_if::cfg_if! {
-                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita"))] {
+                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nto"))] {
                     // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
                     // it implementation-defined whether `link` follows symlinks, so rely on the
                     // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 5552e9ac977..9d091f033e0 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -19,7 +19,8 @@ use crate::sys::process::process_common::*;
 use crate::{fmt, mem, sys};
 
 cfg_if::cfg_if! {
-    if #[cfg(all(target_os = "nto", target_env = "nto71"))] {
+    // This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0
+    if #[cfg(any(target_env = "nto70", target_env = "nto71"))] {
         use crate::thread;
         use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t};
         use crate::time::Duration;
@@ -189,7 +190,8 @@ impl Command {
     #[cfg(not(any(
         target_os = "watchos",
         target_os = "tvos",
-        all(target_os = "nto", target_env = "nto71"),
+        target_env = "nto70",
+        target_env = "nto71"
     )))]
     unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
         cvt(libc::fork())
@@ -199,7 +201,8 @@ impl Command {
     // or closed a file descriptor while the fork() was occurring".
     // Documentation says "... or try calling fork() again". This is what we do here.
     // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
-    #[cfg(all(target_os = "nto", target_env = "nto71"))]
+    // This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0
+    #[cfg(any(target_env = "nto70", target_env = "nto71"))]
     unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
         use crate::sys::os::errno;
 
@@ -537,7 +540,7 @@ impl Command {
         // or closed a file descriptor while the posix_spawn() was occurring".
         // Documentation says "... or try calling posix_spawn() again". This is what we do here.
         // See also http://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/p/posix_spawn.html
-        #[cfg(all(target_os = "nto", target_env = "nto71"))]
+        #[cfg(target_os = "nto")]
         unsafe fn retrying_libc_posix_spawnp(
             pid: *mut pid_t,
             file: *const c_char,
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index b3de71f29f3..250af912e07 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -165,8 +165,15 @@ extern "C" {}
 extern "C" {}
 
 #[cfg(target_os = "nto")]
-#[link(name = "gcc_s")]
-extern "C" {}
+cfg_if::cfg_if! {
+    if #[cfg(target_env = "nto70")] {
+        #[link(name = "gcc")]
+        extern "C" {}
+    } else {
+        #[link(name = "gcc_s")]
+        extern "C" {}
+    }
+}
 
 #[cfg(target_os = "hurd")]
 #[link(name = "gcc_s")]
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 0d79e5f4114..a2641b22753 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -256,6 +256,7 @@ target | std | host | notes
 [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ |  | ARM64 SOLID with TOPPERS/ASP3
 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * |  | ARM64 Nintendo Switch, Horizon
 [`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? |  | ARM64 TEEOS |
+[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? |  | ARM64 QNX Neutrino 7.0 RTOS |
 [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ |  | ARM64 QNX Neutrino 7.1 RTOS |
 `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
 [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ |  | ARM64 Hermit
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
index 51a397a38d2..1c240d1255a 100644
--- a/src/doc/rustc/src/platform-support/nto-qnx.md
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -24,6 +24,7 @@ Currently, the following QNX Neutrino versions and compilation targets are suppo
 |----------------------|---------------------|:------------:|:----------------:|
 | 7.1 | AArch64 | ✓ | ✓ |
 | 7.1 | x86_64  | ✓ | ✓ |
+| 7.0 | AArch64 | ? | ✓ |
 | 7.0 | x86     |   | ✓ |
 
 Adding other architectures that are supported by QNX Neutrino is possible.
@@ -43,6 +44,23 @@ When linking `no_std` applications, they must link against `libc.so` (see exampl
 required because applications always link against the `crt` library and `crt` depends on `libc.so`.
 This is done automatically when using the standard library.
 
+### Disabling RELocation Read-Only (RELRO)
+
+While not recommended by default, some QNX kernel setups may require the `RELRO` to be disabled with `-C relro_level=off`, e.g. by adding it to the `.cargo/config.toml` file:
+
+```toml
+[target.aarch64-unknown-nto-qnx700]
+rustflags = ["-C", "relro_level=off"]
+```
+
+If your QNX kernel does not allow it, and `relro` is not disabled, running compiled binary would fail with `syntax error: ... unexpected` or similar.  This is due to kernel trying to interpret compiled binary with `/bin/sh`, and obviously failing.  To verify that this is really the case, run your binary with the `DL_DEBUG=all` env var, and look for this output. If you see it, you should disable `relro` as described above.
+
+```text
+Resolution scope for Executable->/bin/sh:
+        Executable->/bin/sh
+        libc.so.4->/usr/lib/ldqnx-64.so.2
+```
+
 ### Small example application
 
 Small `no_std` example is shown below. Applications using the standard library work as well.
diff --git a/src/doc/unstable-book/src/language-features/struct-target-features.md b/src/doc/unstable-book/src/language-features/struct-target-features.md
deleted file mode 100644
index e814fe90072..00000000000
--- a/src/doc/unstable-book/src/language-features/struct-target-features.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# `struct_target_features`
-
-The tracking issue for this feature is: [#129107]
-
-[#129107]: https://github.com/rust-lang/rust/issues/129107
-
-------------------------
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index f325d27b8c7..50f845e2d92 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -1,3 +1,14 @@
+error: elided lifetime has a name
+  --> tests/ui/needless_lifetimes.rs:266:52
+   |
+LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
+   |                              --                    ^ this elided lifetime gets resolved as `'a`
+   |                              |
+   |                              lifetime `'a` declared here
+   |
+   = note: `-D elided-named-lifetimes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]`
+
 error: the following explicit lifetimes could be elided: 'a, 'b
   --> tests/ui/needless_lifetimes.rs:17:23
    |
@@ -553,5 +564,5 @@ LL -         fn one_input<'a>(x: &'a u8) -> &'a u8 {
 LL +         fn one_input(x: &u8) -> &u8 {
    |
 
-error: aborting due to 46 previous errors
+error: aborting due to 47 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index 1848ef80fc4..4246453e64c 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -1,3 +1,12 @@
+error: elided lifetime has a name
+  --> tests/ui/ptr_arg.rs:295:56
+   |
+LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
+   |                        -- lifetime `'a` declared here  ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `-D elided-named-lifetimes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]`
+
 error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
   --> tests/ui/ptr_arg.rs:13:14
    |
@@ -212,5 +221,5 @@ error: using a reference to `Cow` is not recommended
 LL |     fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {
    |                                        ^^^^^^^^^^^^^^^^ help: change this to: `&str`
 
-error: aborting due to 24 previous errors
+error: aborting due to 25 previous errors
 
diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr
index 960cae90124..dfe3ed4b522 100644
--- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr
+++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: reading memory at ALLOC[0x0..0x10], but memory is uninitialized at [0x4..0x10], and this operation requires initialized memory
   --> RUSTLIB/core/src/slice/cmp.rs:LL:CC
    |
-LL |         let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x10], but memory is uninitialized at [0x4..0x10], and this operation requires initialized memory
+LL |         let mut order = unsafe { compare_bytes(left, right, len) as isize };
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x10], but memory is uninitialized at [0x4..0x10], and this operation requires initialized memory
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr
index 5439418f267..48ce9ae7656 100644
--- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr
+++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory
   --> RUSTLIB/core/src/slice/cmp.rs:LL:CC
    |
-LL |         let mut order = unsafe { compare_bytes(left.as_ptr(), right.as_ptr(), len) as isize };
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory
+LL |         let mut order = unsafe { compare_bytes(left, right, len) as isize };
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
index 198dc93f6b1..c0547bc3c8d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
@@ -117,7 +117,7 @@ impl Attrs {
 }
 
 impl Attrs {
-    pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'_> {
+    pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'attrs> {
         AttrQuery { attrs: self, key }
     }
 
@@ -594,7 +594,7 @@ impl<'attr> AttrQuery<'attr> {
     /// #[doc(html_root_url = "url")]
     ///       ^^^^^^^^^^^^^ key
     /// ```
-    pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> Option<&str> {
+    pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> Option<&'attr str> {
         self.tt_values().find_map(|tt| {
             let name = tt.token_trees.iter()
                 .skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if *sym == *key))
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
index f5fe8f87701..dde1f142ab0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
@@ -197,7 +197,7 @@ impl Body {
     pub fn blocks<'a>(
         &'a self,
         db: &'a dyn DefDatabase,
-    ) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + '_ {
+    ) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + 'a {
         self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block)))
     }
 
diff --git a/tests/assembly/struct-target-features.rs b/tests/assembly/struct-target-features.rs
deleted file mode 100644
index cc86fbaa840..00000000000
--- a/tests/assembly/struct-target-features.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-//@ compile-flags: -O
-//@ assembly-output: emit-asm
-//@ only-x86_64
-
-#![crate_type = "lib"]
-#![feature(struct_target_features)]
-
-// Check that a struct_target_features type causes the compiler to effectively inline intrinsics.
-
-use std::arch::x86_64::*;
-
-#[target_feature(enable = "avx")]
-struct Avx {}
-
-#[target_feature(enable = "fma")]
-struct Fma {}
-
-pub fn add_simple(_: Avx, v: __m256) -> __m256 {
-    // CHECK-NOT: call
-    // CHECK: vaddps
-    unsafe { _mm256_add_ps(v, v) }
-}
-
-pub fn add_complex_type(_: (&Avx, ()), v: __m256) -> __m256 {
-    // CHECK-NOT: call
-    // CHECK: vaddps
-    unsafe { _mm256_add_ps(v, v) }
-}
-
-pub fn add_fma_combined(_: (&Avx, &Fma), v: __m256) -> (__m256, __m256) {
-    // CHECK-NOT: call
-    // CHECK-DAG: vaddps
-    let r1 = unsafe { _mm256_add_ps(v, v) };
-    // CHECK-DAG: vfmadd213ps
-    let r2 = unsafe { _mm256_fmadd_ps(v, v, v) };
-    (r1, r2)
-}
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index 6f0a200a08c..b0c5eec1fe4 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -54,6 +54,9 @@
 //@ revisions: aarch64_unknown_none_softfloat
 //@ [aarch64_unknown_none_softfloat] compile-flags: --target aarch64-unknown-none-softfloat
 //@ [aarch64_unknown_none_softfloat] needs-llvm-components: aarch64
+//@ revisions: aarch64_unknown_nto_qnx700
+//@ [aarch64_unknown_nto_qnx700] compile-flags: --target aarch64-unknown-nto-qnx700
+//@ [aarch64_unknown_nto_qnx700] needs-llvm-components: aarch64
 //@ revisions: aarch64_unknown_nto_qnx710
 //@ [aarch64_unknown_nto_qnx710] compile-flags: --target aarch64-unknown-nto-qnx710
 //@ [aarch64_unknown_nto_qnx710] needs-llvm-components: aarch64
diff --git a/tests/crashes/117460.rs b/tests/crashes/117460.rs
new file mode 100644
index 00000000000..4878a35ffe5
--- /dev/null
+++ b/tests/crashes/117460.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #117460
+#![feature(generic_const_exprs)]
+
+struct Matrix<D = [(); 2 + 2]> {
+    d: D,
+}
+
+impl Matrix {}
diff --git a/tests/crashes/119095.rs b/tests/crashes/119095.rs
new file mode 100644
index 00000000000..28742e0d5da
--- /dev/null
+++ b/tests/crashes/119095.rs
@@ -0,0 +1,48 @@
+//@ known-bug: #119095
+//@ compile-flags: --edition=2021
+
+fn any<T>() -> T {
+    loop {}
+}
+
+trait Acquire {
+    type Connection;
+}
+
+impl Acquire for &'static () {
+    type Connection = ();
+}
+
+trait Unit {}
+impl Unit for () {}
+
+fn get_connection<T>() -> impl Unit
+where
+    T: Acquire,
+    T::Connection: Unit,
+{
+    any::<T::Connection>()
+}
+
+fn main() {
+    let future = async { async { get_connection::<&'static ()>() }.await };
+
+    future.resolve_me();
+}
+
+trait ResolveMe {
+    fn resolve_me(self);
+}
+
+impl<S> ResolveMe for S
+where
+    (): CheckSend<S>,
+{
+    fn resolve_me(self) {}
+}
+
+trait CheckSend<F> {}
+impl<F> CheckSend<F> for () where F: Send {}
+
+trait NeverImplemented {}
+impl<E, F> CheckSend<F> for E where E: NeverImplemented {}
diff --git a/tests/crashes/126443.rs b/tests/crashes/126443.rs
new file mode 100644
index 00000000000..fba779444f9
--- /dev/null
+++ b/tests/crashes/126443.rs
@@ -0,0 +1,15 @@
+//@ known-bug: #126443
+//@ compile-flags: -Copt-level=0
+#![feature(generic_const_exprs)]
+
+fn double_up<const M: usize>() -> [(); M * 2] {
+    todo!()
+}
+
+fn quadruple_up<const N: usize>() -> [(); N * 2 * 2] {
+    double_up()
+}
+
+fn main() {
+    quadruple_up::<0>();
+}
diff --git a/tests/crashes/128097.rs b/tests/crashes/128097.rs
new file mode 100644
index 00000000000..6ffca640cbd
--- /dev/null
+++ b/tests/crashes/128097.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #128097
+#![feature(explicit_tail_calls)]
+fn f(x: &mut ()) {
+    let _y: String;
+    become f(x);
+}
diff --git a/tests/debuginfo/option-like-enum.rs b/tests/debuginfo/option-like-enum.rs
index d370796efa9..72a41986dce 100644
--- a/tests/debuginfo/option-like-enum.rs
+++ b/tests/debuginfo/option-like-enum.rs
@@ -8,22 +8,22 @@
 // gdb-command:run
 
 // gdb-command:print some
-// gdb-check:$1 = core::option::Option<&u32>::Some(0x12345678)
+// gdb-check:$1 = core::option::Option<&u32>::Some(0x[...])
 
 // gdb-command:print none
 // gdb-check:$2 = core::option::Option<&u32>::None
 
 // gdb-command:print full
-// gdb-check:$3 = option_like_enum::MoreFields::Full(454545, 0x87654321, 9988)
+// gdb-check:$3 = option_like_enum::MoreFields::Full(454545, 0x[...], 9988)
 
-// gdb-command:print empty_gdb.discr
-// gdb-check:$4 = (*mut isize) 0x1
+// gdb-command:print empty
+// gdb-check:$4 = option_like_enum::MoreFields::Empty
 
 // gdb-command:print droid
-// gdb-check:$5 = option_like_enum::NamedFields::Droid{id: 675675, range: 10000001, internals: 0x43218765}
+// gdb-check:$5 = option_like_enum::NamedFields::Droid{id: 675675, range: 10000001, internals: 0x[...]}
 
-// gdb-command:print void_droid_gdb.internals
-// gdb-check:$6 = (*mut isize) 0x1
+// gdb-command:print void_droid
+// gdb-check:$6 = option_like_enum::NamedFields::Void
 
 // gdb-command:print nested_non_zero_yep
 // gdb-check:$7 = option_like_enum::NestedNonZero::Yep(10.5, option_like_enum::NestedNonZeroField {a: 10, b: 20, c: 0x[...]})
@@ -39,19 +39,19 @@
 // lldb-command:run
 
 // lldb-command:v some
-// lldb-check:[...] Some(&0x12345678)
+// lldb-check:[...] Some(&0x[...])
 
 // lldb-command:v none
 // lldb-check:[...] None
 
 // lldb-command:v full
-// lldb-check:[...] Full(454545, &0x87654321, 9988)
+// lldb-check:[...] Full(454545, &0x[...], 9988)
 
 // lldb-command:v empty
 // lldb-check:[...] Empty
 
 // lldb-command:v droid
-// lldb-check:[...] Droid { id: 675675, range: 10000001, internals: &0x43218765 }
+// lldb-check:[...] Droid { id: 675675, range: 10000001, internals: &0x[...] }
 
 // lldb-command:v void_droid
 // lldb-check:[...] Void
@@ -76,11 +76,6 @@
 // contains a non-nullable pointer, then this value is used as the discriminator.
 // The test cases in this file make sure that something readable is generated for
 // this kind of types.
-// If the non-empty variant contains a single non-nullable pointer than the whole
-// item is represented as just a pointer and not wrapped in a struct.
-// Unfortunately (for these test cases) the content of the non-discriminant fields
-// in the null-case is not defined. So we just read the discriminator field in
-// this case (by casting the value to a memory-equivalent struct).
 
 enum MoreFields<'a> {
     Full(u32, &'a isize, i16),
@@ -120,32 +115,26 @@ fn main() {
     let some_str: Option<&'static str> = Some("abc");
     let none_str: Option<&'static str> = None;
 
-    let some: Option<&u32> = Some(unsafe { std::mem::transmute(0x12345678_usize) });
+    let some: Option<&u32> = Some(&1234);
     let none: Option<&u32> = None;
 
-    let full = MoreFields::Full(454545, unsafe { std::mem::transmute(0x87654321_usize) }, 9988);
-
+    let full = MoreFields::Full(454545, &1234, 9988);
     let empty = MoreFields::Empty;
-    let empty_gdb: &MoreFieldsRepr = unsafe { std::mem::transmute(&MoreFields::Empty) };
 
     let droid = NamedFields::Droid {
         id: 675675,
         range: 10000001,
-        internals: unsafe { std::mem::transmute(0x43218765_usize) }
+        internals: &1234,
     };
-
     let void_droid = NamedFields::Void;
-    let void_droid_gdb: &NamedFieldsRepr = unsafe { std::mem::transmute(&NamedFields::Void) };
 
-    let x = 'x';
     let nested_non_zero_yep = NestedNonZero::Yep(
         10.5,
         NestedNonZeroField {
             a: 10,
             b: 20,
-            c: &x
+            c: &'x',
         });
-
     let nested_non_zero_nope = NestedNonZero::Nope;
 
     zzz(); // #break
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
index c1c2fdcfa94..109a41d1ef9 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
@@ -3,14 +3,14 @@
     field_tys: {
         _0: CoroutineSavedTy {
             ty: Coroutine(
-                DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
+                DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
                 [
                     (),
                     std::future::ResumeTy,
                     (),
                     (),
                     CoroutineWitness(
-                        DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
+                        DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
                         [],
                     ),
                     (),
@@ -24,14 +24,14 @@
         },
         _1: CoroutineSavedTy {
             ty: Coroutine(
-                DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
+                DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
                 [
                     (),
                     std::future::ResumeTy,
                     (),
                     (),
                     CoroutineWitness(
-                        DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
+                        DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
                         [],
                     ),
                     (),
diff --git a/tests/ui/async-await/issues/issue-63388-1.rs b/tests/ui/async-await/issues/issue-63388-1.rs
index 32026a22a16..a6f499ba94e 100644
--- a/tests/ui/async-await/issues/issue-63388-1.rs
+++ b/tests/ui/async-await/issues/issue-63388-1.rs
@@ -9,7 +9,7 @@ trait Foo {}
 impl Xyz {
     async fn do_sth<'a>(
         &'a self, foo: &dyn Foo
-    ) -> &dyn Foo
+    ) -> &dyn Foo  //~ WARNING elided lifetime has a name
     {
         //~^ ERROR explicit lifetime required in the type of `foo` [E0621]
         foo
diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr
index f7f285ad0cc..ef74bfe3237 100644
--- a/tests/ui/async-await/issues/issue-63388-1.stderr
+++ b/tests/ui/async-await/issues/issue-63388-1.stderr
@@ -1,3 +1,14 @@
+warning: elided lifetime has a name
+  --> $DIR/issue-63388-1.rs:12:10
+   |
+LL |     async fn do_sth<'a>(
+   |                     -- lifetime `'a` declared here
+LL |         &'a self, foo: &dyn Foo
+LL |     ) -> &dyn Foo
+   |          ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0621]: explicit lifetime required in the type of `foo`
   --> $DIR/issue-63388-1.rs:13:5
    |
@@ -10,6 +21,6 @@ LL | |         foo
 LL | |     }
    | |_____^ lifetime `'a` required
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
new file mode 100644
index 00000000000..177ff20fbf9
--- /dev/null
+++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
@@ -0,0 +1,10 @@
+warning: elided lifetime has a name
+  --> $DIR/issue-71348.rs:18:68
+   |
+LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
+   |            -- lifetime `'a` declared here                          ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
index 858900a500d..5aee282952a 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
@@ -1,3 +1,11 @@
+warning: elided lifetime has a name
+  --> $DIR/issue-71348.rs:18:68
+   |
+LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
+   |            -- lifetime `'a` declared here                          ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error: `&'static str` is forbidden as the type of a const generic parameter
   --> $DIR/issue-71348.rs:10:24
    |
@@ -30,5 +38,5 @@ help: add `#![feature(unsized_const_params)]` to the crate attributes to enable
 LL + #![feature(unsized_const_params)]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.rs b/tests/ui/const-generics/type-dependent/issue-71348.rs
index 2ffbd015485..97e786405fe 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.rs
+++ b/tests/ui/const-generics/type-dependent/issue-71348.rs
@@ -17,6 +17,7 @@ trait Get<'a, const N: &'static str> {
 impl Foo {
     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
     //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter
+    //~^^ WARNING elided lifetime has a name
     where
         Self: Get<'a, N>,
     {
diff --git a/tests/ui/consts/min_const_fn/min_const_fn.rs b/tests/ui/consts/min_const_fn/min_const_fn.rs
index 76245c08ffc..f7663f6044e 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn.rs
+++ b/tests/ui/consts/min_const_fn/min_const_fn.rs
@@ -44,8 +44,8 @@ impl<T> Foo<T> {
 impl<'a, T> Foo<T> {
     const fn new_lt(t: T) -> Self { Foo(t) }
     const fn into_inner_lt(self) -> T { self.0 } //~ destructor of
-    const fn get_lt(&'a self) -> &T { &self.0 }
-    const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
+    const fn get_lt(&'a self) -> &T { &self.0 } //~ WARNING elided lifetime has a name
+    const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } //~ WARNING elided lifetime has a name
     //~^ mutable references
     //~| mutable references
     //~| mutable references
diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr
index daa0ab2614f..4b348a182b8 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr
@@ -1,3 +1,23 @@
+warning: elided lifetime has a name
+  --> $DIR/min_const_fn.rs:47:34
+   |
+LL | impl<'a, T> Foo<T> {
+   |      -- lifetime `'a` declared here
+...
+LL |     const fn get_lt(&'a self) -> &T { &self.0 }
+   |                                  ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+warning: elided lifetime has a name
+  --> $DIR/min_const_fn.rs:48:42
+   |
+LL | impl<'a, T> Foo<T> {
+   |      -- lifetime `'a` declared here
+...
+LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
+   |                                          ^ this elided lifetime gets resolved as `'a`
+
 error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
   --> $DIR/min_const_fn.rs:37:25
    |
@@ -228,7 +248,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    |                  |
    |                  the destructor for this type cannot be evaluated in constant functions
 
-error: aborting due to 24 previous errors
+error: aborting due to 24 previous errors; 2 warnings emitted
 
 Some errors have detailed explanations: E0493, E0658.
 For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
index 934ab08cf17..daf88fc1f23 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
@@ -10,7 +10,7 @@ note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/coroutine-print-verbose-1.rs:35:9
    |
 LL |         let _non_send_gen = make_non_send_coroutine();
-   |             ------------- has type `Opaque(DefId(0:34 ~ coroutine_print_verbose_1[75fb]::make_non_send_coroutine::{opaque#0}), [])` which is not `Send`
+   |             ------------- has type `Opaque(DefId(0:24 ~ coroutine_print_verbose_1[75fb]::make_non_send_coroutine::{opaque#0}), [])` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
 note: required by a bound in `require_send`
@@ -33,12 +33,12 @@ note: required because it's used within this coroutine
    |
 LL |     #[coroutine] || {
    |                  ^^
-note: required because it appears within the type `Opaque(DefId(0:35 ~ coroutine_print_verbose_1[75fb]::make_gen2::{opaque#0}), [Arc<RefCell<i32>>])`
+note: required because it appears within the type `Opaque(DefId(0:29 ~ coroutine_print_verbose_1[75fb]::make_gen2::{opaque#0}), [Arc<RefCell<i32>>])`
   --> $DIR/coroutine-print-verbose-1.rs:41:30
    |
 LL | pub fn make_gen2<T>(t: T) -> impl Coroutine<Return = T> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `Opaque(DefId(0:36 ~ coroutine_print_verbose_1[75fb]::make_non_send_coroutine2::{opaque#0}), [])`
+note: required because it appears within the type `Opaque(DefId(0:32 ~ coroutine_print_verbose_1[75fb]::make_non_send_coroutine2::{opaque#0}), [])`
   --> $DIR/coroutine-print-verbose-1.rs:47:34
    |
 LL | fn make_non_send_coroutine2() -> impl Coroutine<Return = Arc<RefCell<i32>>> {
diff --git a/tests/ui/error-codes/E0602.stderr b/tests/ui/error-codes/E0602.stderr
index b0b6033aadd..b6b5cd5c3d3 100644
--- a/tests/ui/error-codes/E0602.stderr
+++ b/tests/ui/error-codes/E0602.stderr
@@ -13,11 +13,6 @@ warning[E0602]: unknown lint: `bogus`
    = note: requested on the command line with `-D bogus`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-warning[E0602]: unknown lint: `bogus`
-   |
-   = note: requested on the command line with `-D bogus`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: 4 warnings emitted
+warning: 3 warnings emitted
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/feature-gates/feature-gate-struct-target-features.rs b/tests/ui/feature-gates/feature-gate-struct-target-features.rs
deleted file mode 100644
index 85494881146..00000000000
--- a/tests/ui/feature-gates/feature-gate-struct-target-features.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[target_feature(enable = "avx")] //~ ERROR attribute should be applied to a function definition
-struct Avx {}
-
-fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-struct-target-features.stderr b/tests/ui/feature-gates/feature-gate-struct-target-features.stderr
deleted file mode 100644
index 1e18d3ee1e1..00000000000
--- a/tests/ui/feature-gates/feature-gate-struct-target-features.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: attribute should be applied to a function definition
-  --> $DIR/feature-gate-struct-target-features.rs:1:1
-   |
-LL | #[target_feature(enable = "avx")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | struct Avx {}
-   | ------------- not a function definition
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/generics/generic-no-mangle.fixed b/tests/ui/generics/generic-no-mangle.fixed
index 69db712f9dc..2776848c45f 100644
--- a/tests/ui/generics/generic-no-mangle.fixed
+++ b/tests/ui/generics/generic-no-mangle.fixed
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![allow(dead_code)]
+#![allow(dead_code, elided_named_lifetimes)]
 #![deny(no_mangle_generic_items)]
 
 pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
diff --git a/tests/ui/generics/generic-no-mangle.rs b/tests/ui/generics/generic-no-mangle.rs
index 2288b5bbe70..5314005d31f 100644
--- a/tests/ui/generics/generic-no-mangle.rs
+++ b/tests/ui/generics/generic-no-mangle.rs
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![allow(dead_code)]
+#![allow(dead_code, elided_named_lifetimes)]
 #![deny(no_mangle_generic_items)]
 
 #[no_mangle]
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
index da7530b4e7a..a7f38b5c16a 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
@@ -13,6 +13,7 @@ fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
 
 fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
     //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
+    //~| WARNING elided lifetime has a name
     |x| x
 }
 
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
index 7d108b30b76..d0f8f7689d1 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
@@ -1,5 +1,5 @@
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-fn-hrtb-bounds.rs:19:38
+  --> $DIR/impl-fn-hrtb-bounds.rs:20:38
    |
 LL | fn d() -> impl Fn() -> (impl Debug + '_) {
    |                                      ^^ expected named lifetime parameter
@@ -10,6 +10,14 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
 LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
    |                                      ~~~~~~~
 
+warning: elided lifetime has a name
+  --> $DIR/impl-fn-hrtb-bounds.rs:14:52
+   |
+LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+   |                    -- lifetime `'a` declared here  ^^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-hrtb-bounds.rs:4:41
    |
@@ -46,7 +54,7 @@ note: lifetime declared here
 LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
    |                    ^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 4 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0106, E0657.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
index 8aba3de530b..2f17c0ff508 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
@@ -3,6 +3,7 @@ use std::fmt::Debug;
 
 fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
     //~^ ERROR cannot resolve opaque type
+    //~| WARNING elided lifetime has a name
     |x| x
     //~^ ERROR expected generic lifetime parameter, found `'_`
 }
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
index c2386e8c88b..50a9f3ebeab 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -1,9 +1,17 @@
+warning: elided lifetime has a name
+  --> $DIR/impl-fn-predefined-lifetimes.rs:4:48
+   |
+LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
+   |      -- lifetime `'a` declared here            ^^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/impl-fn-predefined-lifetimes.rs:6:9
+  --> $DIR/impl-fn-predefined-lifetimes.rs:7:9
    |
 LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
    |                                                -- this generic parameter must be used with a generic lifetime parameter
-LL |
+...
 LL |     |x| x
    |         ^
 
@@ -13,7 +21,7 @@ error[E0720]: cannot resolve opaque type
 LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
    |                                   ^^^^^^^^^^^^^^^ cannot resolve opaque type
 
-error: aborting due to 2 previous errors
+error: aborting due to 2 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0720, E0792.
 For more information about an error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs
index 73c8a6c0aed..e48441f533d 100644
--- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs
+++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs
@@ -1,6 +1,7 @@
 //@ check-pass
 
 pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> {
+    //~^ WARNING elided lifetime has a name
     v.into_iter()
 }
 
diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
new file mode 100644
index 00000000000..bff3ffd934a
--- /dev/null
+++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
@@ -0,0 +1,10 @@
+warning: elided lifetime has a name
+  --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:82
+   |
+LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> {
+   |             -- lifetime `'a` declared here                                       ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
index d0a8fe795ef..63a2c9be9eb 100644
--- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
@@ -47,5 +47,6 @@ fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
 
 // This is ok because both `'a` are for the same parameter.
 fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
+//~^ WARNING elided lifetime has a name
 
 fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index 23ef36888f0..f835d2655bb 100644
--- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -105,6 +105,16 @@ help: consider using the `'a` lifetime
 LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
    |                                      ++
 
-error: aborting due to 7 previous errors
+warning: elided lifetime has a name
+  --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:49:29
+   |
+LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
+   |      --                     ^ this elided lifetime gets resolved as `'a`
+   |      |
+   |      lifetime `'a` declared here
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+error: aborting due to 7 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
index a1126d6bb15..598633d7576 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
@@ -4,6 +4,7 @@ struct Foo {
 
 impl Foo {
   fn foo<'a>(&'a self, x: &i32) -> &i32 {
+    //~^ WARNING elided lifetime has a name
 
     if true { &self.field } else { x } //~ ERROR explicit lifetime
 
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
index 6dda9e61a79..2d5d4fb0e72 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
@@ -1,12 +1,22 @@
+warning: elided lifetime has a name
+  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:6:36
+   |
+LL |   fn foo<'a>(&'a self, x: &i32) -> &i32 {
+   |          --                        ^ this elided lifetime gets resolved as `'a`
+   |          |
+   |          lifetime `'a` declared here
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:8:36
+  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36
    |
 LL |   fn foo<'a>(&'a self, x: &i32) -> &i32 {
    |                           ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
-LL |
+...
 LL |     if true { &self.field } else { x }
    |                                    ^ lifetime `'a` required
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lint/cli-unknown-force-warn.stderr b/tests/ui/lint/cli-unknown-force-warn.stderr
index cfff190b54a..5084b4a4001 100644
--- a/tests/ui/lint/cli-unknown-force-warn.stderr
+++ b/tests/ui/lint/cli-unknown-force-warn.stderr
@@ -13,11 +13,6 @@ warning[E0602]: unknown lint: `foo_qux`
    = note: requested on the command line with `--force-warn foo_qux`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-warning[E0602]: unknown lint: `foo_qux`
-   |
-   = note: requested on the command line with `--force-warn foo_qux`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: 4 warnings emitted
+warning: 3 warnings emitted
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs
new file mode 100644
index 00000000000..eac7c32a9aa
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs
@@ -0,0 +1,12 @@
+#![deny(elided_named_lifetimes)]
+
+struct Foo;
+
+impl Foo {
+    pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
+        //~^ ERROR elided lifetime has a name
+        unsafe { &mut *(x as *mut _) }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
new file mode 100644
index 00000000000..8c5426a60cb
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
@@ -0,0 +1,14 @@
+error: elided lifetime has a name
+  --> $DIR/example-from-issue48686.rs:6:50
+   |
+LL |     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
+   |                                                  ^ this elided lifetime gets resolved as `'static`
+   |
+note: the lint level is defined here
+  --> $DIR/example-from-issue48686.rs:1:9
+   |
+LL | #![deny(elided_named_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs
new file mode 100644
index 00000000000..2f9083ed65f
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs
@@ -0,0 +1,27 @@
+#![deny(elided_named_lifetimes)]
+
+fn ampersand<'a>(x: &'a u8) -> &u8 {
+    //~^ ERROR elided lifetime has a name
+    x
+}
+
+struct Brackets<'a>(&'a u8);
+
+fn brackets<'a>(x: &'a u8) -> Brackets {
+    //~^ ERROR elided lifetime has a name
+    Brackets(x)
+}
+
+struct Comma<'a, T>(&'a T);
+
+fn comma<'a>(x: &'a u8) -> Comma<u8> {
+    //~^ ERROR elided lifetime has a name
+    Comma(x)
+}
+
+fn underscore<'a>(x: &'a u8) -> &'_ u8 {
+    //~^ ERROR elided lifetime has a name
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
new file mode 100644
index 00000000000..249ae146b16
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
@@ -0,0 +1,40 @@
+error: elided lifetime has a name
+  --> $DIR/missing-lifetime-kind.rs:3:32
+   |
+LL | fn ampersand<'a>(x: &'a u8) -> &u8 {
+   |              --                ^ this elided lifetime gets resolved as `'a`
+   |              |
+   |              lifetime `'a` declared here
+   |
+note: the lint level is defined here
+  --> $DIR/missing-lifetime-kind.rs:1:9
+   |
+LL | #![deny(elided_named_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: elided lifetime has a name
+  --> $DIR/missing-lifetime-kind.rs:10:31
+   |
+LL | fn brackets<'a>(x: &'a u8) -> Brackets {
+   |             --                ^^^^^^^^ this elided lifetime gets resolved as `'a`
+   |             |
+   |             lifetime `'a` declared here
+
+error: elided lifetime has a name
+  --> $DIR/missing-lifetime-kind.rs:17:33
+   |
+LL | fn comma<'a>(x: &'a u8) -> Comma<u8> {
+   |          --                     ^ this elided lifetime gets resolved as `'a`
+   |          |
+   |          lifetime `'a` declared here
+
+error: elided lifetime has a name
+  --> $DIR/missing-lifetime-kind.rs:22:34
+   |
+LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 {
+   |               --                 ^^ this elided lifetime gets resolved as `'a`
+   |               |
+   |               lifetime `'a` declared here
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs
new file mode 100644
index 00000000000..4f9218130fb
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs
@@ -0,0 +1,17 @@
+#![allow(elided_named_lifetimes)]
+
+#[warn(elided_named_lifetimes)]
+mod foo {
+    fn bar(x: &'static u8) -> &u8 {
+        //~^ WARNING elided lifetime has a name
+        x
+    }
+
+    #[deny(elided_named_lifetimes)]
+    fn baz(x: &'static u8) -> &u8 {
+        //~^ ERROR elided lifetime has a name
+        x
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
new file mode 100644
index 00000000000..c465aab1a03
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
@@ -0,0 +1,26 @@
+warning: elided lifetime has a name
+  --> $DIR/not-tied-to-crate.rs:5:31
+   |
+LL |     fn bar(x: &'static u8) -> &u8 {
+   |                               ^ this elided lifetime gets resolved as `'static`
+   |
+note: the lint level is defined here
+  --> $DIR/not-tied-to-crate.rs:3:8
+   |
+LL | #[warn(elided_named_lifetimes)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^
+
+error: elided lifetime has a name
+  --> $DIR/not-tied-to-crate.rs:11:31
+   |
+LL |     fn baz(x: &'static u8) -> &u8 {
+   |                               ^ this elided lifetime gets resolved as `'static`
+   |
+note: the lint level is defined here
+  --> $DIR/not-tied-to-crate.rs:10:12
+   |
+LL |     #[deny(elided_named_lifetimes)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/elided-named-lifetimes/static.rs b/tests/ui/lint/elided-named-lifetimes/static.rs
new file mode 100644
index 00000000000..dc8222c6e6e
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/static.rs
@@ -0,0 +1,46 @@
+#![deny(elided_named_lifetimes)]
+
+use std::borrow::Cow;
+
+const A: &[u8] = &[];
+static B: &str = "hello";
+
+trait Trait {
+    const C: &u8 = &0;
+}
+
+impl Trait for () {
+    const C: &u8 = &1;
+}
+
+fn ampersand(x: &'static u8) -> &u8 {
+    //~^ ERROR elided lifetime has a name
+    x
+}
+
+struct Brackets<'a>(&'a u8);
+
+fn brackets(x: &'static u8) -> Brackets {
+    //~^ ERROR elided lifetime has a name
+    Brackets(x)
+}
+
+struct Comma<'a, T>(&'a T);
+
+fn comma(x: &'static u8) -> Comma<u8> {
+    //~^ ERROR elided lifetime has a name
+    Comma(x)
+}
+
+fn underscore(x: &'static u8) -> &'_ u8 {
+    //~^ ERROR elided lifetime has a name
+    x
+}
+
+const NESTED: &Vec<&Box<Cow<str>>> = &vec![];
+
+fn main() {
+    const HELLO: &str = "Hello";
+    static WORLD: &str = "world";
+    println!("{HELLO}, {WORLD}!")
+}
diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr
new file mode 100644
index 00000000000..d2e9776cb4f
--- /dev/null
+++ b/tests/ui/lint/elided-named-lifetimes/static.stderr
@@ -0,0 +1,32 @@
+error: elided lifetime has a name
+  --> $DIR/static.rs:16:33
+   |
+LL | fn ampersand(x: &'static u8) -> &u8 {
+   |                                 ^ this elided lifetime gets resolved as `'static`
+   |
+note: the lint level is defined here
+  --> $DIR/static.rs:1:9
+   |
+LL | #![deny(elided_named_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: elided lifetime has a name
+  --> $DIR/static.rs:23:32
+   |
+LL | fn brackets(x: &'static u8) -> Brackets {
+   |                                ^^^^^^^^ this elided lifetime gets resolved as `'static`
+
+error: elided lifetime has a name
+  --> $DIR/static.rs:30:34
+   |
+LL | fn comma(x: &'static u8) -> Comma<u8> {
+   |                                  ^ this elided lifetime gets resolved as `'static`
+
+error: elided lifetime has a name
+  --> $DIR/static.rs:35:35
+   |
+LL | fn underscore(x: &'static u8) -> &'_ u8 {
+   |                                   ^^ this elided lifetime gets resolved as `'static`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/lint-removed-cmdline-deny.stderr b/tests/ui/lint/lint-removed-cmdline-deny.stderr
index 2a24e795f44..3321afa7fcd 100644
--- a/tests/ui/lint/lint-removed-cmdline-deny.stderr
+++ b/tests/ui/lint/lint-removed-cmdline-deny.stderr
@@ -26,10 +26,5 @@ LL | #[deny(warnings)]
    |        ^^^^^^^^
    = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
 
-error: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
-   |
-   = note: requested on the command line with `-D raw_pointer_derive`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/lint/lint-removed-cmdline.stderr b/tests/ui/lint/lint-removed-cmdline.stderr
index 78ae2fd8fbf..fd63433c308 100644
--- a/tests/ui/lint/lint-removed-cmdline.stderr
+++ b/tests/ui/lint/lint-removed-cmdline.stderr
@@ -26,10 +26,5 @@ LL | #[deny(warnings)]
    |        ^^^^^^^^
    = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
 
-warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
-   |
-   = note: requested on the command line with `-D raw_pointer_derive`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 1 previous error; 4 warnings emitted
+error: aborting due to 1 previous error; 3 warnings emitted
 
diff --git a/tests/ui/lint/lint-renamed-cmdline-deny.stderr b/tests/ui/lint/lint-renamed-cmdline-deny.stderr
index 3c1a59ec1e1..0e182a4e5de 100644
--- a/tests/ui/lint/lint-renamed-cmdline-deny.stderr
+++ b/tests/ui/lint/lint-renamed-cmdline-deny.stderr
@@ -29,11 +29,5 @@ LL | #[deny(unused)]
    |        ^^^^^^
    = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
 
-error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
-   |
-   = help: use the new name `bare_trait_objects`
-   = note: requested on the command line with `-D bare_trait_object`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/lint/lint-renamed-cmdline.stderr b/tests/ui/lint/lint-renamed-cmdline.stderr
index 6544416f611..d6bb72f34dc 100644
--- a/tests/ui/lint/lint-renamed-cmdline.stderr
+++ b/tests/ui/lint/lint-renamed-cmdline.stderr
@@ -29,11 +29,5 @@ LL | #[deny(unused)]
    |        ^^^^^^
    = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
 
-warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
-   |
-   = help: use the new name `bare_trait_objects`
-   = note: requested on the command line with `-D bare_trait_object`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 1 previous error; 4 warnings emitted
+error: aborting due to 1 previous error; 3 warnings emitted
 
diff --git a/tests/ui/lint/lint-unexported-no-mangle.stderr b/tests/ui/lint/lint-unexported-no-mangle.stderr
index 39377b6fe84..0efec51abaf 100644
--- a/tests/ui/lint/lint-unexported-no-mangle.stderr
+++ b/tests/ui/lint/lint-unexported-no-mangle.stderr
@@ -45,15 +45,5 @@ LL | pub const PUB_FOO: u64 = 1;
    | |
    | help: try a static value: `pub static`
 
-warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported
-   |
-   = note: requested on the command line with `-F private_no_mangle_fns`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported
-   |
-   = note: requested on the command line with `-F private_no_mangle_statics`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors; 8 warnings emitted
+error: aborting due to 2 previous errors; 6 warnings emitted
 
diff --git a/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr b/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr
index 1ce55706d76..f12ce03ddfc 100644
--- a/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr
+++ b/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr
@@ -30,17 +30,6 @@ error[E0602]: unknown lint: `dead_cod`
    = note: requested on the command line with `-D dead_cod`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0602]: unknown lint: `bogus`
-   |
-   = note: requested on the command line with `-D bogus`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0602]: unknown lint: `dead_cod`
-   |
-   = help: did you mean: `dead_code`
-   = note: requested on the command line with `-D dead_cod`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/lint/lint-unknown-lint-cmdline.stderr b/tests/ui/lint/lint-unknown-lint-cmdline.stderr
index 4e0c5dbcb07..f452fc9eb94 100644
--- a/tests/ui/lint/lint-unknown-lint-cmdline.stderr
+++ b/tests/ui/lint/lint-unknown-lint-cmdline.stderr
@@ -30,17 +30,6 @@ warning[E0602]: unknown lint: `dead_cod`
    = note: requested on the command line with `-D dead_cod`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-warning[E0602]: unknown lint: `bogus`
-   |
-   = note: requested on the command line with `-D bogus`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning[E0602]: unknown lint: `dead_cod`
-   |
-   = help: did you mean: `dead_code`
-   = note: requested on the command line with `-D dead_cod`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: 8 warnings emitted
+warning: 6 warnings emitted
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
index 3ceefbc4066..87bbd50a15c 100644
--- a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -1,16 +1,16 @@
-error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])` captures lifetime that does not appear in bounds
+error[E0700]: hidden type for `Opaque(DefId(0:11 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])` captures lifetime that does not appear in bounds
   --> $DIR/impl-trait-captures.rs:11:5
    |
 LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
    |                  --     ------------ opaque type defined here
    |                  |
-   |                  hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here
+   |                  hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here
 LL |     x
    |     ^
    |
-help: add a `use<...>` bound to explicitly capture `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`
+help: add a `use<...>` bound to explicitly capture `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_))`
    |
-LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + use<'a, ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)), T> {
+LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + use<'a, ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)), T> {
    |                                      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.rs b/tests/ui/object-lifetime/object-lifetime-default-elision.rs
index f7c0261cfbb..ede6af51174 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-elision.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-elision.rs
@@ -46,6 +46,8 @@ fn load1(ss: &dyn SomeTrait) -> &dyn SomeTrait {
 }
 
 fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait {
+    //~^ WARNING elided lifetime has a name
+
     // Same as `load1` but with an explicit name thrown in for fun.
 
     ss
diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
index b5995687927..b44a184c684 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
+++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
@@ -1,5 +1,15 @@
+warning: elided lifetime has a name
+  --> $DIR/object-lifetime-default-elision.rs:48:40
+   |
+LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait {
+   |          --                            ^ this elided lifetime gets resolved as `'a`
+   |          |
+   |          lifetime `'a` declared here
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error: lifetime may not live long enough
-  --> $DIR/object-lifetime-default-elision.rs:71:5
+  --> $DIR/object-lifetime-default-elision.rs:73:5
    |
 LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
    |          -- -- lifetime `'b` defined here
@@ -11,5 +21,5 @@ LL |     ss
    |
    = help: consider adding the following bound: `'a: 'b`
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
index f7f61b8c810..cedc6f0f9bc 100644
--- a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
+++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
@@ -4,9 +4,11 @@ struct Foo<'a>(&'a str);
 
 impl<'b> Foo<'b> {
     fn a<'a>(self: Self, a: &'a str) -> &str {
+        //~^ WARNING elided lifetime has a name
         a
     }
     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
+        //~^ WARNING elided lifetime has a name
         a
     }
 }
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
new file mode 100644
index 00000000000..4465dbae529
--- /dev/null
+++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
@@ -0,0 +1,16 @@
+warning: elided lifetime has a name
+  --> $DIR/ignore-non-reference-lifetimes.rs:6:41
+   |
+LL |     fn a<'a>(self: Self, a: &'a str) -> &str {
+   |          -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+warning: elided lifetime has a name
+  --> $DIR/ignore-non-reference-lifetimes.rs:10:44
+   |
+LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
+   |          -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/self/elision/lt-ref-self-async.fixed b/tests/ui/self/elision/lt-ref-self-async.fixed
index aa1d62012da..914511641b8 100644
--- a/tests/ui/self/elision/lt-ref-self-async.fixed
+++ b/tests/ui/self/elision/lt-ref-self-async.fixed
@@ -1,6 +1,6 @@
 //@ edition:2018
 //@ run-rustfix
-#![allow(non_snake_case, dead_code)]
+#![allow(non_snake_case, dead_code, elided_named_lifetimes)]
 
 use std::pin::Pin;
 
diff --git a/tests/ui/self/elision/lt-ref-self-async.rs b/tests/ui/self/elision/lt-ref-self-async.rs
index 38de0fd39f0..0c11b271c35 100644
--- a/tests/ui/self/elision/lt-ref-self-async.rs
+++ b/tests/ui/self/elision/lt-ref-self-async.rs
@@ -1,6 +1,6 @@
 //@ edition:2018
 //@ run-rustfix
-#![allow(non_snake_case, dead_code)]
+#![allow(non_snake_case, dead_code, elided_named_lifetimes)]
 
 use std::pin::Pin;
 
diff --git a/tests/ui/self/self_lifetime-async.rs b/tests/ui/self/self_lifetime-async.rs
index 7d6eb3f5eaf..fd690207118 100644
--- a/tests/ui/self/self_lifetime-async.rs
+++ b/tests/ui/self/self_lifetime-async.rs
@@ -4,11 +4,13 @@
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {
     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+    //~^ WARNING elided lifetime has a name
 }
 
 type Alias = Foo<'static>;
 impl Alias {
     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+    //~^ WARNING elided lifetime has a name
 }
 
 fn main() {}
diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr
new file mode 100644
index 00000000000..32de3fd18c9
--- /dev/null
+++ b/tests/ui/self/self_lifetime-async.stderr
@@ -0,0 +1,18 @@
+warning: elided lifetime has a name
+  --> $DIR/self_lifetime-async.rs:6:44
+   |
+LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+   |                  --                        ^ this elided lifetime gets resolved as `'b`
+   |                  |
+   |                  lifetime `'b` declared here
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+warning: elided lifetime has a name
+  --> $DIR/self_lifetime-async.rs:12:52
+   |
+LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+   |                  -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/self/self_lifetime.rs b/tests/ui/self/self_lifetime.rs
index 3f655b960b1..0607c3b9317 100644
--- a/tests/ui/self/self_lifetime.rs
+++ b/tests/ui/self/self_lifetime.rs
@@ -5,11 +5,13 @@
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {
     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+    //~^ WARNING elided lifetime has a name
 }
 
 type Alias = Foo<'static>;
 impl Alias {
     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+    //~^ WARNING elided lifetime has a name
 }
 
 fn main() {}
diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr
new file mode 100644
index 00000000000..cd8f4d8adf8
--- /dev/null
+++ b/tests/ui/self/self_lifetime.stderr
@@ -0,0 +1,18 @@
+warning: elided lifetime has a name
+  --> $DIR/self_lifetime.rs:7:38
+   |
+LL |     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+   |            --                        ^ this elided lifetime gets resolved as `'b`
+   |            |
+   |            lifetime `'b` declared here
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
+warning: elided lifetime has a name
+  --> $DIR/self_lifetime.rs:13:46
+   |
+LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+   |            -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
index 735efe89cba..daec66709b6 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
@@ -64,6 +64,7 @@ mod in_path {
 
 // This must not err, as the `&` actually resolves to `'a`.
 fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
+    //~^ WARNING elided lifetime has a name
     f("f");
 }
 
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
index 61a2925f582..30f4509d49d 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -124,6 +124,14 @@ LL -     fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
 LL +     fn g(mut x: impl Foo<()>) -> Option<()> { x.next() }
    |
 
+warning: elided lifetime has a name
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:66:57
+   |
+LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
+   |                       -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
   --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35
    |
@@ -244,7 +252,7 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() }
    |         ++++                 +++
 
-error: aborting due to 16 previous errors
+error: aborting due to 16 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0106, E0658.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
index b641f5941dc..b61bea16e3b 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
@@ -100,6 +100,7 @@ where
 
 // This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
 fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
+//~^ WARNING elided lifetime has a name
 where
     G: Get<T>,
 {
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index 88a18e9d06d..ea01dcd5020 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -6,6 +6,14 @@ LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
    |        |
    |        help: consider introducing lifetime `'a` here: `'a,`
 
+warning: elided lifetime has a name
+  --> $DIR/missing-lifetimes-in-signature.rs:102:64
+   |
+LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
+   |        -- lifetime `'a` declared here                          ^^ this elided lifetime gets resolved as `'a`
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds
   --> $DIR/missing-lifetimes-in-signature.rs:19:5
    |
@@ -125,7 +133,7 @@ help: consider adding an explicit lifetime bound
 LL |     G: Get<T> + 'a,
    |               ++++
 
-error: aborting due to 8 previous errors
+error: aborting due to 8 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700.
 For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/target-feature/struct-target-features.rs b/tests/ui/target-feature/struct-target-features.rs
deleted file mode 100644
index feb479b6dc8..00000000000
--- a/tests/ui/target-feature/struct-target-features.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-//@ only-x86_64
-#![feature(struct_target_features)]
-//~^ WARNING the feature `struct_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
-#![feature(target_feature_11)]
-
-use std::arch::x86_64::*;
-
-#[target_feature(enable = "avx")]
-//~^ ERROR attribute should be applied to a function definition or unit struct
-struct Invalid(u32);
-
-#[target_feature(enable = "avx")]
-struct Avx {}
-
-#[target_feature(enable = "sse")]
-struct Sse();
-
-#[target_feature(enable = "avx")]
-fn avx() {}
-
-trait TFAssociatedType {
-    type Assoc;
-}
-
-impl TFAssociatedType for () {
-    type Assoc = Avx;
-}
-
-fn avx_self(_: <() as TFAssociatedType>::Assoc) {
-    avx();
-}
-
-fn avx_avx(_: Avx) {
-    avx();
-}
-
-extern "C" fn bad_fun(_: Avx) {}
-//~^ ERROR cannot use a struct with target features in a function with non-Rust ABI
-
-#[inline(always)]
-//~^ ERROR cannot use `#[inline(always)]` with `#[target_feature]`
-fn inline_fun(_: Avx) {}
-//~^ ERROR cannot use a struct with target features in a #[inline(always)] function
-
-trait Simd {
-    fn do_something(&self);
-}
-
-impl Simd for Avx {
-    fn do_something(&self) {
-        unsafe {
-            println!("{:?}", _mm256_setzero_ps());
-        }
-    }
-}
-
-impl Simd for Sse {
-    fn do_something(&self) {
-        unsafe {
-            println!("{:?}", _mm_setzero_ps());
-        }
-    }
-}
-
-struct WithAvx {
-    #[allow(dead_code)]
-    avx: Avx,
-}
-
-impl Simd for WithAvx {
-    fn do_something(&self) {
-        unsafe {
-            println!("{:?}", _mm256_setzero_ps());
-        }
-    }
-}
-
-#[inline(never)]
-fn dosomething<S: Simd>(simd: &S) {
-    simd.do_something();
-}
-
-fn avxfn(_: &Avx) {}
-
-fn main() {
-    Avx {};
-    //~^ ERROR initializing type with `target_feature` attr is unsafe and requires unsafe function or block [E0133]
-
-    if is_x86_feature_detected!("avx") {
-        let avx = unsafe { Avx {} };
-        avxfn(&avx);
-        dosomething(&avx);
-        dosomething(&WithAvx { avx });
-    }
-    if is_x86_feature_detected!("sse") {
-        dosomething(&unsafe { Sse {} })
-    }
-}
diff --git a/tests/ui/target-feature/struct-target-features.stderr b/tests/ui/target-feature/struct-target-features.stderr
deleted file mode 100644
index 5ef863f504e..00000000000
--- a/tests/ui/target-feature/struct-target-features.stderr
+++ /dev/null
@@ -1,47 +0,0 @@
-warning: the feature `struct_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/struct-target-features.rs:2:12
-   |
-LL | #![feature(struct_target_features)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #129107 <https://github.com/rust-lang/rust/issues/129107> for more information
-   = note: `#[warn(incomplete_features)]` on by default
-
-error: attribute should be applied to a function definition or unit struct
-  --> $DIR/struct-target-features.rs:8:1
-   |
-LL | #[target_feature(enable = "avx")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |
-LL | struct Invalid(u32);
-   | -------------------- not a function definition or a unit struct
-
-error: cannot use a struct with target features in a function with non-Rust ABI
-  --> $DIR/struct-target-features.rs:37:1
-   |
-LL | extern "C" fn bad_fun(_: Avx) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cannot use a struct with target features in a #[inline(always)] function
-  --> $DIR/struct-target-features.rs:42:1
-   |
-LL | fn inline_fun(_: Avx) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
-
-error: cannot use `#[inline(always)]` with `#[target_feature]`
-  --> $DIR/struct-target-features.rs:40:1
-   |
-LL | #[inline(always)]
-   | ^^^^^^^^^^^^^^^^^
-
-error[E0133]: initializing type with `target_feature` attr is unsafe and requires unsafe function or block
-  --> $DIR/struct-target-features.rs:86:5
-   |
-LL |     Avx {};
-   |     ^^^^^^ initializing type with `target_feature` attr
-   |
-   = note: this struct can only be constructed if the corresponding `target_feature`s are available
-
-error: aborting due to 5 previous errors; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
index c584a58cb32..c178fcf5a91 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
@@ -2,7 +2,7 @@
 
 type Opaque2<T> = impl Sized;
 type Opaque<'a, T> = Opaque2<T>;
-fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
+fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x } //~ WARNING elided lifetime has a name
 //~^ ERROR: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
index 03cc943d509..e2c21f1636b 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -1,3 +1,13 @@
+warning: elided lifetime has a name
+  --> $DIR/missing_lifetime_bound.rs:5:41
+   |
+LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
+   |             --                          ^ this elided lifetime gets resolved as `'a`
+   |             |
+   |             lifetime `'a` declared here
+   |
+   = note: `#[warn(elided_named_lifetimes)]` on by default
+
 error[E0700]: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
   --> $DIR/missing_lifetime_bound.rs:5:47
    |
@@ -9,6 +19,6 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
    |             |
    |             hidden type `&'a i32` captures the lifetime `'a` as defined here
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0700`.