about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs595
-rw-r--r--compiler/rustc_ast_lowering/src/lifetime_collector.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0577.md2
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs23
-rw-r--r--compiler/rustc_lint/src/lints.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs14
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs28
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs2
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs29
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs62
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs31
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs22
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs10
-rw-r--r--library/core/src/clone.rs40
-rw-r--r--library/core/src/iter/mod.rs6
-rw-r--r--library/core/src/iter/traits/double_ended.rs62
-rw-r--r--library/core/src/iter/traits/iterator.rs62
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/tidy/src/fluent_alphabetical.rs2
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/run-make/pretty-print-with-dep-file/Makefile9
-rw-r--r--tests/run-make/pretty-print-with-dep-file/with-dep.rs1
-rw-r--r--tests/rustdoc-gui/scrape-examples-toggle.goml12
-rw-r--r--tests/ui/issues/issue-100605.rs9
-rw-r--r--tests/ui/lint/invalid-nan-comparison.stderr5
-rw-r--r--tests/ui/lint/missing-copy-implementations-negative-copy.rs15
-rw-r--r--tests/ui/resolve/issue-114433-invalid-unused-qualifications-suggestion.rs10
-rw-r--r--tests/ui/resolve/unresolved-segments-visibility.rs11
-rw-r--r--tests/ui/resolve/unresolved-segments-visibility.stderr9
-rw-r--r--tests/ui/span/visibility-ty-params.rs2
-rw-r--r--tests/ui/span/visibility-ty-params.stderr6
-rw-r--r--tests/ui/type/option-ref-advice.rs11
-rw-r--r--tests/ui/type/option-ref-advice.stderr (renamed from tests/ui/issues/issue-100605.stderr)8
-rw-r--r--tests/ui/use/use-self-type.stderr4
43 files changed, 598 insertions, 556 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index ac750690046..d29e9f9b3f6 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -512,11 +512,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.resolver.node_id_to_def_id.get(&node).map(|local_def_id| *local_def_id)
     }
 
-    fn orig_local_def_id(&self, node: NodeId) -> LocalDefId {
-        self.orig_opt_local_def_id(node)
-            .unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
-    }
-
     /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
     /// resolver (if any), after applying any remapping from `get_remapped_def_id`.
     ///
@@ -1521,209 +1516,86 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // frequently opened issues show.
         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
 
-        let opaque_ty_def_id = self.create_def(
-            self.current_hir_id_owner.def_id,
-            opaque_ty_node_id,
-            DefPathData::ImplTrait,
-            opaque_ty_span,
-        );
-        debug!(?opaque_ty_def_id);
-
-        // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
-        // to capture the lifetimes that appear in the bounds. So visit the bounds to find out
-        // exactly which ones those are.
-        let lifetimes_to_remap = match origin {
+        let captured_lifetimes_to_duplicate = match origin {
             hir::OpaqueTyOrigin::TyAlias { .. } => {
-                // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
+                // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't duplicate any
+                // lifetimes, since we don't have the issue that any are late-bound.
                 Vec::new()
             }
-            hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => {
-                // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
-                // we only keep the lifetimes that appear in the `impl Debug` itself:
+            hir::OpaqueTyOrigin::FnReturn(..) => {
+                // in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
+                // example, we only need to duplicate lifetimes that appear in the
+                // bounds, since those are the only ones that are captured by the opaque.
                 lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
             }
+            hir::OpaqueTyOrigin::AsyncFn(..) => {
+                unreachable!("should be using `lower_async_fn_ret_ty`")
+            }
         };
-        debug!(?lifetimes_to_remap);
-
-        let mut new_remapping = FxHashMap::default();
-
-        // Contains the new lifetime definitions created for the TAIT (if any).
-        // If this opaque type is only capturing a subset of the lifetimes (those that appear in
-        // bounds), then create the new lifetime parameters required and create a mapping from the
-        // old `'a` (on the function) to the new `'a` (on the opaque type).
-        let collected_lifetimes =
-            self.create_lifetime_defs(opaque_ty_def_id, &lifetimes_to_remap, &mut new_remapping);
-        debug!(?collected_lifetimes);
-        debug!(?new_remapping);
-
-        // This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type
-        // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`.
-        let collected_lifetime_mapping: Vec<_> = collected_lifetimes
-            .iter()
-            .map(|(node_id, lifetime)| {
-                let id = self.next_node_id();
-                let lifetime = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
-                let def_id = self.local_def_id(*node_id);
-                (lifetime, def_id)
-            })
-            .collect();
-        debug!(?collected_lifetime_mapping);
-
-        self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
-            // Install the remapping from old to new (if any):
-            lctx.with_remapping(new_remapping, |lctx| {
-                // This creates HIR lifetime definitions as `hir::GenericParam`, in the given
-                // example `type TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection
-                // containing `&['x]`.
-                let lifetime_defs = lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(
-                    |&(new_node_id, lifetime)| {
-                        let hir_id = lctx.lower_node_id(new_node_id);
-                        debug_assert_ne!(lctx.opt_local_def_id(new_node_id), None);
-
-                        let (name, kind) = if lifetime.ident.name == kw::UnderscoreLifetime {
-                            (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided)
-                        } else {
-                            (
-                                hir::ParamName::Plain(lifetime.ident),
-                                hir::LifetimeParamKind::Explicit,
-                            )
-                        };
+        debug!(?captured_lifetimes_to_duplicate);
 
-                        hir::GenericParam {
-                            hir_id,
-                            def_id: lctx.local_def_id(new_node_id),
-                            name,
-                            span: lifetime.ident.span,
-                            pure_wrt_drop: false,
-                            kind: hir::GenericParamKind::Lifetime { kind },
-                            colon_span: None,
-                            source: hir::GenericParamSource::Generics,
-                        }
-                    },
-                ));
-                debug!(?lifetime_defs);
-
-                // Then when we lower the param bounds, references to 'a are remapped to 'a1, so we
-                // get back Debug + 'a1, which is suitable for use on the TAIT.
-                let hir_bounds = lctx.lower_param_bounds(bounds, itctx);
-                debug!(?hir_bounds);
-
-                let lifetime_mapping = if in_trait {
-                    Some(
-                        &*self.arena.alloc_from_iter(
-                            collected_lifetime_mapping
-                                .iter()
-                                .map(|(lifetime, def_id)| (**lifetime, *def_id)),
-                        ),
-                    )
-                } else {
-                    None
-                };
-
-                let opaque_ty_item = hir::OpaqueTy {
-                    generics: self.arena.alloc(hir::Generics {
-                        params: lifetime_defs,
-                        predicates: &[],
-                        has_where_clause_predicates: false,
-                        where_clause_span: lctx.lower_span(span),
-                        span: lctx.lower_span(span),
-                    }),
-                    bounds: hir_bounds,
-                    origin,
-                    lifetime_mapping,
-                    in_trait,
-                };
-                debug!(?opaque_ty_item);
-
-                lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
-            })
-        });
-
-        // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
-        hir::TyKind::OpaqueDef(
-            hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
-            self.arena.alloc_from_iter(
-                collected_lifetime_mapping
-                    .iter()
-                    .map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)),
-            ),
+        self.lower_opaque_inner(
+            opaque_ty_node_id,
+            origin,
             in_trait,
+            captured_lifetimes_to_duplicate,
+            span,
+            opaque_ty_span,
+            |this| this.lower_param_bounds(bounds, itctx),
         )
     }
 
-    /// Registers a new opaque type with the proper `NodeId`s and
-    /// returns the lowered node-ID for the opaque type.
-    fn generate_opaque_type(
+    fn lower_opaque_inner(
         &mut self,
-        opaque_ty_id: LocalDefId,
-        opaque_ty_item: hir::OpaqueTy<'hir>,
+        opaque_ty_node_id: NodeId,
+        origin: hir::OpaqueTyOrigin,
+        in_trait: bool,
+        captured_lifetimes_to_duplicate: Vec<Lifetime>,
         span: Span,
         opaque_ty_span: Span,
-    ) -> hir::OwnerNode<'hir> {
-        let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(self.arena.alloc(opaque_ty_item));
-        // Generate an `type Foo = impl Trait;` declaration.
-        trace!("registering opaque type with id {:#?}", opaque_ty_id);
-        let opaque_ty_item = hir::Item {
-            owner_id: hir::OwnerId { def_id: opaque_ty_id },
-            ident: Ident::empty(),
-            kind: opaque_ty_item_kind,
-            vis_span: self.lower_span(span.shrink_to_lo()),
-            span: self.lower_span(opaque_ty_span),
-        };
-        hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
-    }
-
-    /// Given a `parent_def_id`, a list of `lifetimes_in_bounds` and a `remapping` hash to be
-    /// filled, this function creates new definitions for `Param` and `Fresh` lifetimes, inserts the
-    /// new definition, adds it to the remapping with the definition of the given lifetime and
-    /// returns a list of lifetimes to be lowered afterwards.
-    fn create_lifetime_defs(
-        &mut self,
-        parent_def_id: LocalDefId,
-        lifetimes_in_bounds: &[Lifetime],
-        remapping: &mut FxHashMap<LocalDefId, LocalDefId>,
-    ) -> Vec<(NodeId, Lifetime)> {
-        let mut result = Vec::new();
+        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,
+            opaque_ty_node_id,
+            DefPathData::ImplTrait,
+            opaque_ty_span,
+        );
+        debug!(?opaque_ty_def_id);
 
-        for lifetime in lifetimes_in_bounds {
+        // Map from captured (old) lifetime to synthetic (new) lifetime.
+        // Used to resolve lifetimes in the bounds of the opaque.
+        let mut captured_to_synthesized_mapping = FxHashMap::default();
+        // List of (early-bound) synthetic lifetimes that are owned by the opaque.
+        // This is used to create the `hir::Generics` owned by the opaque.
+        let mut synthesized_lifetime_definitions = vec![];
+        // Pairs of lifetime arg (that resolves to the captured lifetime)
+        // and the def-id of the (early-bound) synthetic lifetime definition.
+        // This is used both to create generics for the `TyKind::OpaqueDef` that
+        // we return, and also as a captured lifetime mapping for RPITITs.
+        let mut synthesized_lifetime_args = vec![];
+
+        for lifetime in captured_lifetimes_to_duplicate {
             let res = self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error);
-            debug!(?res);
-
-            match res {
-                LifetimeRes::Param { param: old_def_id, binder: _ } => {
-                    if remapping.get(&old_def_id).is_none() {
-                        let node_id = self.next_node_id();
-
-                        let new_def_id = self.create_def(
-                            parent_def_id,
-                            node_id,
-                            DefPathData::LifetimeNs(lifetime.ident.name),
-                            lifetime.ident.span,
-                        );
-                        remapping.insert(old_def_id, new_def_id);
-
-                        result.push((node_id, *lifetime));
-                    }
-                }
+            let old_def_id = match res {
+                LifetimeRes::Param { param: old_def_id, binder: _ } => old_def_id,
 
                 LifetimeRes::Fresh { param, binder: _ } => {
                     debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
-                    if let Some(old_def_id) = self.orig_opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
-                        let node_id = self.next_node_id();
-
-                        let new_def_id = self.create_def(
-                            parent_def_id,
-                            node_id,
-                            DefPathData::LifetimeNs(kw::UnderscoreLifetime),
-                            lifetime.ident.span,
-                        );
-                        remapping.insert(old_def_id, new_def_id);
-
-                        result.push((node_id, *lifetime));
+                    if let Some(old_def_id) = self.orig_opt_local_def_id(param) {
+                        old_def_id
+                    } else {
+                        self.tcx
+                            .sess
+                            .delay_span_bug(lifetime.ident.span, "no def-id for fresh lifetime");
+                        continue;
                     }
                 }
 
-                LifetimeRes::Static | LifetimeRes::Error => {}
+                // Opaques do not capture `'static`
+                LifetimeRes::Static | LifetimeRes::Error => {
+                    continue;
+                }
 
                 res => {
                     let bug_msg = format!(
@@ -1732,10 +1604,113 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     );
                     span_bug!(lifetime.ident.span, "{}", bug_msg);
                 }
+            };
+
+            if captured_to_synthesized_mapping.get(&old_def_id).is_none() {
+                // Create a new lifetime parameter local to the opaque.
+                let duplicated_lifetime_node_id = self.next_node_id();
+                let duplicated_lifetime_def_id = self.create_def(
+                    opaque_ty_def_id,
+                    duplicated_lifetime_node_id,
+                    DefPathData::LifetimeNs(lifetime.ident.name),
+                    lifetime.ident.span,
+                );
+                captured_to_synthesized_mapping.insert(old_def_id, duplicated_lifetime_def_id);
+                // FIXME: Instead of doing this, we could move this whole loop
+                // into the `with_hir_id_owner`, then just directly construct
+                // the `hir::GenericParam` here.
+                synthesized_lifetime_definitions.push((
+                    duplicated_lifetime_node_id,
+                    duplicated_lifetime_def_id,
+                    lifetime.ident,
+                ));
+
+                // Now make an arg that we can use for the substs of the opaque tykind.
+                let id = self.next_node_id();
+                let lifetime_arg = self.new_named_lifetime_with_res(id, lifetime.ident, res);
+                let duplicated_lifetime_def_id = self.local_def_id(duplicated_lifetime_node_id);
+                synthesized_lifetime_args.push((lifetime_arg, duplicated_lifetime_def_id))
             }
         }
 
-        result
+        self.with_hir_id_owner(opaque_ty_node_id, |this| {
+            // Install the remapping from old to new (if any). This makes sure that
+            // any lifetimes that would have resolved to the def-id of captured
+            // lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
+            let bounds = this
+                .with_remapping(captured_to_synthesized_mapping, |this| lower_item_bounds(this));
+
+            let generic_params = this.arena.alloc_from_iter(
+                synthesized_lifetime_definitions.iter().map(|&(new_node_id, new_def_id, ident)| {
+                    let hir_id = this.lower_node_id(new_node_id);
+                    let (name, kind) = if ident.name == kw::UnderscoreLifetime {
+                        (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided)
+                    } else {
+                        (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
+                    };
+
+                    hir::GenericParam {
+                        hir_id,
+                        def_id: new_def_id,
+                        name,
+                        span: ident.span,
+                        pure_wrt_drop: false,
+                        kind: hir::GenericParamKind::Lifetime { kind },
+                        colon_span: None,
+                        source: hir::GenericParamSource::Generics,
+                    }
+                }),
+            );
+            debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
+
+            let lifetime_mapping = if in_trait {
+                Some(&*self.arena.alloc_slice(&synthesized_lifetime_args))
+            } else {
+                None
+            };
+
+            let opaque_ty_item = hir::OpaqueTy {
+                generics: this.arena.alloc(hir::Generics {
+                    params: generic_params,
+                    predicates: &[],
+                    has_where_clause_predicates: false,
+                    where_clause_span: this.lower_span(span),
+                    span: this.lower_span(span),
+                }),
+                bounds,
+                origin,
+                lifetime_mapping,
+                in_trait,
+            };
+
+            // Generate an `type Foo = impl Trait;` declaration.
+            trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
+            let opaque_ty_item = hir::Item {
+                owner_id: hir::OwnerId { def_id: opaque_ty_def_id },
+                ident: Ident::empty(),
+                kind: hir::ItemKind::OpaqueTy(this.arena.alloc(opaque_ty_item)),
+                vis_span: this.lower_span(span.shrink_to_lo()),
+                span: this.lower_span(opaque_ty_span),
+            };
+
+            hir::OwnerNode::Item(this.arena.alloc(opaque_ty_item))
+        });
+
+        let generic_args = self.arena.alloc_from_iter(
+            synthesized_lifetime_args
+                .iter()
+                .map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)),
+        );
+
+        // Create the `Foo<...>` reference itself. Note that the `type
+        // Foo = impl Trait` is, internally, created as a child of the
+        // async fn, so the *type parameters* are inherited. It's
+        // only the lifetime parameters that we must supply.
+        hir::TyKind::OpaqueDef(
+            hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
+            generic_args,
+            in_trait,
+        )
     }
 
     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
@@ -1813,9 +1788,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
             }
 
+            let fn_def_id = self.local_def_id(fn_node_id);
             self.lower_async_fn_ret_ty(
                 &decl.output,
-                fn_node_id,
+                fn_def_id,
                 ret_id,
                 matches!(kind, FnDeclKind::Trait),
             )
@@ -1892,151 +1868,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_async_fn_ret_ty(
         &mut self,
         output: &FnRetTy,
-        fn_node_id: NodeId,
+        fn_def_id: LocalDefId,
         opaque_ty_node_id: NodeId,
         in_trait: bool,
     ) -> hir::FnRetTy<'hir> {
-        let span = output.span();
-
+        let span = self.lower_span(output.span());
         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
 
-        let fn_def_id = self.local_def_id(fn_node_id);
-
-        let opaque_ty_def_id =
-            self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait, opaque_ty_span);
-
-        // When we create the opaque type for this async fn, it is going to have
-        // to capture all the lifetimes involved in the signature (including in the
-        // return type). This is done by introducing lifetime parameters for:
-        //
-        // - all the explicitly declared lifetimes from the impl and function itself;
-        // - all the elided lifetimes in the fn arguments;
-        // - all the elided lifetimes in the return type.
-        //
-        // So for example in this snippet:
-        //
-        // ```rust
-        // impl<'a> Foo<'a> {
-        //   async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
-        //   //               ^ '0                       ^ '1     ^ '2
-        //   // elided lifetimes used below
-        //   }
-        // }
-        // ```
-        //
-        // we would create an opaque type like:
-        //
-        // ```
-        // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
-        // ```
-        //
-        // and we would then desugar `bar` to the equivalent of:
-        //
-        // ```rust
-        // impl<'a> Foo<'a> {
-        //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
-        // }
-        // ```
-        //
-        // Note that the final parameter to `Bar` is `'_`, not `'2` --
-        // this is because the elided lifetimes from the return type
-        // should be figured out using the ordinary elision rules, and
-        // this desugaring achieves that.
-
-        // Calculate all the lifetimes that should be captured
-        // by the opaque type. This should include all in-scope
-        // lifetime parameters, including those defined in-band.
-
-        // Contains the new lifetime definitions created for the TAIT (if any) generated for the
-        // return type.
-        let mut collected_lifetimes = Vec::new();
-        let mut new_remapping = FxHashMap::default();
-
-        let extra_lifetime_params = self.resolver.take_extra_lifetime_params(opaque_ty_node_id);
-        debug!(?extra_lifetime_params);
-        for (ident, outer_node_id, outer_res) in extra_lifetime_params {
-            let outer_def_id = self.orig_local_def_id(outer_node_id);
-            let inner_node_id = self.next_node_id();
-
-            // Add a definition for the in scope lifetime def.
-            let inner_def_id = self.create_def(
-                opaque_ty_def_id,
-                inner_node_id,
-                DefPathData::LifetimeNs(ident.name),
-                ident.span,
-            );
-            new_remapping.insert(outer_def_id, inner_def_id);
-
-            let inner_res = match outer_res {
-                // Input lifetime like `'a`:
-                LifetimeRes::Param { param, .. } => {
-                    LifetimeRes::Param { param, binder: fn_node_id }
-                }
-                // Input lifetime like `'1`:
-                LifetimeRes::Fresh { param, .. } => {
-                    LifetimeRes::Fresh { param, binder: fn_node_id }
-                }
-                LifetimeRes::Static | LifetimeRes::Error => continue,
-                res => {
-                    panic!(
-                        "Unexpected lifetime resolution {:?} for {:?} at {:?}",
-                        res, ident, ident.span
-                    )
-                }
-            };
-
-            let lifetime = Lifetime { id: outer_node_id, ident };
-            collected_lifetimes.push((inner_node_id, lifetime, Some(inner_res)));
-        }
-        debug!(?collected_lifetimes);
-
-        // We only want to capture the lifetimes that appear in the bounds. So visit the bounds to
-        // find out exactly which ones those are.
-        // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
-        // we only keep the lifetimes that appear in the `impl Debug` itself:
-        let lifetimes_to_remap = lifetime_collector::lifetimes_in_ret_ty(&self.resolver, output);
-        debug!(?lifetimes_to_remap);
-
-        // If this opaque type is only capturing a subset of the lifetimes (those that appear in
-        // bounds), then create the new lifetime parameters required and create a mapping from the
-        // old `'a` (on the function) to the new `'a` (on the opaque type).
-        collected_lifetimes.extend(
-            self.create_lifetime_defs(opaque_ty_def_id, &lifetimes_to_remap, &mut new_remapping)
-                .into_iter()
-                .map(|(new_node_id, lifetime)| (new_node_id, lifetime, None)),
-        );
-        debug!(?collected_lifetimes);
-        debug!(?new_remapping);
-
-        // This creates pairs of HIR lifetimes and def_ids. In the given example `type
-        // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing the
-        // new lifetime of the RPIT 'x and the def_id of the lifetime 'x corresponding to
-        // `TestReturn`.
-        let collected_lifetime_mapping: Vec<_> = collected_lifetimes
-            .iter()
-            .map(|(node_id, lifetime, res)| {
-                let id = self.next_node_id();
-                let res = res.unwrap_or(
-                    self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
-                );
-                let lifetime = self.new_named_lifetime_with_res(id, lifetime.ident, res);
-                let def_id = self.local_def_id(*node_id);
-                (lifetime, def_id)
-            })
+        let captured_lifetimes: Vec<_> = self
+            .resolver
+            .take_extra_lifetime_params(opaque_ty_node_id)
+            .into_iter()
+            .map(|(ident, id, _)| Lifetime { id, ident })
             .collect();
-        debug!(?collected_lifetime_mapping);
 
-        self.with_hir_id_owner(opaque_ty_node_id, |this| {
-            // Install the remapping from old to new (if any):
-            this.with_remapping(new_remapping, |this| {
-                // We have to be careful to get elision right here. The
-                // idea is that we create a lifetime parameter for each
-                // lifetime in the return type. So, given a return type
-                // like `async fn foo(..) -> &[&u32]`, we lower to `impl
-                // Future<Output = &'1 [ &'2 u32 ]>`.
-                //
-                // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
-                // hence the elision takes place at the fn site.
+        let opaque_ty_ref = self.lower_opaque_inner(
+            opaque_ty_node_id,
+            hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+            in_trait,
+            captured_lifetimes,
+            span,
+            opaque_ty_span,
+            |this| {
                 let future_bound = this.lower_async_fn_output_type_to_future_bound(
                     output,
                     span,
@@ -2052,96 +1905,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         }
                     },
                 );
-
-                let generic_params = this.arena.alloc_from_iter(collected_lifetimes.iter().map(
-                    |&(new_node_id, lifetime, _)| {
-                        let hir_id = this.lower_node_id(new_node_id);
-                        debug_assert_ne!(this.opt_local_def_id(new_node_id), None);
-
-                        let (name, kind) = if lifetime.ident.name == kw::UnderscoreLifetime {
-                            (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided)
-                        } else {
-                            (
-                                hir::ParamName::Plain(lifetime.ident),
-                                hir::LifetimeParamKind::Explicit,
-                            )
-                        };
-
-                        hir::GenericParam {
-                            hir_id,
-                            def_id: this.local_def_id(new_node_id),
-                            name,
-                            span: lifetime.ident.span,
-                            pure_wrt_drop: false,
-                            kind: hir::GenericParamKind::Lifetime { kind },
-                            colon_span: None,
-                            source: hir::GenericParamSource::Generics,
-                        }
-                    },
-                ));
-                debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
-
-                let lifetime_mapping = if in_trait {
-                    Some(
-                        &*self.arena.alloc_from_iter(
-                            collected_lifetime_mapping
-                                .iter()
-                                .map(|(lifetime, def_id)| (**lifetime, *def_id)),
-                        ),
-                    )
-                } else {
-                    None
-                };
-
-                let opaque_ty_item = hir::OpaqueTy {
-                    generics: this.arena.alloc(hir::Generics {
-                        params: generic_params,
-                        predicates: &[],
-                        has_where_clause_predicates: false,
-                        where_clause_span: this.lower_span(span),
-                        span: this.lower_span(span),
-                    }),
-                    bounds: arena_vec![this; future_bound],
-                    origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
-                    lifetime_mapping,
-                    in_trait,
-                };
-
-                trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
-                this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
-            })
-        });
-
-        // As documented above, we need to create the lifetime
-        // arguments to our opaque type. Continuing with our example,
-        // we're creating the type arguments for the return type:
-        //
-        // ```
-        // Bar<'a, 'b, '0, '1, '_>
-        // ```
-        //
-        // For the "input" lifetime parameters, we wish to create
-        // references to the parameters themselves, including the
-        // "implicit" ones created from parameter types (`'a`, `'b`,
-        // '`0`, `'1`).
-        //
-        // For the "output" lifetime parameters, we just want to
-        // generate `'_`.
-        let generic_args = self.arena.alloc_from_iter(
-            collected_lifetime_mapping
-                .iter()
-                .map(|(lifetime, _)| hir::GenericArg::Lifetime(*lifetime)),
+                arena_vec![this; future_bound]
+            },
         );
 
-        // Create the `Foo<...>` reference itself. Note that the `type
-        // Foo = impl Trait` is, internally, created as a child of the
-        // async fn, so the *type parameters* are inherited. It's
-        // only the lifetime parameters that we must supply.
-        let opaque_ty_ref = hir::TyKind::OpaqueDef(
-            hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
-            generic_args,
-            in_trait,
-        );
         let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
         hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
     }
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
index 3989fc48619..0e0bdf17389 100644
--- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs
+++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
@@ -1,6 +1,6 @@
 use super::ResolverAstLoweringExt;
 use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
-use rustc_ast::{FnRetTy, GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind};
+use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind};
 use rustc_hir::def::LifetimeRes;
 use rustc_middle::span_bug;
 use rustc_middle::ty::ResolverAstLowering;
@@ -94,12 +94,6 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
     }
 }
 
-pub fn lifetimes_in_ret_ty(resolver: &ResolverAstLowering, ret_ty: &FnRetTy) -> Vec<Lifetime> {
-    let mut visitor = LifetimeCollectVisitor::new(resolver);
-    visitor.visit_fn_ret_ty(ret_ty);
-    visitor.collected_lifetimes
-}
-
 pub fn lifetimes_in_bounds(
     resolver: &ResolverAstLowering,
     bounds: &GenericBounds,
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 053f5730f6e..7bded6b1d82 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -78,11 +78,11 @@ impl AllocFnFactory<'_, '_> {
         };
         let args = method.inputs.iter().map(|ty| self.arg_ty(ty, &mut abi_args, &mut mk)).collect();
         let result = self.call_allocator(method.name, args);
-        let (output_ty, output_expr) = self.ret_ty(&method.output, result);
+        let output_ty = self.ret_ty(&method.output);
         let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
         let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
         let sig = FnSig { decl, header, span: self.span };
-        let body = Some(self.cx.block_expr(output_expr));
+        let body = Some(self.cx.block_expr(result));
         let kind = ItemKind::Fn(Box::new(Fn {
             defaultness: ast::Defaultness::Final,
             sig,
@@ -140,8 +140,7 @@ impl AllocFnFactory<'_, '_> {
             AllocatorTy::Ptr => {
                 let ident = ident();
                 args.push(self.cx.param(self.span, ident, self.ptr_u8()));
-                let arg = self.cx.expr_ident(self.span, ident);
-                self.cx.expr_cast(self.span, arg, self.ptr_u8())
+                self.cx.expr_ident(self.span, ident)
             }
 
             AllocatorTy::Usize => {
@@ -156,18 +155,11 @@ impl AllocFnFactory<'_, '_> {
         }
     }
 
-    fn ret_ty(&self, ty: &AllocatorTy, expr: P<Expr>) -> (P<Ty>, P<Expr>) {
+    fn ret_ty(&self, ty: &AllocatorTy) -> P<Ty> {
         match *ty {
-            AllocatorTy::ResultPtr => {
-                // We're creating:
-                //
-                //      #expr as *mut u8
-
-                let expr = self.cx.expr_cast(self.span, expr, self.ptr_u8());
-                (self.ptr_u8(), expr)
-            }
+            AllocatorTy::ResultPtr => self.ptr_u8(),
 
-            AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(ThinVec::new())), expr),
+            AllocatorTy::Unit => self.cx.ty(self.span, TyKind::Tup(ThinVec::new())),
 
             AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
                 panic!("can't convert `AllocatorTy` to an output")
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 64c6d17469b..e7c3906d977 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -441,7 +441,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             LocalRef::Place(place) => place,
             LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
             LocalRef::Operand(..) => {
-                if place_ref.has_deref() {
+                if place_ref.is_indirect_first_projection() {
                     base = 1;
                     let cg_base = self.codegen_consume(
                         bx,
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 0ef5522729a..a6edc6fb363 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -247,7 +247,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
             AddressOf(_, place) => {
                 // Figure out whether this is an addr_of of an already raw place.
-                let place_base_raw = if place.has_deref() {
+                let place_base_raw = if place.is_indirect_first_projection() {
                     let ty = self.frame().body.local_decls[place.local].ty;
                     ty.is_unsafe_ptr()
                 } else {
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index d4532873854..60dc9b20077 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -391,6 +391,10 @@ fn run_compiler(
                         pretty::print_after_hir_lowering(tcx, *ppm);
                         Ok(())
                     })?;
+
+                    // Make sure the `output_filenames` query is run for its side
+                    // effects of writing the dep-info and reporting errors.
+                    queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(()));
                 } else {
                     let krate = queries.parse()?.steal();
                     pretty::print_after_parsing(sess, &krate, *ppm);
diff --git a/compiler/rustc_error_codes/src/error_codes/E0577.md b/compiler/rustc_error_codes/src/error_codes/E0577.md
index eba2d3b1417..383ca61f6c4 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0577.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0577.md
@@ -3,7 +3,7 @@ Something other than a module was found in visibility scope.
 Erroneous code example:
 
 ```compile_fail,E0577,edition2018
-pub struct Sea;
+pub enum Sea {}
 
 pub (in crate::Sea) struct Shark; // error!
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index bc05565fed4..c6f8d1e211d 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2675,7 +2675,7 @@ pub struct OpaqueTy<'hir> {
     ///
     /// This mapping associated a captured lifetime (first parameter) with the new
     /// early-bound lifetime that was generated for the opaque.
-    pub lifetime_mapping: Option<&'hir [(Lifetime, LocalDefId)]>,
+    pub lifetime_mapping: Option<&'hir [(&'hir Lifetime, LocalDefId)]>,
     /// Whether the opaque is a return-position impl trait (or async future)
     /// originating from a trait method. This makes it so that the opaque is
     /// lowered as an associated type.
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 2950ce683a3..83220be6883 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -82,7 +82,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                 tcx,
                 def_id,
                 lifetime_mapping.iter().map(|(lifetime, def_id)| {
-                    (*lifetime, (*def_id, lifetime.ident.name, lifetime.ident.span))
+                    (**lifetime, (*def_id, lifetime.ident.name, lifetime.ident.span))
                 }),
                 tcx.generics_of(def_id.to_def_id()),
                 &mut predicates,
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index c290462fc20..2c9d212a6a6 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -58,6 +58,7 @@ use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::GenericArgKind;
+use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
 use rustc_session::config::ExpectedValues;
@@ -68,6 +69,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, InnerSpan, Span};
 use rustc_target::abi::Abi;
 use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
 
 use crate::nonstandard_style::{method_context, MethodLateContext};
@@ -673,6 +675,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
         if ty.is_copy_modulo_regions(cx.tcx, param_env) {
             return;
         }
+        if type_implements_negative_copy_modulo_regions(cx.tcx, ty, param_env) {
+            return;
+        }
 
         // We shouldn't recommend implementing `Copy` on stateful things,
         // such as iterators.
@@ -708,6 +713,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
     }
 }
 
+/// Check whether a `ty` has a negative `Copy` implementation, ignoring outlives constraints.
+fn type_implements_negative_copy_modulo_regions<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: Ty<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+) -> bool {
+    let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]);
+    let pred = ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Negative };
+    let obligation = traits::Obligation {
+        cause: traits::ObligationCause::dummy(),
+        param_env,
+        recursion_depth: 0,
+        predicate: ty::Binder::dummy(pred).to_predicate(tcx),
+    };
+
+    tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
+}
+
 declare_lint! {
     /// The `missing_debug_implementations` lint detects missing
     /// implementations of [`fmt::Debug`] for public types.
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 70311a5c576..25982a45853 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1496,7 +1496,7 @@ pub enum InvalidNanComparisons {
     #[diag(lint_invalid_nan_comparisons_eq_ne)]
     EqNe {
         #[subdiagnostic]
-        suggestion: InvalidNanComparisonsSuggestion,
+        suggestion: Option<InvalidNanComparisonsSuggestion>,
     },
     #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)]
     LtLeGtGe,
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 24bc16af2ee..1ba746eddeb 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -572,32 +572,36 @@ fn lint_nan<'tcx>(
     }
 
     fn eq_ne(
+        cx: &LateContext<'_>,
         e: &hir::Expr<'_>,
         l: &hir::Expr<'_>,
         r: &hir::Expr<'_>,
         f: impl FnOnce(Span, Span) -> InvalidNanComparisonsSuggestion,
     ) -> InvalidNanComparisons {
-        let suggestion =
+        // FIXME(#72505): This suggestion can be restored if `f{32,64}::is_nan` is made const.
+        let suggestion = (!cx.tcx.hir().is_inside_const_context(e.hir_id)).then(|| {
             if let Some(l_span) = l.span.find_ancestor_inside(e.span) &&
-                let Some(r_span) = r.span.find_ancestor_inside(e.span) {
+                let Some(r_span) = r.span.find_ancestor_inside(e.span)
+            {
                 f(l_span, r_span)
             } else {
                 InvalidNanComparisonsSuggestion::Spanless
-            };
+            }
+        });
 
         InvalidNanComparisons::EqNe { suggestion }
     }
 
     let lint = match binop.node {
         hir::BinOpKind::Eq | hir::BinOpKind::Ne if is_nan(cx, l) => {
-            eq_ne(e, l, r, |l_span, r_span| InvalidNanComparisonsSuggestion::Spanful {
+            eq_ne(cx, e, l, r, |l_span, r_span| InvalidNanComparisonsSuggestion::Spanful {
                 nan_plus_binop: l_span.until(r_span),
                 float: r_span.shrink_to_hi(),
                 neg: (binop.node == hir::BinOpKind::Ne).then(|| r_span.shrink_to_lo()),
             })
         }
         hir::BinOpKind::Eq | hir::BinOpKind::Ne if is_nan(cx, r) => {
-            eq_ne(e, l, r, |l_span, r_span| InvalidNanComparisonsSuggestion::Spanful {
+            eq_ne(cx, e, l, r, |l_span, r_span| InvalidNanComparisonsSuggestion::Spanful {
                 nan_plus_binop: l_span.shrink_to_hi().to(r_span),
                 float: l_span.shrink_to_hi(),
                 neg: (binop.node == hir::BinOpKind::Ne).then(|| l_span.shrink_to_lo()),
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index c1f87d79b83..ddb5e248cdc 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1592,14 +1592,13 @@ impl<'tcx> Place<'tcx> {
         self.projection.iter().any(|elem| elem.is_indirect())
     }
 
-    /// If MirPhase >= Derefered and if projection contains Deref,
-    /// It's guaranteed to be in the first place
-    pub fn has_deref(&self) -> bool {
-        // To make sure this is not accidentally used in wrong mir phase
-        debug_assert!(
-            self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
-        );
-        self.projection.first() == Some(&PlaceElem::Deref)
+    /// Returns `true` if this `Place`'s first projection is `Deref`.
+    ///
+    /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
+    /// `Deref` projections can only occur as the first projection. In that case this method
+    /// is equivalent to `is_indirect`, but faster.
+    pub fn is_indirect_first_projection(&self) -> bool {
+        self.as_ref().is_indirect_first_projection()
     }
 
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -1672,9 +1671,16 @@ impl<'tcx> PlaceRef<'tcx> {
         self.projection.iter().any(|elem| elem.is_indirect())
     }
 
-    /// If MirPhase >= Derefered and if projection contains Deref,
-    /// It's guaranteed to be in the first place
-    pub fn has_deref(&self) -> bool {
+    /// Returns `true` if this `Place`'s first projection is `Deref`.
+    ///
+    /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
+    /// `Deref` projections can only occur as the first projection. In that case this method
+    /// is equivalent to `is_indirect`, but faster.
+    pub fn is_indirect_first_projection(&self) -> bool {
+        // To make sure this is not accidentally used in wrong mir phase
+        debug_assert!(
+            self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
+        );
         self.projection.first() == Some(&PlaceElem::Deref)
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 8d78ec04821..17bb8fc37ad 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -839,7 +839,7 @@ impl Map {
         tail_elem: Option<TrackElem>,
         f: &mut impl FnMut(ValueIndex),
     ) {
-        if place.has_deref() {
+        if place.is_indirect_first_projection() {
             // We do not track indirect places.
             return;
         }
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index d9e7339f1b2..75473ca53fb 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
         let basic_blocks = body.basic_blocks.as_mut();
         let local_decls = &body.local_decls;
         let needs_retag = |place: &Place<'tcx>| {
-            !place.has_deref() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
+            !place.is_indirect_first_projection() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
                 && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
                 && !local_decls[place.local].is_deref_temp()
         };
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index 47d9f52bfb5..9a3798eea3b 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -154,7 +154,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
         if let Operand::Move(place) = *operand
             // A move out of a projection of a copy is equivalent to a copy of the original projection.
-            && !place.has_deref()
+            && !place.is_indirect_first_projection()
             && !self.fully_moved.contains(place.local)
         {
             *operand = Operand::Copy(place);
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 734321e97d8..1ffc4597772 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -338,38 +338,9 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
         return shim::build_adt_ctor(tcx, def.to_def_id());
     }
 
-    let context = tcx
-        .hir()
-        .body_const_context(def)
-        .expect("mir_for_ctfe should not be used for runtime functions");
-
     let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
 
     let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::Const);
-
-    match context {
-        // Do not const prop functions, either they get executed at runtime or exported to metadata,
-        // so we run const prop on them, or they don't, in which case we const evaluate some control
-        // flow paths of the function and any errors in those paths will get emitted as const eval
-        // errors.
-        hir::ConstContext::ConstFn => {}
-        // Static items always get evaluated, so we can just let const eval see if any erroneous
-        // control flow paths get executed.
-        hir::ConstContext::Static(_) => {}
-        // Associated constants get const prop run so we detect common failure situations in the
-        // crate that defined the constant.
-        // Technically we want to not run on regular const items, but oli-obk doesn't know how to
-        // conveniently detect that at this point without looking at the HIR.
-        hir::ConstContext::Const => {
-            pm::run_passes(
-                tcx,
-                &mut body,
-                &[&const_prop::ConstProp],
-                Some(MirPhase::Runtime(RuntimePhase::Optimized)),
-            );
-        }
-    }
-
     pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None);
 
     body
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 2f432799022..80d6a47ff53 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -278,7 +278,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 };
                 match self.r.resolve_path(
                     &segments,
-                    Some(TypeNS),
+                    None,
                     parent_scope,
                     finalize.then(|| Finalize::new(id, path.span)),
                     None,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 7b590d16d8c..65fa077dcd9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -904,9 +904,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                             sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
                             &sig.decl.output,
                         );
+
+                        if let Some((async_node_id, span)) = sig.header.asyncness.opt_return_id() {
+                            this.record_lifetime_params_for_impl_trait(async_node_id, span);
+                        }
                     },
                 );
-                self.record_lifetime_params_for_async(fn_id, sig.header.asyncness.opt_return_id());
                 return;
             }
             FnKind::Fn(..) => {
@@ -942,12 +945,14 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                                         .iter()
                                         .map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)),
                                     &declaration.output,
-                                )
+                                );
+
+                                if let Some((async_node_id, span)) = async_node_id {
+                                    this.record_lifetime_params_for_impl_trait(async_node_id, span);
+                                }
                             },
                         );
 
-                        this.record_lifetime_params_for_async(fn_id, async_node_id);
-
                         if let Some(body) = body {
                             // Ignore errors in function bodies if this is rustdoc
                             // Be sure not to set this until the function signature has been resolved.
@@ -1694,6 +1699,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // Leave the responsibility to create the `LocalDefId` to lowering.
         let param = self.r.next_node_id();
         let res = LifetimeRes::Fresh { param, binder };
+        self.record_lifetime_param(param, res);
 
         // Record the created lifetime parameter so lowering can pick it up and add it to HIR.
         self.r
@@ -3944,11 +3950,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
         if path.len() > 1
             && let Some(res) = result.full_res()
+            && let Some((&last_segment, prev_segs)) = path.split_last()
+            && prev_segs.iter().all(|seg| !seg.has_generic_args)
             && res != Res::Err
             && path[0].ident.name != kw::PathRoot
             && path[0].ident.name != kw::DollarCrate
         {
-            let last_segment = *path.last().unwrap();
             let unqualified_result = {
                 match self.resolve_path(&[last_segment], Some(ns), None) {
                     PathResult::NonModule(path_res) => path_res.expect_full_res(),
@@ -4325,39 +4332,32 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         )
     }
 
-    /// Construct the list of in-scope lifetime parameters for async lowering.
+    /// Construct the list of in-scope lifetime parameters for impl trait lowering.
     /// We include all lifetime parameters, either named or "Fresh".
     /// The order of those parameters does not matter, as long as it is
     /// deterministic.
-    fn record_lifetime_params_for_async(
-        &mut self,
-        fn_id: NodeId,
-        async_node_id: Option<(NodeId, Span)>,
-    ) {
-        if let Some((async_node_id, span)) = async_node_id {
-            let mut extra_lifetime_params =
-                self.r.extra_lifetime_params_map.get(&fn_id).cloned().unwrap_or_default();
-            for rib in self.lifetime_ribs.iter().rev() {
-                extra_lifetime_params.extend(
-                    rib.bindings.iter().map(|(&ident, &(node_id, res))| (ident, node_id, res)),
-                );
-                match rib.kind {
-                    LifetimeRibKind::Item => break,
-                    LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
-                        if let Some(earlier_fresh) = self.r.extra_lifetime_params_map.get(&binder) {
-                            extra_lifetime_params.extend(earlier_fresh);
-                        }
-                    }
-                    LifetimeRibKind::Generics { .. } => {}
-                    _ => {
-                        // We are in a function definition. We should only find `Generics`
-                        // and `AnonymousCreateParameter` inside the innermost `Item`.
-                        span_bug!(span, "unexpected rib kind: {:?}", rib.kind)
+    fn record_lifetime_params_for_impl_trait(&mut self, impl_trait_node_id: NodeId, span: Span) {
+        let mut extra_lifetime_params = vec![];
+
+        for rib in self.lifetime_ribs.iter().rev() {
+            extra_lifetime_params
+                .extend(rib.bindings.iter().map(|(&ident, &(node_id, res))| (ident, node_id, res)));
+            match rib.kind {
+                LifetimeRibKind::Item => break,
+                LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
+                    if let Some(earlier_fresh) = self.r.extra_lifetime_params_map.get(&binder) {
+                        extra_lifetime_params.extend(earlier_fresh);
                     }
                 }
+                LifetimeRibKind::Generics { .. } => {}
+                _ => {
+                    // We are in a function definition. We should only find `Generics`
+                    // and `AnonymousCreateParameter` inside the innermost `Item`.
+                    span_bug!(span, "unexpected rib kind: {:?}", rib.kind)
+                }
             }
-            self.r.extra_lifetime_params_map.insert(async_node_id, extra_lifetime_params);
         }
+        self.r.extra_lifetime_params_map.insert(impl_trait_node_id, extra_lifetime_params);
     }
 
     fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option<Res> {
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index c4bdec0ee28..e377843cdb4 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1063,3 +1063,34 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::BoundTy {
         BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) }
     }
 }
+
+impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
+    type T = stable_mir::ty::Allocation;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let size = self.size();
+        let mut bytes: Vec<Option<u8>> = self
+            .inspect_with_uninit_and_ptr_outside_interpreter(0..size.bytes_usize())
+            .iter()
+            .copied()
+            .map(Some)
+            .collect();
+        for (i, b) in bytes.iter_mut().enumerate() {
+            if !self.init_mask().get(rustc_target::abi::Size::from_bytes(i)) {
+                *b = None;
+            }
+        }
+        stable_mir::ty::Allocation {
+            bytes: bytes,
+            provenance: {
+                let mut ptrs = Vec::new();
+                for (size, prov) in self.provenance().ptrs().iter() {
+                    ptrs.push((size.bytes_usize(), opaque(prov)));
+                }
+                stable_mir::ty::ProvenanceMap { ptrs }
+            },
+            align: self.align.bytes(),
+            mutability: self.mutability.stable(tables),
+        }
+    }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 025225b8d19..df28fc4eed9 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -242,3 +242,25 @@ pub struct BoundTy {
     pub var: usize,
     pub kind: BoundTyKind,
 }
+
+pub type Bytes = Vec<Option<u8>>;
+pub type Size = usize;
+pub type Prov = Opaque;
+pub type Align = u64;
+pub type InitMaskMaterialized = Vec<u64>;
+
+/// Stores the provenance information of pointers stored in memory.
+#[derive(Clone, Debug)]
+pub struct ProvenanceMap {
+    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
+    /// bytes. Two entries in this map are always at least a pointer size apart.
+    pub ptrs: Vec<(Size, Prov)>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Allocation {
+    pub bytes: Bytes,
+    pub provenance: ProvenanceMap,
+    pub align: Align,
+    pub mutability: Mutability,
+}
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 5ec9ddfe64a..60c49f665a6 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -391,13 +391,19 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             debug!("rerunning goal to check result is stable");
             self.search_graph.reset_encountered_overflow(encountered_overflow);
             let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
-            let new_canonical_response = EvalCtxt::evaluate_canonical_goal(
+            let Ok(new_canonical_response) = EvalCtxt::evaluate_canonical_goal(
                 self.tcx(),
                 self.search_graph,
                 canonical_goal,
                 // FIXME(-Ztrait-solver=next): we do not track what happens in `evaluate_canonical_goal`
                 &mut ProofTreeBuilder::new_noop(),
-            )?;
+            ) else {
+                bug!(
+                    "goal went from {certainty:?} to error: re-canonicalized goal={canonical_goal:#?} \
+                    first_response={canonical_response:#?},
+                    second response was error"
+                );
+            };
             // We only check for modulo regions as we convert all regions in
             // the input to new existentials, even if they're expected to be
             // `'static` or a placeholder region.
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index a6d6230d3a6..d7ca9c22dad 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -86,6 +86,46 @@
 /// }
 /// ```
 ///
+/// If we `derive`:
+///
+/// ```
+/// #[derive(Copy, Clone)]
+/// struct Generate<T>(fn() -> T);
+/// ```
+///
+/// the auto-derived implementations will have unnecessary `T: Copy` and `T: Clone` bounds:
+///
+/// ```
+/// # struct Generate<T>(fn() -> T);
+///
+/// // Automatically derived
+/// impl<T: Copy> Copy for Generate<T> { }
+///
+/// // Automatically derived
+/// impl<T: Clone> Clone for Generate<T> {
+///     fn clone(&self) -> Generate<T> {
+///         Generate(Clone::clone(&self.0))
+///     }
+/// }
+/// ```
+///
+/// The bounds are unnecessary because clearly the function itself should be
+/// copy- and cloneable even if its return type is not:
+///
+/// ```compile_fail,E0599
+/// #[derive(Copy, Clone)]
+/// struct Generate<T>(fn() -> T);
+///
+/// struct NotCloneable;
+///
+/// fn generate_not_cloneable() -> NotCloneable {
+///     NotCloneable
+/// }
+///
+/// Generate(generate_not_cloneable).clone(); // error: trait bounds were not satisfied
+/// // Note: With the manual implementations the above line will compile.
+/// ```
+///
 /// ## Additional implementors
 ///
 /// In addition to the [implementors listed below][impls],
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index de638552fa3..be04dfe042e 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -361,6 +361,12 @@ macro_rules! impl_fold_via_try_fold {
     (rfold -> try_rfold) => {
         impl_fold_via_try_fold! { @internal rfold -> try_rfold }
     };
+    (spec_fold -> spec_try_fold) => {
+        impl_fold_via_try_fold! { @internal spec_fold -> spec_try_fold }
+    };
+    (spec_rfold -> spec_try_rfold) => {
+        impl_fold_via_try_fold! { @internal spec_rfold -> spec_try_rfold }
+    };
     (@internal $fold:ident -> $try_fold:ident) => {
         #[inline]
         fn $fold<AAA, FFF>(mut self, init: AAA, fold: FFF) -> AAA
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index 182d9f758ad..4c8af4eba78 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -379,4 +379,66 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
     fn nth_back(&mut self, n: usize) -> Option<I::Item> {
         (**self).nth_back(n)
     }
+    fn rfold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.spec_rfold(init, f)
+    }
+    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        self.spec_try_rfold(init, f)
+    }
+}
+
+/// Helper trait to specialize `rfold` and `rtry_fold` for `&mut I where I: Sized`
+trait DoubleEndedIteratorRefSpec: DoubleEndedIterator {
+    fn spec_rfold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B;
+
+    fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>;
+}
+
+impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIteratorRefSpec for &mut I {
+    default fn spec_rfold<B, F>(self, init: B, mut f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        let mut accum = init;
+        while let Some(x) = self.next_back() {
+            accum = f(accum, x);
+        }
+        accum
+    }
+
+    default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        let mut accum = init;
+        while let Some(x) = self.next_back() {
+            accum = f(accum, x)?;
+        }
+        try { accum }
+    }
+}
+
+impl<I: DoubleEndedIterator> DoubleEndedIteratorRefSpec for &mut I {
+    impl_fold_via_try_fold! { spec_rfold -> spec_try_rfold }
+
+    fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        (**self).try_rfold(init, f)
+    }
 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 98835228308..cecc120a6e2 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -4018,4 +4018,66 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         (**self).nth(n)
     }
+    fn fold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        self.spec_fold(init, f)
+    }
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        self.spec_try_fold(init, f)
+    }
+}
+
+/// Helper trait to specialize `fold` and `try_fold` for `&mut I where I: Sized`
+trait IteratorRefSpec: Iterator {
+    fn spec_fold<B, F>(self, init: B, f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B;
+
+    fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>;
+}
+
+impl<I: Iterator + ?Sized> IteratorRefSpec for &mut I {
+    default fn spec_fold<B, F>(self, init: B, mut f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        let mut accum = init;
+        while let Some(x) = self.next() {
+            accum = f(accum, x);
+        }
+        accum
+    }
+
+    default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        let mut accum = init;
+        while let Some(x) = self.next() {
+            accum = f(accum, x)?;
+        }
+        try { accum }
+    }
+}
+
+impl<I: Iterator> IteratorRefSpec for &mut I {
+    impl_fold_via_try_fold! { spec_fold -> spec_try_fold }
+
+    fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Output = B>,
+    {
+        (**self).try_fold(init, f)
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 137bd9c9451..bc011a6c354 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1170,7 +1170,7 @@ fn referent_used_exactly_once<'tcx>(
         && let [location] = *local_assignments(mir, local).as_slice()
         && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
         && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
-        && !place.has_deref()
+        && !place.is_indirect_first_projection()
         // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
         && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
     {
diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs
index 5f8eaebf531..67b745373f0 100644
--- a/src/tools/tidy/src/fluent_alphabetical.rs
+++ b/src/tools/tidy/src/fluent_alphabetical.rs
@@ -23,7 +23,7 @@ fn check_alphabetic(filename: &str, fluent: &str, bad: &mut bool) {
                 tidy_error!(
                     bad,
                     "{filename}: message `{}` appears before `{}`, but is alphabetically later than it
-run tidy with `--bless` to sort the file correctly",
+run `./x.py test tidy --bless` to sort the file correctly",
                     name.as_str(),
                     next.as_str()
                 );
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 930b7408390..3414924007b 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -10,7 +10,7 @@ use std::path::{Path, PathBuf};
 
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1893;
+const ISSUES_ENTRY_LIMIT: usize = 1891;
 const ROOT_ENTRY_LIMIT: usize = 866;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
diff --git a/tests/run-make/pretty-print-with-dep-file/Makefile b/tests/run-make/pretty-print-with-dep-file/Makefile
new file mode 100644
index 00000000000..fa8089eb6a5
--- /dev/null
+++ b/tests/run-make/pretty-print-with-dep-file/Makefile
@@ -0,0 +1,9 @@
+include ../tools.mk
+
+all:
+	$(RUSTC) --emit=dep-info -Zunpretty=expanded with-dep.rs
+	$(CGREP) "with-dep.rs" < $(TMPDIR)/with-dep.d
+	-rm $(TMPDIR)/with-dep.d
+
+	$(RUSTC) --emit=dep-info -Zunpretty=normal with-dep.rs
+	! test -f $(TMPDIR)/with-dep.d
diff --git a/tests/run-make/pretty-print-with-dep-file/with-dep.rs b/tests/run-make/pretty-print-with-dep-file/with-dep.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/tests/run-make/pretty-print-with-dep-file/with-dep.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/tests/rustdoc-gui/scrape-examples-toggle.goml b/tests/rustdoc-gui/scrape-examples-toggle.goml
index 9cec6d2bbe8..f742b3186e5 100644
--- a/tests/rustdoc-gui/scrape-examples-toggle.goml
+++ b/tests/rustdoc-gui/scrape-examples-toggle.goml
@@ -28,18 +28,18 @@ define-function: (
 
 call-function: ("check-color", {
     "theme": "ayu",
-    "toggle_line_color": "rgb(153, 153, 153)",
-    "toggle_line_hover_color": "rgb(197, 197, 197)",
+    "toggle_line_color": "#999",
+    "toggle_line_hover_color": "#c5c5c5",
 })
 call-function: ("check-color", {
     "theme": "dark",
-    "toggle_line_color": "rgb(153, 153, 153)",
-    "toggle_line_hover_color": "rgb(197, 197, 197)",
+    "toggle_line_color": "#999",
+    "toggle_line_hover_color": "#c5c5c5",
 })
 call-function: ("check-color", {
     "theme": "light",
-    "toggle_line_color": "rgb(204, 204, 204)",
-    "toggle_line_hover_color": "rgb(153, 153, 153)",
+    "toggle_line_color": "#ccc",
+    "toggle_line_hover_color": "#999",
 })
 
 // Toggling all docs will close additional examples
diff --git a/tests/ui/issues/issue-100605.rs b/tests/ui/issues/issue-100605.rs
deleted file mode 100644
index 917a45c15bb..00000000000
--- a/tests/ui/issues/issue-100605.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-fn takes_option(_arg: Option<&String>) {}
-
-fn main() {
-    takes_option(&None); //~ ERROR 4:18: 4:23: mismatched types [E0308]
-
-    let x = String::from("x");
-    let res = Some(x);
-    takes_option(&res); //~ ERROR 8:18: 8:22: mismatched types [E0308]
-}
diff --git a/tests/ui/lint/invalid-nan-comparison.stderr b/tests/ui/lint/invalid-nan-comparison.stderr
index 054c06d38b3..f2d55c107ba 100644
--- a/tests/ui/lint/invalid-nan-comparison.stderr
+++ b/tests/ui/lint/invalid-nan-comparison.stderr
@@ -5,11 +5,6 @@ LL | const TEST: bool = 5f32 == f32::NAN;
    |                    ^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(invalid_nan_comparisons)]` on by default
-help: use `f32::is_nan()` or `f64::is_nan()` instead
-   |
-LL - const TEST: bool = 5f32 == f32::NAN;
-LL + const TEST: bool = 5f32.is_nan();
-   |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
   --> $DIR/invalid-nan-comparison.rs:14:5
diff --git a/tests/ui/lint/missing-copy-implementations-negative-copy.rs b/tests/ui/lint/missing-copy-implementations-negative-copy.rs
new file mode 100644
index 00000000000..b29d2209fa9
--- /dev/null
+++ b/tests/ui/lint/missing-copy-implementations-negative-copy.rs
@@ -0,0 +1,15 @@
+// Regression test for issue #101980.
+// Ensure that we don't suggest impl'ing `Copy` for a type if it already impl's `!Copy`.
+
+// check-pass
+
+#![feature(negative_impls)]
+#![deny(missing_copy_implementations)]
+
+pub struct Struct {
+    pub field: i32,
+}
+
+impl !Copy for Struct {}
+
+fn main() {}
diff --git a/tests/ui/resolve/issue-114433-invalid-unused-qualifications-suggestion.rs b/tests/ui/resolve/issue-114433-invalid-unused-qualifications-suggestion.rs
new file mode 100644
index 00000000000..83349dd3350
--- /dev/null
+++ b/tests/ui/resolve/issue-114433-invalid-unused-qualifications-suggestion.rs
@@ -0,0 +1,10 @@
+#![deny(unused_qualifications)]
+// check-pass
+fn bar() {
+    match Option::<Option<()>>::None {
+        Some(v) => {}
+        None => {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/resolve/unresolved-segments-visibility.rs b/tests/ui/resolve/unresolved-segments-visibility.rs
new file mode 100644
index 00000000000..c26171f75d2
--- /dev/null
+++ b/tests/ui/resolve/unresolved-segments-visibility.rs
@@ -0,0 +1,11 @@
+// Check that we do not ICE due to unresolved segments in visibility path.
+#![crate_type = "lib"]
+
+extern crate alloc as b;
+
+mod foo {
+    mod bar {
+        pub(in b::string::String::newy) extern crate alloc as e;
+        //~^ ERROR failed to resolve: `String` is a struct, not a module [E0433]
+    }
+}
diff --git a/tests/ui/resolve/unresolved-segments-visibility.stderr b/tests/ui/resolve/unresolved-segments-visibility.stderr
new file mode 100644
index 00000000000..0a11549cdbf
--- /dev/null
+++ b/tests/ui/resolve/unresolved-segments-visibility.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: `String` is a struct, not a module
+  --> $DIR/unresolved-segments-visibility.rs:8:27
+   |
+LL |         pub(in b::string::String::newy) extern crate alloc as e;
+   |                           ^^^^^^ `String` is a struct, not a module
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/span/visibility-ty-params.rs b/tests/ui/span/visibility-ty-params.rs
index d77febe0aa2..11c2cf44cb4 100644
--- a/tests/ui/span/visibility-ty-params.rs
+++ b/tests/ui/span/visibility-ty-params.rs
@@ -4,7 +4,7 @@ macro_rules! m {
 
 struct S<T>(T);
 m!{ S<u8> } //~ ERROR unexpected generic arguments in path
-            //~| ERROR expected module, found struct `S`
+            //~| ERROR failed to resolve: `S` is a struct, not a module [E0433]
 
 mod m {
     m!{ m<> } //~ ERROR unexpected generic arguments in path
diff --git a/tests/ui/span/visibility-ty-params.stderr b/tests/ui/span/visibility-ty-params.stderr
index 067893fd22d..97d05c4644e 100644
--- a/tests/ui/span/visibility-ty-params.stderr
+++ b/tests/ui/span/visibility-ty-params.stderr
@@ -4,11 +4,11 @@ error: unexpected generic arguments in path
 LL | m!{ S<u8> }
    |      ^^^^
 
-error[E0577]: expected module, found struct `S`
+error[E0433]: failed to resolve: `S` is a struct, not a module
   --> $DIR/visibility-ty-params.rs:6:5
    |
 LL | m!{ S<u8> }
-   |     ^^^^^ not a module
+   |     ^ `S` is a struct, not a module
 
 error: unexpected generic arguments in path
   --> $DIR/visibility-ty-params.rs:10:10
@@ -18,4 +18,4 @@ LL |     m!{ m<> }
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0577`.
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/type/option-ref-advice.rs b/tests/ui/type/option-ref-advice.rs
new file mode 100644
index 00000000000..2dcee5a2eb9
--- /dev/null
+++ b/tests/ui/type/option-ref-advice.rs
@@ -0,0 +1,11 @@
+// Regression test for https://github.com/rust-lang/rust/issues/100605
+
+fn takes_option(_arg: Option<&String>) {}
+
+fn main() {
+    takes_option(&None); //~ ERROR 6:18: 6:23: mismatched types [E0308]
+
+    let x = String::from("x");
+    let res = Some(x);
+    takes_option(&res); //~ ERROR 10:18: 10:22: mismatched types [E0308]
+}
diff --git a/tests/ui/issues/issue-100605.stderr b/tests/ui/type/option-ref-advice.stderr
index 6f11f44755a..d4dbef3013f 100644
--- a/tests/ui/issues/issue-100605.stderr
+++ b/tests/ui/type/option-ref-advice.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-100605.rs:4:18
+  --> $DIR/option-ref-advice.rs:6:18
    |
 LL |     takes_option(&None);
    |     ------------ ^^^^^ expected `Option<&String>`, found `&Option<_>`
@@ -9,7 +9,7 @@ LL |     takes_option(&None);
    = note:   expected enum `Option<&String>`
            found reference `&Option<_>`
 note: function defined here
-  --> $DIR/issue-100605.rs:1:4
+  --> $DIR/option-ref-advice.rs:3:4
    |
 LL | fn takes_option(_arg: Option<&String>) {}
    |    ^^^^^^^^^^^^ ---------------------
@@ -20,7 +20,7 @@ LL +     takes_option(None);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/issue-100605.rs:8:18
+  --> $DIR/option-ref-advice.rs:10:18
    |
 LL |     takes_option(&res);
    |     ------------ ^^^^ expected `Option<&String>`, found `&Option<String>`
@@ -30,7 +30,7 @@ LL |     takes_option(&res);
    = note:   expected enum `Option<&String>`
            found reference `&Option<String>`
 note: function defined here
-  --> $DIR/issue-100605.rs:1:4
+  --> $DIR/option-ref-advice.rs:3:4
    |
 LL | fn takes_option(_arg: Option<&String>) {}
    |    ^^^^^^^^^^^^ ---------------------
diff --git a/tests/ui/use/use-self-type.stderr b/tests/ui/use/use-self-type.stderr
index 3da04a851f6..498df34fe32 100644
--- a/tests/ui/use/use-self-type.stderr
+++ b/tests/ui/use/use-self-type.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+error[E0433]: failed to resolve: `Self` cannot be used in imports
   --> $DIR/use-self-type.rs:7:16
    |
 LL |         pub(in Self::f) struct Z;
-   |                ^^^^ `Self` is only available in impls, traits, and type definitions
+   |                ^^^^ `Self` cannot be used in imports
 
 error[E0432]: unresolved import `Self`
   --> $DIR/use-self-type.rs:6:13