about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/tracking_issue.md3
-rw-r--r--compiler/rustc_ast/src/ast.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs84
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs95
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs43
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs25
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/errors.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs7
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs11
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs7
-rw-r--r--compiler/rustc_hir/src/hir.rs1
-rw-r--r--compiler/rustc_hir/src/intravisit.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs3
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp17
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp19
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs2
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs19
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs11
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs6
-rw-r--r--compiler/rustc_passes/src/stability.rs10
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs6
-rw-r--r--compiler/rustc_session/messages.ftl4
-rw-r--r--compiler/rustc_session/src/errors.rs4
-rw-r--r--compiler/rustc_session/src/session.rs12
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs16
-rw-r--r--compiler/rustc_target/src/spec/mod.rs3
-rw-r--r--compiler/rustc_target/src/spec/teeos_base.rs29
-rw-r--r--compiler/rustc_trait_selection/messages.ftl9
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs36
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs71
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/sys/unix/process/process_fuchsia.rs2
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs223
-rw-r--r--library/std/src/sys/unix/process/process_unix/tests.rs25
-rw-r--r--library/std/src/sys/unix/process/process_unsupported.rs2
-rw-r--r--library/std/src/sys/unix/process/process_vxworks.rs2
-rw-r--r--library/std/src/sys/unsupported/process.rs37
-rw-r--r--library/std/src/sys/windows/process.rs2
-rw-r--r--src/bootstrap/compile.rs37
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/bootstrap/llvm.rs20
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md100
-rw-r--r--src/tools/compiletest/src/runtest.rs2
-rw-r--r--tests/run-make/optimization-remarks-dir-pgo/Makefile20
-rw-r--r--tests/run-make/optimization-remarks-dir-pgo/foo.rs6
-rw-r--r--tests/rustdoc-gui/links-color.goml72
-rw-r--r--tests/ui/check-cfg/values-target-json.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr2
-rw-r--r--tests/ui/const-generics/const_trait_fn-issue-88433.rs2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.rs8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.stderr75
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr42
-rw-r--r--tests/ui/const-generics/lifetime-in-const-param.rs9
-rw-r--r--tests/ui/const-generics/lifetime-in-const-param.stderr18
-rw-r--r--tests/ui/consts/const-try.stderr33
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.rs2
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.stderr12
-rw-r--r--tests/ui/generic-associated-types/streaming_iterator.rs3
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.stderr5
-rw-r--r--tests/ui/lto/issue-100772.rs4
-rw-r--r--tests/ui/proc-macro/auxiliary/exports_no_mangle.rs11
-rw-r--r--tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs22
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr28
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr27
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs7
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr23
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs1
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr40
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs6
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr17
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr33
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs2
-rw-r--r--tests/ui/sanitize/issue-111184-generator-witness.rs4
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-requires-lto.rs2
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr2
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs8
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr4
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.rs2
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs46
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr29
123 files changed, 1259 insertions, 718 deletions
diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md
index 00659605071..5f17f30b3b0 100644
--- a/.github/ISSUE_TEMPLATE/tracking_issue.md
+++ b/.github/ISSUE_TEMPLATE/tracking_issue.md
@@ -39,10 +39,13 @@ for larger features an implementation could be broken up into multiple PRs.
 - [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring
       instructions?)
 - [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
+- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure])
 - [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide])
 
 [stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
 [doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs
+[nightly-style-procedure]: https://github.com/rust-lang/style-team/blob/master/nightly-style-procedure.md 
+[Style Guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide
 
 ### Unresolved Questions
 <!--
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f2e90fd8eed..58725a08c7c 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -313,6 +313,16 @@ pub enum TraitBoundModifier {
     MaybeConstMaybe,
 }
 
+impl TraitBoundModifier {
+    pub fn to_constness(self) -> Const {
+        match self {
+            // FIXME(effects) span
+            Self::MaybeConst => Const::Yes(DUMMY_SP),
+            _ => Const::No,
+        }
+    }
+}
+
 /// The AST represents all type param bounds as types.
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index ab55c09465b..a1e62699680 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -207,6 +207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 &sym.path,
                                 ParamMode::Optional,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                                None,
                             );
                             hir::InlineAsmOperand::SymStatic { path, def_id }
                         } else {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 42d0998d162..b23cee14f75 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -100,6 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ParamMode::Optional,
                         ParenthesizedGenericArgs::Err,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     ));
                     let receiver = self.lower_expr(receiver);
                     let args =
@@ -260,6 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     hir::ExprKind::Path(qpath)
                 }
@@ -307,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         )),
                         self.arena
                             .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -1179,6 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a tuple struct.
                     let tuple_struct_pat = hir::PatKind::TupleStruct(
@@ -1198,6 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a unit struct.
                     let unit_struct_pat = hir::PatKind::Path(qpath);
@@ -1222,6 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.path,
                     ParamMode::Optional,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 );
                 let fields_omitted = match &se.rest {
                     StructRest::Base(e) => {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index df73c721ade..7954297900f 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
             allow_gen_future,
             generics_def_id_map: Default::default(),
+            host_param_id: None,
         };
         lctx.with_hir_id_owner(owner, |lctx| f(lctx));
 
@@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             // This is used to track which lifetimes have already been defined,
             // and which need to be replicated when lowering an async fn.
 
-            if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind {
-                lctx.is_in_trait_impl = impl_.of_trait.is_some();
+            match parent_hir.node().expect_item().kind {
+                hir::ItemKind::Impl(impl_) => {
+                    lctx.is_in_trait_impl = impl_.of_trait.is_some();
+                }
+                hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => {
+                    lctx.host_param_id = generics
+                        .params
+                        .iter()
+                        .find(|param| {
+                            parent_hir
+                                .attrs
+                                .get(param.hir_id.local_id)
+                                .iter()
+                                .any(|attr| attr.has_name(sym::rustc_host))
+                        })
+                        .map(|param| param.def_id);
+                }
+                _ => {}
             }
 
             match ctxt {
@@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.lower_generics(ast_generics, *constness, id, &itctx, |this| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(
+                                *constness,
                                 trait_ref,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
                             )
@@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     polarity,
                     defaultness,
                     defaultness_span,
-                    constness: self.lower_constness(*constness),
                     generics,
                     of_trait: trait_ref,
                     self_ty: lowered_ty,
@@ -1363,6 +1380,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         }
 
+        // Desugar `~const` bound in generics into an additional `const host: bool` param
+        // if the effects feature is enabled. This needs to be done before we lower where
+        // clauses since where clauses need to bind to the DefId of the host param
+        let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects {
+            if let Some(param) = generics.params.iter().find(|x| {
+                x.attrs.iter().any(|x| x.has_name(sym::rustc_host))
+            }) {
+                // user has manually specified a `rustc_host` param, in this case, we set
+                // the param id so that lowering logic can use that. But we don't create
+                // another host param, so this gives `None`.
+                self.host_param_id = Some(self.local_def_id(param.id));
+                None
+            } else {
+                let param_node_id = self.next_node_id();
+                let hir_id = self.next_id();
+                let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
+                self.host_param_id = Some(def_id);
+                Some((span, hir_id, def_id))
+            }
+        } else {
+            None
+        };
+
         let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
         predicates.extend(generics.params.iter().filter_map(|param| {
             self.lower_generic_bound_predicate(
@@ -1410,22 +1450,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
         predicates.extend(impl_trait_bounds.into_iter());
 
-        // Desugar `~const` bound in generics into an additional `const host: bool` param
-        // if the effects feature is enabled.
-        if let Const::Yes(span) = constness && self.tcx.features().effects
-            // Do not add host param if it already has it (manually specified)
-            && !params.iter().any(|x| {
-                self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| {
-                    attrs.iter().any(|x| x.has_name(sym::rustc_host))
-                })
-            })
-        {
-            let param_node_id = self.next_node_id();
+        if let Some((span, hir_id, def_id)) = host_param_parts {
             let const_node_id = self.next_node_id();
-            let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
-            let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
+            let anon_const: LocalDefId =
+                self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
 
-            let hir_id = self.next_id();
             let const_id = self.next_id();
             let const_expr_id = self.next_id();
             let bool_id = self.next_id();
@@ -1435,14 +1464,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
 
-            let attrs = self.arena.alloc_from_iter([
-                Attribute {
-                    kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            let attrs = self.arena.alloc_from_iter([Attribute {
+                kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(
+                    sym::rustc_host,
                     span,
-                    id: attr_id,
-                    style: AttrStyle::Outer,
-                },
-            ]);
+                )))),
+                span,
+                id: attr_id,
+                style: AttrStyle::Outer,
+            }]);
             self.attrs.insert(hir_id.local_id, attrs);
 
             let const_body = self.lower_body(|this| {
@@ -1481,7 +1511,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             }),
                         )),
                     )),
-                    default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }),
+                    default: Some(hir::AnonConst {
+                        def_id: anon_const,
+                        hir_id: const_id,
+                        body: const_body,
+                    }),
                 },
                 colon_span: None,
                 pure_wrt_drop: false,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index a8151ccfff3..0aeff22ca9f 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> {
     /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
     /// field from the original parameter 'a to the new parameter 'a1.
     generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
+
+    host_param_id: Option<LocalDefId>,
 }
 
 trait ResolverAstLoweringExt {
@@ -1262,6 +1264,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         span: t.span
                     },
                     itctx,
+                    ast::Const::No,
                 );
                 let bounds = this.arena.alloc_from_iter([bound]);
                 let lifetime_bound = this.elided_dyn_bound(t.span);
@@ -1272,7 +1275,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         let id = self.lower_node_id(t.id);
-        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
+        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None);
         self.ty_path(id, t.span, qpath)
     }
 
@@ -1356,10 +1359,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
                             GenericBound::Trait(
                                 ty,
-                                TraitBoundModifier::None
+                                modifier @ (TraitBoundModifier::None
                                 | TraitBoundModifier::MaybeConst
-                                | TraitBoundModifier::Negative,
-                            ) => Some(this.lower_poly_trait_ref(ty, itctx)),
+                                | TraitBoundModifier::Negative),
+                            ) => {
+                                Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness()))
+                            }
                             // `~const ?Bound` will cause an error during AST validation
                             // anyways, so treat it like `?Bound` as compilation proceeds.
                             GenericBound::Trait(
@@ -1952,7 +1957,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(p, itctx),
+                self.lower_poly_trait_ref(p, itctx, modifier.to_constness()),
                 self.lower_trait_bound_modifier(*modifier),
             ),
             GenericBound::Outlives(lifetime) => {
@@ -2095,8 +2100,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> {
-        let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
+    fn lower_trait_ref(
+        &mut self,
+        constness: ast::Const,
+        p: &TraitRef,
+        itctx: &ImplTraitContext,
+    ) -> hir::TraitRef<'hir> {
+        let path = match self.lower_qpath(
+            p.ref_id,
+            &None,
+            &p.path,
+            ParamMode::Explicit,
+            itctx,
+            Some(constness),
+        ) {
             hir::QPath::Resolved(None, path) => path,
             qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
         };
@@ -2108,10 +2125,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         p: &PolyTraitRef,
         itctx: &ImplTraitContext,
+        constness: ast::Const,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
             self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
-        let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx);
+        let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx);
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
     }
 
@@ -2465,6 +2483,67 @@ struct GenericArgsCtor<'hir> {
 }
 
 impl<'hir> GenericArgsCtor<'hir> {
+    fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) {
+        if !lcx.tcx.features().effects {
+            return;
+        }
+
+        // if bound is non-const, don't add host effect param
+        let ast::Const::Yes(span) = constness else { return };
+
+        let span = lcx.lower_span(span);
+
+        let id = lcx.next_node_id();
+        let hir_id = lcx.next_id();
+        let body = lcx.lower_body(|lcx| {
+            (
+                &[],
+                match constness {
+                    ast::Const::Yes(_) => {
+                        let hir_id = lcx.next_id();
+                        let res =
+                            Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id());
+                        let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved(
+                            None,
+                            lcx.arena.alloc(hir::Path {
+                                span,
+                                res,
+                                segments: arena_vec![lcx; hir::PathSegment::new(Ident {
+                                    name: sym::host,
+                                    span,
+                                }, hir_id, res)],
+                            }),
+                        ));
+                        lcx.expr(span, expr_kind)
+                    }
+                    ast::Const::No => lcx.expr(
+                        span,
+                        hir::ExprKind::Lit(
+                            lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }),
+                        ),
+                    ),
+                },
+            )
+        });
+
+        let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
+        let attr = lcx.arena.alloc(Attribute {
+            kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            span,
+            id: attr_id,
+            style: AttrStyle::Outer,
+        });
+        lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr));
+
+        let def_id =
+            lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span);
+        lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
+        self.args.push(hir::GenericArg::Const(hir::ConstArg {
+            value: hir::AnonConst { def_id, hir_id, body },
+            span,
+        }))
+    }
+
     fn is_empty(&self) -> bool {
         self.args.is_empty()
             && self.bindings.is_empty()
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2509b705639..a30f264bc7d 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                         break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -54,6 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         break hir::PatKind::Path(qpath);
                     }
@@ -64,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
 
                         let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 441282c05b4..899f92a9958 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -23,6 +23,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Path,
         param_mode: ParamMode,
         itctx: &ImplTraitContext,
+        // constness of the impl/bound if this is a trait path
+        constness: Option<ast::Const>,
     ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
@@ -73,6 +75,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         param_mode,
                         parenthesized_generic_args,
                         itctx,
+                        // if this is the last segment, add constness to the trait path
+                        if i == proj_start - 1 { constness } else { None },
                     )
                 },
             )),
@@ -119,6 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 param_mode,
                 ParenthesizedGenericArgs::Err,
                 itctx,
+                None,
             ));
             let qpath = hir::QPath::TypeRelative(ty, hir_segment);
 
@@ -159,6 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     param_mode,
                     ParenthesizedGenericArgs::Err,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 )
             })),
             span: self.lower_span(p.span),
@@ -172,8 +178,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         param_mode: ParamMode,
         parenthesized_generic_args: ParenthesizedGenericArgs,
         itctx: &ImplTraitContext,
+        constness: Option<ast::Const>,
     ) -> hir::PathSegment<'hir> {
-        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
+        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment);
         let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
             match generic_args {
                 GenericArgs::AngleBracketed(data) => {
@@ -231,6 +238,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             )
         };
 
+        if let Some(constness) = constness {
+            generic_args.push_constness(self, constness);
+        }
+
         let has_lifetimes =
             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
 
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 46e6daed21f..47cc5bd52e2 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -320,6 +320,7 @@ impl<'a> DiagnosticHandlers<'a> {
             })
             .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok()));
 
+        let pgo_available = cgcx.opts.cg.profile_use.is_some();
         let data = Box::into_raw(Box::new((cgcx, handler)));
         unsafe {
             let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx);
@@ -333,6 +334,7 @@ impl<'a> DiagnosticHandlers<'a> {
                 // The `as_ref()` is important here, otherwise the `CString` will be dropped
                 // too soon!
                 remark_file.as_ref().map(|dir| dir.as_ptr()).unwrap_or(std::ptr::null()),
+                pgo_available,
             );
             DiagnosticHandlers { data, llcx, old_handler }
         }
@@ -470,6 +472,8 @@ pub(crate) unsafe fn llvm_optimize(
         Some(llvm::SanitizerOptions {
             sanitize_address: config.sanitizer.contains(SanitizerSet::ADDRESS),
             sanitize_address_recover: config.sanitizer_recover.contains(SanitizerSet::ADDRESS),
+            sanitize_cfi: config.sanitizer.contains(SanitizerSet::CFI),
+            sanitize_kcfi: config.sanitizer.contains(SanitizerSet::KCFI),
             sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY),
             sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
             sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
@@ -505,6 +509,7 @@ pub(crate) unsafe fn llvm_optimize(
         &*module.module_llvm.tm,
         to_pass_builder_opt_level(opt_level),
         opt_stage,
+        cgcx.opts.cg.linker_plugin_lto.enabled(),
         config.no_prepopulate_passes,
         config.verify_llvm_ir,
         using_thin_buffers,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 5408481df48..ac6d8f84142 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1512,9 +1512,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
     ) {
-        let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
-        if is_indirect_call && fn_abi.is_some() && self.tcx.sess.is_sanitizer_cfi_enabled() {
-            if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::CFI) {
+        let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
+        if self.tcx.sess.is_sanitizer_cfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call {
+            if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) {
                 return;
             }
 
@@ -1526,7 +1526,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
                 options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
             }
 
-            let typeid = typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options);
+            let typeid = typeid_for_fnabi(self.tcx, fn_abi, options);
             let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
 
             // Test whether the function pointer is associated with the type identifier.
@@ -1550,25 +1550,26 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
     ) -> Option<llvm::OperandBundleDef<'ll>> {
-        let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
-        let kcfi_bundle = if is_indirect_call && self.tcx.sess.is_sanitizer_kcfi_enabled() {
-            if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::KCFI) {
-                return None;
-            }
+        let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
+        let kcfi_bundle =
+            if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call {
+                if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) {
+                    return None;
+                }
 
-            let mut options = TypeIdOptions::empty();
-            if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() {
-                options.insert(TypeIdOptions::GENERALIZE_POINTERS);
-            }
-            if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() {
-                options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
-            }
+                let mut options = TypeIdOptions::empty();
+                if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() {
+                    options.insert(TypeIdOptions::GENERALIZE_POINTERS);
+                }
+                if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() {
+                    options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
+                }
 
-            let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options);
-            Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
-        } else {
-            None
-        };
+                let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
+                Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
+            } else {
+                None
+            };
         kcfi_bundle
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index b167facfb02..112b4a173a5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -475,6 +475,8 @@ pub enum OptStage {
 pub struct SanitizerOptions {
     pub sanitize_address: bool,
     pub sanitize_address_recover: bool,
+    pub sanitize_cfi: bool,
+    pub sanitize_kcfi: bool,
     pub sanitize_memory: bool,
     pub sanitize_memory_recover: bool,
     pub sanitize_memory_track_origins: c_int,
@@ -894,6 +896,7 @@ extern "C" {
     pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
     pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
     pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>;
+    pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
 
     // Operations on constants of any type
     pub fn LLVMConstNull(Ty: &Type) -> &Value;
@@ -2138,6 +2141,7 @@ extern "C" {
         TM: &'a TargetMachine,
         OptLevel: PassBuilderOptLevel,
         OptStage: OptStage,
+        IsLinkerPluginLTO: bool,
         NoPrepopulatePasses: bool,
         VerifyIR: bool,
         UseThinLTOBuffers: bool,
@@ -2332,6 +2336,7 @@ extern "C" {
         remark_passes: *const *const c_char,
         remark_passes_len: usize,
         remark_file: *const c_char,
+        pgo_available: bool,
     );
 
     #[allow(improper_ctypes)]
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 4c04fc60b98..a1e322f4b31 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -13,6 +13,7 @@ use std::{env, mem, str};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::find_native_static_library;
 use rustc_middle::middle::dependency_format::Linkage;
+use rustc_middle::middle::exported_symbols;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
@@ -659,8 +660,6 @@ impl<'a> Linker for GccLinker<'a> {
             return;
         }
 
-        // FIXME(#99978) hide #[no_mangle] symbols for proc-macros
-
         let is_windows = self.sess.target.is_like_windows;
         let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
 
@@ -1679,8 +1678,15 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
         return exports.iter().map(ToString::to_string).collect();
     }
 
-    let mut symbols = Vec::new();
+    if let CrateType::ProcMacro = crate_type {
+        exported_symbols_for_proc_macro_crate(tcx)
+    } else {
+        exported_symbols_for_non_proc_macro(tcx, crate_type)
+    }
+}
 
+fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
+    let mut symbols = Vec::new();
     let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
     for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
         if info.level.is_below_threshold(export_threshold) {
@@ -1691,6 +1697,19 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
     symbols
 }
 
+fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
+    // `exported_symbols` will be empty when !should_codegen.
+    if !tcx.sess.opts.output_types.should_codegen() {
+        return Vec::new();
+    }
+
+    let stable_crate_id = tcx.sess.local_stable_crate_id();
+    let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
+    let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
+
+    vec![proc_macro_decls_name, metadata_symbol_name]
+}
+
 pub(crate) fn linked_symbols(
     tcx: TyCtxt<'_>,
     crate_type: CrateType,
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 0b336109921..e5dd5729d89 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -303,8 +303,6 @@ const_eval_remainder_overflow =
     overflow in signed remainder (dividing MIN by -1)
 const_eval_scalar_size_mismatch =
     scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead
-const_eval_size_of_unsized =
-    size_of called on unsized type `{$ty}`
 const_eval_size_overflow =
     overflow computing total size of `{$name}`
 
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index cc39387c41f..4ee4ebbb9e4 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -40,7 +40,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
         | hir::Node::AnonConst(_)
         | hir::Node::ConstBlock(_)
         | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const,
-        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const),
         hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
             // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
             // foreign items cannot be evaluated at compile-time.
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 3a4e2648b80..4362cae7ed7 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -862,7 +862,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
             InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
                 rustc_middle::error::middle_adjust_for_foreign_abi_error
             }
-            InvalidProgramInfo::SizeOfUnsizedType(_) => const_eval_size_of_unsized,
             InvalidProgramInfo::ConstPropNonsense => {
                 panic!("We had const-prop nonsense, this should never be printed")
             }
@@ -890,9 +889,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
                 builder.set_arg("arch", arch);
                 builder.set_arg("abi", abi.name());
             }
-            InvalidProgramInfo::SizeOfUnsizedType(ty) => {
-                builder.set_arg("ty", ty);
-            }
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index f04c73105d2..0740894a4ff 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -269,13 +269,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
                 let layout = self.layout_of(ty)?;
                 if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() {
-                    // FIXME: This should be a span_bug, but const generics can run MIR
-                    // that is not properly type-checked yet (#97477).
-                    self.tcx.sess.delay_span_bug(
+                    span_bug!(
                         self.frame().current_span(),
-                        format!("{null_op:?} MIR operator called for unsized type {ty}"),
+                        "{null_op:?} MIR operator called for unsized type {ty}",
                     );
-                    throw_inval!(SizeOfUnsizedType(ty));
                 }
                 let val = match null_op {
                     mir::NullOp::SizeOf => layout.size.bytes(),
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index e77fb4ea2a2..e51082e1ec0 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -127,15 +127,8 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let hir_id = tcx.local_def_id_to_hir_id(local_def_id);
 
     let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false };
-    let parent_def = tcx.hir().get(parent);
-
-    if !matches!(
-        parent_def,
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
-            ..
-        })
-    ) {
+
+    if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) {
         return false;
     }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index e785196c744..1f3cda35c2b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -145,8 +145,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                     let implsrc = selcx.select(&obligation);
 
                     if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
-                        let span = tcx.def_span(data.impl_def_id);
-                        err.subdiagnostic(errors::NonConstImplNote { span });
+                        // FIXME(effects) revisit this
+                        if !tcx.is_const_trait_impl_raw(data.impl_def_id) {
+                            let span = tcx.def_span(data.impl_def_id);
+                            err.subdiagnostic(errors::NonConstImplNote { span });
+                        }
                     }
                 }
                 _ => {}
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 61353c7b1ec..92a91766d91 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3359,7 +3359,6 @@ pub struct Impl<'hir> {
     // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
     // decoding as `Span`s cannot be decoded when a `Session` is not available.
     pub defaultness_span: Option<Span>,
-    pub constness: Constness,
     pub generics: &'hir Generics<'hir>,
 
     /// The trait being implemented, if any.
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9d1d899eef0..172f557f8e2 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -522,7 +522,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
             unsafety: _,
             defaultness: _,
             polarity: _,
-            constness: _,
             defaultness_span: _,
             ref generics,
             ref of_trait,
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 319573c85b4..668763f9bf6 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -532,6 +532,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         if let Err(guar) = ty.error_reported() {
                             return ty::Const::new_error(tcx, guar, ty).into();
                         }
+                        // FIXME(effects) see if we should special case effect params here
                         if !infer_args && has_default {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, args.unwrap())
@@ -659,7 +660,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         trait_ref: &hir::TraitRef<'_>,
         self_ty: Ty<'tcx>,
-        constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
 
@@ -669,7 +669,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             self_ty,
             trait_ref.path.segments.last().unwrap(),
             true,
-            constness,
+            ty::BoundConstness::NotConst,
         )
     }
 
@@ -849,6 +849,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         self_ty: Ty<'tcx>,
         trait_segment: &hir::PathSegment<'_>,
         is_impl: bool,
+        // FIXME(effects) move all host param things in astconv to hir lowering
         constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         let (generic_args, _) = self.create_args_for_ast_trait_ref(
@@ -2714,11 +2715,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         };
         let i = hir.get_parent(fn_hir_id).expect_item().expect_impl();
 
-        let trait_ref = self.instantiate_mono_trait_ref(
-            i.of_trait.as_ref()?,
-            self.ast_ty_to_ty(i.self_ty),
-            ty::BoundConstness::NotConst,
-        );
+        let trait_ref =
+            self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
 
         let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index f568b751951..02a5d28b1e2 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1359,38 +1359,60 @@ fn impl_trait_ref(
         .as_ref()
         .map(|ast_trait_ref| {
             let selfty = tcx.type_of(def_id).instantiate_identity();
-            icx.astconv().instantiate_mono_trait_ref(
-                ast_trait_ref,
-                selfty,
-                check_impl_constness(tcx, impl_.constness, ast_trait_ref),
-            )
+
+            if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
+                tcx,
+                tcx.is_const_trait_impl_raw(def_id.to_def_id()),
+                &ast_trait_ref,
+            ) {
+                // we have a const impl, but for a trait without `#[const_trait]`, so
+                // without the host param. If we continue with the HIR trait ref, we get
+                // ICEs for generic arg count mismatch. We do a little HIR editing to
+                // make astconv happy.
+                let mut path_segments = ast_trait_ref.path.segments.to_vec();
+                let last_segment = path_segments.len() - 1;
+                let mut args = path_segments[last_segment].args().clone();
+                let last_arg = args.args.len() - 1;
+                assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host)));
+                args.args = &args.args[..args.args.len() - 1];
+                path_segments[last_segment].args = Some(&args);
+                let path = hir::Path {
+                    span: ast_trait_ref.path.span,
+                    res: ast_trait_ref.path.res,
+                    segments: &path_segments,
+                };
+                let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id };
+                icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty)
+            } else {
+                icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty)
+            }
         })
         .map(ty::EarlyBinder::bind)
 }
 
 fn check_impl_constness(
     tcx: TyCtxt<'_>,
-    constness: hir::Constness,
+    is_const: bool,
     ast_trait_ref: &hir::TraitRef<'_>,
-) -> ty::BoundConstness {
-    match constness {
-        hir::Constness::Const => {
-            if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
-                let trait_name = tcx.item_name(trait_def_id).to_string();
-                tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
-                    trait_ref_span: ast_trait_ref.path.span,
-                    trait_name,
-                    local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
-                    marking: (),
-                    adding: (),
-                });
-                ty::BoundConstness::NotConst
-            } else {
-                ty::BoundConstness::ConstIfConst
-            }
-        },
-        hir::Constness::NotConst => ty::BoundConstness::NotConst,
+) -> Option<ErrorGuaranteed> {
+    if !is_const {
+        return None;
     }
+
+    let trait_def_id = ast_trait_ref.trait_def_id()?;
+    if tcx.has_attr(trait_def_id, sym::const_trait) {
+        return None;
+    }
+
+    let trait_name = tcx.item_name(trait_def_id).to_string();
+    Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
+        trait_ref_span: ast_trait_ref.path.span,
+        trait_name,
+        local_trait_span:
+            trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
+        marking: (),
+        adding: (),
+    }))
 }
 
 fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 6e1762c54f2..4842008279a 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
                 }
 
-                host_effect_index = Some(parent_count + index as usize);
+                host_effect_index = Some(index as usize);
             }
 
             Some(ty::GenericParamDef {
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 6be8d72aed2..61b182b1be7 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -578,6 +578,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             MissingTypesOrConsts { .. } => {
                 self.suggest_adding_type_and_const_args(err);
             }
+            ExcessTypesOrConsts { .. } => {
+                // this can happen with `~const T` where T isn't a const_trait.
+            }
             _ => unreachable!(),
         }
     }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index fda46798708..89efdc269c4 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -626,7 +626,6 @@ impl<'a> State<'a> {
                 unsafety,
                 polarity,
                 defaultness,
-                constness,
                 defaultness_span: _,
                 generics,
                 ref of_trait,
@@ -643,10 +642,6 @@ impl<'a> State<'a> {
                     self.space();
                 }
 
-                if constness == hir::Constness::Const {
-                    self.word_nbsp("const");
-                }
-
                 if let hir::ImplPolarity::Negative(_) = polarity {
                     self.word("!");
                 }
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index c68f2d94f35..ba00954db91 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -767,9 +767,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let tcx = self.tcx;
 
-        if !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you {
-            return;
-        }
+        // fast-reject if callee doesn't have the host effect param (non-const)
+        let generics = tcx.generics_of(callee_did);
+        let Some(host_effect_index) = generics.host_effect_index else { return };
+
+        // if the callee does have the param, we need to equate the param to some const
+        // value no matter whether the effects feature is enabled in the local crate,
+        // because inference will fail if we don't.
+        let mut host_always_on =
+            !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
 
         // Compute the constness required by the context.
         let context = tcx.hir().enclosing_body_owner(call_expr_hir);
@@ -780,10 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if tcx.has_attr(context.to_def_id(), sym::rustc_do_not_const_check) {
             trace!("do not const check this context");
-            return;
+            host_always_on = true;
         }
 
         let effect = match const_context {
+            _ if host_always_on => tcx.consts.true_,
             Some(hir::ConstContext::Static(_) | hir::ConstContext::Const) => tcx.consts.false_,
             Some(hir::ConstContext::ConstFn) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, context);
@@ -792,21 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             None => tcx.consts.true_,
         };
 
-        let generics = tcx.generics_of(callee_did);
-
         trace!(?effect, ?generics, ?callee_args);
 
-        if let Some(idx) = generics.host_effect_index {
-            let param = callee_args.const_at(idx);
-            let cause = self.misc(span);
-            match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
-                Ok(infer::InferOk { obligations, value: () }) => {
-                    self.register_predicates(obligations);
-                }
-                Err(e) => {
-                    // FIXME(effects): better diagnostic
-                    self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
-                }
+        let param = callee_args.const_at(host_effect_index);
+        let cause = self.misc(span);
+        match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
+            Ok(infer::InferOk { obligations, value: () }) => {
+                self.register_predicates(obligations);
+            }
+            Err(e) => {
+                // FIXME(effects): better diagnostic
+                self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 322d726a89d..8fad0a6c9e4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1349,7 +1349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     GenericParamDefKind::Const { has_default } => {
-                        if !infer_args && has_default {
+                        if !infer_args
+                            && has_default
+                            && !tcx.has_attr(param.def_id, sym::rustc_host)
+                        {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, args.unwrap())
                                 .into()
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index ea045462845..3f2bf2c9b44 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -15,7 +15,6 @@
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/JSON.h"
-#include "llvm/Support/Host.h"
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 48b5fd6e283..b3371dbe834 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -25,11 +25,11 @@
 #if LLVM_VERSION_GE(17, 0)
 #include "llvm/Support/VirtualFileSystem.h"
 #endif
-#include "llvm/Support/Host.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
 #include "llvm/Transforms/IPO/Internalize.h"
+#include "llvm/Transforms/IPO/LowerTypeTests.h"
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Utils/AddDiscriminators.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
@@ -609,6 +609,8 @@ enum class LLVMRustOptStage {
 struct LLVMRustSanitizerOptions {
   bool SanitizeAddress;
   bool SanitizeAddressRecover;
+  bool SanitizeCFI;
+  bool SanitizeKCFI;
   bool SanitizeMemory;
   bool SanitizeMemoryRecover;
   int  SanitizeMemoryTrackOrigins;
@@ -625,6 +627,7 @@ LLVMRustOptimize(
     LLVMTargetMachineRef TMRef,
     LLVMRustPassBuilderOptLevel OptLevelRust,
     LLVMRustOptStage OptStage,
+    bool IsLinkerPluginLTO,
     bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
     bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
     bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
@@ -736,6 +739,18 @@ LLVMRustOptimize(
   std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
       OptimizerLastEPCallbacks;
 
+  if (!IsLinkerPluginLTO
+      && SanitizerOptions && SanitizerOptions->SanitizeCFI
+      && !NoPrepopulatePasses) {
+    PipelineStartEPCallbacks.push_back(
+      [](ModulePassManager &MPM, OptimizationLevel Level) {
+        MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
+                                       /*ImportSummary=*/nullptr,
+                                       /*DropTypeTests=*/false));
+      }
+    );
+  }
+
   if (VerifyIR) {
     PipelineStartEPCallbacks.push_back(
       [VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) {
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 8ef39a6c866..70cdf3d6d23 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1869,7 +1869,8 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
     LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
     void *DiagnosticHandlerContext, bool RemarkAllPasses,
     const char * const * RemarkPasses, size_t RemarkPassesLen,
-    const char * RemarkFilePath
+    const char * RemarkFilePath,
+    bool PGOAvailable
 ) {
 
   class RustDiagnosticHandler final : public DiagnosticHandler {
@@ -1967,6 +1968,11 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
   std::unique_ptr<LLVMRemarkStreamer> LlvmRemarkStreamer;
 
   if (RemarkFilePath != nullptr) {
+    if (PGOAvailable) {
+      // Enable PGO hotness data for remarks, if available
+      unwrap(C)->setDiagnosticsHotnessRequested(true);
+    }
+
     std::error_code EC;
     RemarkFile = std::make_unique<ToolOutputFile>(
       RemarkFilePath,
@@ -2027,3 +2033,14 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
 extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) {
   return identify_magic(StringRef(ptr, len)) == file_magic::bitcode;
 }
+
+extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) {
+  if (unwrap<Value>(V)->getType()->isPointerTy()) {
+    if (auto *GV = dyn_cast<GlobalValue>(unwrap<Value>(V))) {
+      if (GV->getValueType()->isFunctionTy())
+        return false;
+    }
+    return true;
+  }
+  return false;
+}
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 2e46bfc1a38..e6ef5a41ee0 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -184,8 +184,6 @@ pub enum InvalidProgramInfo<'tcx> {
     /// (which unfortunately typeck does not reject).
     /// Not using `FnAbiError` as that contains a nested `LayoutError`.
     FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
-    /// SizeOf of unsized type was requested.
-    SizeOfUnsizedType(Ty<'tcx>),
     /// We are runnning into a nonsense situation due to ConstProp violating our invariants.
     ConstPropNonsense,
 }
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 2e5c6a44579..74bdd07a1c9 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -7,6 +7,7 @@ use std::fmt::Write;
 
 use crate::query::Providers;
 use rustc_data_structures::fx::FxIndexMap;
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{self as hir, LangItem};
 use rustc_span::def_id::LocalDefIdMap;
@@ -89,10 +90,18 @@ pub enum ClosureKind {
     FnOnce,
 }
 
-impl<'tcx> ClosureKind {
+impl ClosureKind {
     /// This is the initial value used when doing upvar inference.
     pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
 
+    pub const fn as_str(self) -> &'static str {
+        match self {
+            ClosureKind::Fn => "Fn",
+            ClosureKind::FnMut => "FnMut",
+            ClosureKind::FnOnce => "FnOnce",
+        }
+    }
+
     /// Returns `true` if a type that impls this closure kind
     /// must also implement `other`.
     pub fn extends(self, other: ty::ClosureKind) -> bool {
@@ -115,7 +124,7 @@ impl<'tcx> ClosureKind {
 
     /// Returns the representative scalar type for this closure kind.
     /// See `Ty::to_opt_closure_kind` for more details.
-    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self {
             ClosureKind::Fn => tcx.types.i8,
             ClosureKind::FnMut => tcx.types.i16,
@@ -124,6 +133,12 @@ impl<'tcx> ClosureKind {
     }
 }
 
+impl IntoDiagnosticArg for ClosureKind {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(self.as_str().into())
+    }
+}
+
 /// A composite describing a `Place` that is captured by a closure.
 #[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 6446f48bd1a..8ac1d02ce50 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2041,9 +2041,9 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(
             node,
             hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
+                kind: hir::ItemKind::Impl(hir::Impl { generics, .. }),
                 ..
-            })
+            }) if generics.params.iter().any(|p| self.has_attr(p.def_id, sym::rustc_host))
         )
     }
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 27ade16739d..bb6513363c9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2841,6 +2841,11 @@ define_print_and_forward_display! {
 
     ty::TraitPredicate<'tcx> {
         p!(print(self.trait_ref.self_ty()), ": ");
+        if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index {
+            if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ {
+                p!("~const ");
+            }
+        }
         // FIXME(effects) print `~const` here
         if let ty::ImplPolarity::Negative = self.polarity {
             p!("!");
@@ -2870,11 +2875,7 @@ define_print_and_forward_display! {
     }
 
     ty::ClosureKind {
-        match *self {
-            ty::ClosureKind::Fn => p!("Fn"),
-            ty::ClosureKind::FnMut => p!("FnMut"),
-            ty::ClosureKind::FnOnce => p!("FnOnce"),
-        }
+        p!(write("{}", self.as_str()))
     }
 
     ty::Predicate<'tcx> {
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index f99a51fea0b..bf798adee19 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -75,7 +75,7 @@ mod errors;
 mod ffi_unwind_calls;
 mod function_item_references;
 mod generator;
-mod inline;
+pub mod inline;
 mod instsimplify;
 mod large_enums;
 mod lower_intrinsics;
@@ -431,7 +431,9 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
     tcx.alloc_steal_mir(body)
 }
 
-fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden
+// by custom rustc drivers, running all the steps by themselves.
+pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
     let did = body.source.def_id();
 
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 25a3d38c144..3950ac9dd31 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -732,13 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
             // For implementations of traits, check the stability of each item
             // individually as it's possible to have a stable trait with unstable
             // items.
-            hir::ItemKind::Impl(hir::Impl {
-                of_trait: Some(ref t),
-                self_ty,
-                items,
-                constness,
-                ..
-            }) => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
                 let features = self.tcx.features();
                 if features.staged_api {
                     let attrs = self.tcx.hir().attrs(item.hir_id());
@@ -769,7 +763,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                     // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
                     // needs to have an error emitted.
                     if features.const_trait_impl
-                        && *constness == hir::Constness::Const
+                        && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id())
                         && const_stab.is_some_and(|(stab, _)| stab.is_const_stable())
                     {
                         self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span });
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index ba9bbbb1463..c34b7df9b46 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2404,7 +2404,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         should_continue = suggest(err, false, span, message, sugg);
                     }
                 }
-                LifetimeRibKind::Item => break,
+                LifetimeRibKind::Item | LifetimeRibKind::ConstParamTy => break,
                 _ => {}
             }
             if !should_continue {
@@ -2510,7 +2510,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             .lifetime_ribs
             .iter()
             .rev()
-            .take_while(|rib| !matches!(rib.kind, LifetimeRibKind::Item))
+            .take_while(|rib| {
+                !matches!(rib.kind, LifetimeRibKind::Item | LifetimeRibKind::ConstParamTy)
+            })
             .flat_map(|rib| rib.bindings.iter())
             .map(|(&ident, &res)| (ident, res))
             .filter(|(ident, _)| ident.name != kw::UnderscoreLifetime)
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index d4042a2e61a..b07c6db599e 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -89,7 +89,9 @@ session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-genera
 
 session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
 
-session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`
+session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
+
+session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
 
 session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
 
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 1ffee01b2f1..78940462b2c 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -115,6 +115,10 @@ pub struct CannotEnableCrtStaticLinux;
 pub struct SanitizerCfiRequiresLto;
 
 #[derive(Diagnostic)]
+#[diag(session_sanitizer_cfi_requires_single_codegen_unit)]
+pub struct SanitizerCfiRequiresSingleCodegenUnit;
+
+#[derive(Diagnostic)]
 #[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)]
 pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi;
 
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index ac745d16161..b25a6299125 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1619,13 +1619,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
 
     // LLVM CFI requires LTO.
     if sess.is_sanitizer_cfi_enabled()
-        && !(sess.lto() == config::Lto::Fat
-            || sess.lto() == config::Lto::Thin
-            || sess.opts.cg.linker_plugin_lto.enabled())
+        && !(sess.lto() == config::Lto::Fat || sess.opts.cg.linker_plugin_lto.enabled())
     {
         sess.emit_err(errors::SanitizerCfiRequiresLto);
     }
 
+    // LLVM CFI using rustc LTO requires a single codegen unit.
+    if sess.is_sanitizer_cfi_enabled()
+        && sess.lto() == config::Lto::Fat
+        && !(sess.codegen_units().as_usize() == 1)
+    {
+        sess.emit_err(errors::SanitizerCfiRequiresSingleCodegenUnit);
+    }
+
     // LLVM CFI is incompatible with LLVM KCFI.
     if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
         sess.emit_err(errors::CannotMixAndMatchSanitizers {
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs
new file mode 100644
index 00000000000..64a7dc681c8
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs
@@ -0,0 +1,16 @@
+use crate::spec::Target;
+
+pub fn target() -> Target {
+    let mut base = super::teeos_base::opts();
+    base.features = "+strict-align,+neon,+fp-armv8".into();
+    base.max_atomic_width = Some(128);
+    base.linker = Some("aarch64-linux-gnu-ld".into());
+
+    Target {
+        llvm_target: "aarch64-unknown-none".into(),
+        pointer_width: 64,
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: base,
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index c215a7c4b6e..6ab0aed1ab8 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -83,6 +83,7 @@ mod openbsd_base;
 mod redox_base;
 mod solaris_base;
 mod solid_base;
+mod teeos_base;
 mod thumb_base;
 mod uefi_msvc_base;
 mod unikraft_linux_musl_base;
@@ -1494,6 +1495,8 @@ supported_targets! {
 
     ("x86_64-unknown-none", x86_64_unknown_none),
 
+    ("aarch64-unknown-teeos", aarch64_unknown_teeos),
+
     ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl),
 
     ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710),
diff --git a/compiler/rustc_target/src/spec/teeos_base.rs b/compiler/rustc_target/src/spec/teeos_base.rs
new file mode 100644
index 00000000000..1bc71bab016
--- /dev/null
+++ b/compiler/rustc_target/src/spec/teeos_base.rs
@@ -0,0 +1,29 @@
+use super::{Cc, LinkerFlavor, Lld, PanicStrategy};
+use crate::spec::{RelroLevel, TargetOptions};
+
+pub fn opts() -> TargetOptions {
+    let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
+    let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
+
+    let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
+    super::add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
+
+    TargetOptions {
+        os: "teeos".into(),
+        vendor: "unknown".into(),
+        dynamic_linking: true,
+        linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        // rpath hardcodes -Wl, so it can't be used together with ld.lld.
+        // C TAs also don't support rpath, so this is fine.
+        has_rpath: false,
+        // Note: Setting has_thread_local to true causes an error when
+        // loading / dyn-linking the TA
+        has_thread_local: false,
+        position_independent_executables: true,
+        relro_level: RelroLevel::Full,
+        crt_static_respected: true,
+        pre_link_args,
+        panic_strategy: PanicStrategy::Abort,
+        ..Default::default()
+    }
+}
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index f57f1bad15d..f4c9dfa3488 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -8,6 +8,15 @@ trait_selection_adjust_signature_remove_borrow = consider adjusting the signatur
         *[other] arguments
     }
 
+trait_selection_closure_fn_mut_label = closure is `FnMut` because it mutates the variable `{$place}` here
+
+trait_selection_closure_fn_once_label = closure is `FnOnce` because it moves the variable `{$place}` out of its environment
+
+trait_selection_closure_kind_mismatch = expected a closure that implements the `{$expected}` trait, but this closure only implements `{$found}`
+    .label = this closure implements `{$found}`, not `{$expected}`
+
+trait_selection_closure_kind_requirement = the requirement to implement `{$expected}` derives from here
+
 trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
 
 trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index dde9e9c9ac6..c1fb287d63e 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -4,7 +4,7 @@ use rustc_errors::{
     SubdiagnosticMessage,
 };
 use rustc_macros::Diagnostic;
-use rustc_middle::ty::{self, PolyTraitRef, Ty};
+use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
 use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
@@ -131,3 +131,37 @@ impl AddToDiagnostic for AdjustSignatureBorrow {
         }
     }
 }
+
+#[derive(Diagnostic)]
+#[diag(trait_selection_closure_kind_mismatch, code = "E0525")]
+pub struct ClosureKindMismatch {
+    #[primary_span]
+    #[label]
+    pub closure_span: Span,
+    pub expected: ClosureKind,
+    pub found: ClosureKind,
+    #[label(trait_selection_closure_kind_requirement)]
+    pub cause_span: Span,
+
+    #[subdiagnostic]
+    pub fn_once_label: Option<ClosureFnOnceLabel>,
+
+    #[subdiagnostic]
+    pub fn_mut_label: Option<ClosureFnMutLabel>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(trait_selection_closure_fn_once_label)]
+pub struct ClosureFnOnceLabel {
+    #[primary_span]
+    pub span: Span,
+    pub place: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(trait_selection_closure_fn_mut_label)]
+pub struct ClosureFnMutLabel {
+    #[primary_span]
+    pub span: Span,
+    pub place: String,
+}
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 4d85e2b6089..457d5420ca3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -7,6 +7,7 @@ use super::{
     ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
     PredicateObligation, SelectionError, TraitNotObjectSafe,
 };
+use crate::errors::{ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch};
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt};
@@ -3110,27 +3111,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> UnsatisfiedConst {
         let unsatisfied_const = UnsatisfiedConst(false);
         // FIXME(effects)
-        /* if trait_predicate.is_const_if_const() {
-            let non_const_predicate = trait_ref.without_const();
-            let non_const_obligation = Obligation {
-                cause: obligation.cause.clone(),
-                param_env: obligation.param_env,
-                predicate: non_const_predicate.to_predicate(self.tcx),
-                recursion_depth: obligation.recursion_depth,
-            };
-            if self.predicate_may_hold(&non_const_obligation) {
-                unsatisfied_const = UnsatisfiedConst(true);
-                err.span_note(
-                    span,
-                    format!(
-                        "the trait `{}` is implemented for `{}`, \
-                        but that implementation is not `const`",
-                        non_const_predicate.print_modifiers_and_trait_path(),
-                        trait_ref.skip_binder().self_ty(),
-                    ),
-                );
-            }
-        } */
         unsatisfied_const
     }
 
@@ -3142,24 +3122,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         kind: ty::ClosureKind,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let closure_span = self.tcx.def_span(closure_def_id);
-        let mut err = struct_span_err!(
-            self.tcx.sess,
-            closure_span,
-            E0525,
-            "expected a closure that implements the `{}` trait, \
-                but this closure only implements `{}`",
-            kind,
-            found_kind
-        );
 
-        err.span_label(
+        let mut err = ClosureKindMismatch {
             closure_span,
-            format!("this closure implements `{found_kind}`, not `{kind}`"),
-        );
-        err.span_label(
-            obligation.cause.span,
-            format!("the requirement to implement `{kind}` derives from here"),
-        );
+            expected: kind,
+            found: found_kind,
+            cause_span: obligation.cause.span,
+            fn_once_label: None,
+            fn_mut_label: None,
+        };
 
         // Additional context information explaining why the closure only implements
         // a particular trait.
@@ -3167,30 +3138,22 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             let hir_id = self.tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local());
             match (found_kind, typeck_results.closure_kind_origins().get(hir_id)) {
                 (ty::ClosureKind::FnOnce, Some((span, place))) => {
-                    err.span_label(
-                        *span,
-                        format!(
-                            "closure is `FnOnce` because it moves the \
-                            variable `{}` out of its environment",
-                            ty::place_to_string_for_capture(self.tcx, place)
-                        ),
-                    );
+                    err.fn_once_label = Some(ClosureFnOnceLabel {
+                        span: *span,
+                        place: ty::place_to_string_for_capture(self.tcx, &place),
+                    })
                 }
                 (ty::ClosureKind::FnMut, Some((span, place))) => {
-                    err.span_label(
-                        *span,
-                        format!(
-                            "closure is `FnMut` because it mutates the \
-                            variable `{}` here",
-                            ty::place_to_string_for_capture(self.tcx, place)
-                        ),
-                    );
+                    err.fn_mut_label = Some(ClosureFnMutLabel {
+                        span: *span,
+                        place: ty::place_to_string_for_capture(self.tcx, &place),
+                    })
                 }
                 _ => {}
             }
         }
 
-        err
+        self.tcx.sess.create_err(err)
     }
 
     fn report_type_parameter_mismatch_cyclic_type_error(
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f9cb755b01a..f1305dee146 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1528,7 +1528,7 @@ impl From<fs::File> for Stdio {
 // vs `_exit`.  Naming of Unix system calls is not standardised across Unices, so terminology is a
 // matter of convention and tradition.  For clarity we usually speak of `exit`, even when we might
 // mean an underlying system call such as `_exit`.
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(imp::ExitStatus);
 
diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs
index e45c380a0bb..9931c2af2f1 100644
--- a/library/std/src/sys/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/unix/process/process_fuchsia.rs
@@ -235,7 +235,7 @@ impl Process {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(i64);
 
 impl ExitStatus {
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 0ce93af66ac..3963e7f52d5 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -10,9 +10,6 @@ use core::ffi::NonZero_c_int;
 #[cfg(target_os = "linux")]
 use crate::os::linux::process::PidFd;
 
-#[cfg(target_os = "linux")]
-use crate::sys::weak::raw_syscall;
-
 #[cfg(any(
     target_os = "macos",
     target_os = "watchos",
@@ -91,6 +88,11 @@ impl Command {
         if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? {
             return Ok((ret, ours));
         }
+
+        #[cfg(target_os = "linux")]
+        let (input, output) = sys::net::Socket::new_pair(libc::AF_UNIX, libc::SOCK_SEQPACKET)?;
+
+        #[cfg(not(target_os = "linux"))]
         let (input, output) = sys::pipe::anon_pipe()?;
 
         // Whatever happens after the fork is almost for sure going to touch or
@@ -104,12 +106,16 @@ impl Command {
         // The child calls `mem::forget` to leak the lock, which is crucial because
         // releasing a lock is not async-signal-safe.
         let env_lock = sys::os::env_read_lock();
-        let (pid, pidfd) = unsafe { self.do_fork()? };
+        let pid = unsafe { self.do_fork()? };
 
         if pid == 0 {
             crate::panic::always_abort();
             mem::forget(env_lock); // avoid non-async-signal-safe unlocking
             drop(input);
+            #[cfg(target_os = "linux")]
+            if self.get_create_pidfd() {
+                self.send_pidfd(&output);
+            }
             let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
             let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
             let errno = errno.to_be_bytes();
@@ -133,6 +139,12 @@ impl Command {
         drop(env_lock);
         drop(output);
 
+        #[cfg(target_os = "linux")]
+        let pidfd = if self.get_create_pidfd() { self.recv_pidfd(&input) } else { -1 };
+
+        #[cfg(not(target_os = "linux"))]
+        let pidfd = -1;
+
         // Safety: We obtained the pidfd from calling `clone3` with
         // `CLONE_PIDFD` so it's valid an otherwise unowned.
         let mut p = unsafe { Process::new(pid, pidfd) };
@@ -160,6 +172,7 @@ impl Command {
                 }
                 Ok(..) => {
                     // pipe I/O up to PIPE_BUF bytes should be atomic
+                    // similarly SOCK_SEQPACKET messages should arrive whole
                     assert!(p.wait().is_ok(), "wait() should either return Ok or panic");
                     panic!("short read on the CLOEXEC pipe")
                 }
@@ -185,20 +198,19 @@ impl Command {
     );
 
     #[cfg(any(target_os = "tvos", target_os = "watchos"))]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
+    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
         return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC);
     }
 
     // Attempts to fork the process. If successful, returns Ok((0, -1))
     // in the child, and Ok((child_pid, -1)) in the parent.
     #[cfg(not(any(
-        target_os = "linux",
         target_os = "watchos",
         target_os = "tvos",
         all(target_os = "nto", target_env = "nto71"),
     )))]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
-        cvt(libc::fork()).map(|res| (res, -1))
+    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
+        cvt(libc::fork())
     }
 
     // On QNX Neutrino, fork can fail with EBADF in case "another thread might have opened
@@ -206,7 +218,7 @@ impl Command {
     // 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"))]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
+    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
         use crate::sys::os::errno;
 
         let mut delay = MIN_FORKSPAWN_SLEEP;
@@ -229,91 +241,11 @@ impl Command {
                 delay *= 2;
                 continue;
             } else {
-                return cvt(r).map(|res| (res, -1));
+                return cvt(r);
             }
         }
     }
 
-    // Attempts to fork the process. If successful, returns Ok((0, -1))
-    // in the child, and Ok((child_pid, child_pidfd)) in the parent.
-    #[cfg(target_os = "linux")]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
-        use crate::sync::atomic::{AtomicBool, Ordering};
-
-        static HAS_CLONE3: AtomicBool = AtomicBool::new(true);
-        const CLONE_PIDFD: u64 = 0x00001000;
-
-        #[repr(C)]
-        struct clone_args {
-            flags: u64,
-            pidfd: u64,
-            child_tid: u64,
-            parent_tid: u64,
-            exit_signal: u64,
-            stack: u64,
-            stack_size: u64,
-            tls: u64,
-            set_tid: u64,
-            set_tid_size: u64,
-            cgroup: u64,
-        }
-
-        raw_syscall! {
-            fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
-        }
-
-        // Bypassing libc for `clone3` can make further libc calls unsafe,
-        // so we use it sparingly for now. See #89522 for details.
-        // Some tools (e.g. sandboxing tools) may also expect `fork`
-        // rather than `clone3`.
-        let want_clone3_pidfd = self.get_create_pidfd();
-
-        // If we fail to create a pidfd for any reason, this will
-        // stay as -1, which indicates an error.
-        let mut pidfd: pid_t = -1;
-
-        // Attempt to use the `clone3` syscall, which supports more arguments
-        // (in particular, the ability to create a pidfd). If this fails,
-        // we will fall through this block to a call to `fork()`
-        if want_clone3_pidfd && HAS_CLONE3.load(Ordering::Relaxed) {
-            let mut args = clone_args {
-                flags: CLONE_PIDFD,
-                pidfd: &mut pidfd as *mut pid_t as u64,
-                child_tid: 0,
-                parent_tid: 0,
-                exit_signal: libc::SIGCHLD as u64,
-                stack: 0,
-                stack_size: 0,
-                tls: 0,
-                set_tid: 0,
-                set_tid_size: 0,
-                cgroup: 0,
-            };
-
-            let args_ptr = &mut args as *mut clone_args;
-            let args_size = crate::mem::size_of::<clone_args>();
-
-            let res = cvt(clone3(args_ptr, args_size));
-            match res {
-                Ok(n) => return Ok((n as pid_t, pidfd)),
-                Err(e) => match e.raw_os_error() {
-                    // Multiple threads can race to execute this store,
-                    // but that's fine - that just means that multiple threads
-                    // will have tried and failed to execute the same syscall,
-                    // with no other side effects.
-                    Some(libc::ENOSYS) => HAS_CLONE3.store(false, Ordering::Relaxed),
-                    // Fallback to fork if `EPERM` is returned. (e.g. blocked by seccomp)
-                    Some(libc::EPERM) => {}
-                    _ => return Err(e),
-                },
-            }
-        }
-
-        // Generally, we just call `fork`. If we get here after wanting `clone3`,
-        // then the syscall does not exist or we do not have permission to call it.
-        cvt(libc::fork()).map(|res| (res, pidfd))
-    }
-
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         let envp = self.capture_env();
 
@@ -722,6 +654,115 @@ impl Command {
             Ok(Some(p))
         }
     }
+
+    #[cfg(target_os = "linux")]
+    fn send_pidfd(&self, sock: &crate::sys::net::Socket) {
+        use crate::io::IoSlice;
+        use crate::os::fd::RawFd;
+        use crate::sys::cvt_r;
+        use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET};
+
+        unsafe {
+            let child_pid = libc::getpid();
+            // pidfd_open sets CLOEXEC by default
+            let pidfd = libc::syscall(libc::SYS_pidfd_open, child_pid, 0);
+
+            let fds: [c_int; 1] = [pidfd as RawFd];
+
+            const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>();
+
+            #[repr(C)]
+            union Cmsg {
+                buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }],
+                _align: libc::cmsghdr,
+            }
+
+            let mut cmsg: Cmsg = mem::zeroed();
+
+            // 0-length message to send through the socket so we can pass along the fd
+            let mut iov = [IoSlice::new(b"")];
+            let mut msg: libc::msghdr = mem::zeroed();
+
+            msg.msg_iov = &mut iov as *mut _ as *mut _;
+            msg.msg_iovlen = 1;
+            msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _;
+            msg.msg_control = &mut cmsg.buf as *mut _ as *mut _;
+
+            // only attach cmsg if we successfully acquired the pidfd
+            if pidfd >= 0 {
+                let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _);
+                (*hdr).cmsg_level = SOL_SOCKET;
+                (*hdr).cmsg_type = SCM_RIGHTS;
+                (*hdr).cmsg_len = CMSG_LEN(SCM_MSG_LEN as _) as _;
+                let data = CMSG_DATA(hdr);
+                crate::ptr::copy_nonoverlapping(
+                    fds.as_ptr().cast::<u8>(),
+                    data as *mut _,
+                    SCM_MSG_LEN,
+                );
+            }
+
+            // we send the 0-length message even if we failed to acquire the pidfd
+            // so we get a consistent SEQPACKET order
+            match cvt_r(|| libc::sendmsg(sock.as_raw(), &msg, 0)) {
+                Ok(0) => {}
+                _ => rtabort!("failed to communicate with parent process"),
+            }
+        }
+    }
+
+    #[cfg(target_os = "linux")]
+    fn recv_pidfd(&self, sock: &crate::sys::net::Socket) -> pid_t {
+        use crate::io::IoSliceMut;
+        use crate::sys::cvt_r;
+
+        use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET};
+
+        unsafe {
+            const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>();
+
+            #[repr(C)]
+            union Cmsg {
+                _buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }],
+                _align: libc::cmsghdr,
+            }
+            let mut cmsg: Cmsg = mem::zeroed();
+            // 0-length read to get the fd
+            let mut iov = [IoSliceMut::new(&mut [])];
+
+            let mut msg: libc::msghdr = mem::zeroed();
+
+            msg.msg_iov = &mut iov as *mut _ as *mut _;
+            msg.msg_iovlen = 1;
+            msg.msg_controllen = mem::size_of::<Cmsg>() as _;
+            msg.msg_control = &mut cmsg as *mut _ as *mut _;
+
+            match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, 0)) {
+                Err(_) => return -1,
+                Ok(_) => {}
+            }
+
+            let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _);
+            if hdr.is_null()
+                || (*hdr).cmsg_level != SOL_SOCKET
+                || (*hdr).cmsg_type != SCM_RIGHTS
+                || (*hdr).cmsg_len != CMSG_LEN(SCM_MSG_LEN as _) as _
+            {
+                return -1;
+            }
+            let data = CMSG_DATA(hdr);
+
+            let mut fds = [-1 as c_int];
+
+            crate::ptr::copy_nonoverlapping(
+                data as *const _,
+                fds.as_mut_ptr().cast::<u8>(),
+                SCM_MSG_LEN,
+            );
+
+            fds[0]
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -800,7 +841,7 @@ impl Process {
 //
 // This is not actually an "exit status" in Unix terminology.  Rather, it is a "wait status".
 // See the discussion in comments and doc comments for `std::process::ExitStatus`.
-#[derive(PartialEq, Eq, Clone, Copy)]
+#[derive(PartialEq, Eq, Clone, Copy, Default)]
 pub struct ExitStatus(c_int);
 
 impl fmt::Debug for ExitStatus {
diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs
index e5e1f956bc3..6aa79e7f9e7 100644
--- a/library/std/src/sys/unix/process/process_unix/tests.rs
+++ b/library/std/src/sys/unix/process/process_unix/tests.rs
@@ -60,3 +60,28 @@ fn test_command_fork_no_unwind() {
             || signal == libc::SIGSEGV
     );
 }
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_command_pidfd() {
+    use crate::os::fd::RawFd;
+    use crate::os::linux::process::{ChildExt, CommandExt};
+    use crate::process::Command;
+
+    let our_pid = crate::process::id();
+    let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) };
+    let pidfd_open_available = if pidfd >= 0 {
+        unsafe { libc::close(pidfd as RawFd) };
+        true
+    } else {
+        false
+    };
+
+    // always exercise creation attempts
+    let child = Command::new("echo").create_pidfd(true).spawn().unwrap();
+
+    // but only check if we know that the kernel supports pidfds
+    if pidfd_open_available {
+        assert!(child.pidfd().is_ok())
+    }
+}
diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs
index f28ca58d020..8e0b971af73 100644
--- a/library/std/src/sys/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/unix/process/process_unsupported.rs
@@ -55,7 +55,7 @@ impl Process {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(c_int);
 
 impl ExitStatus {
diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs
index f70d3cb396b..1ff2b2fb383 100644
--- a/library/std/src/sys/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/unix/process/process_vxworks.rs
@@ -179,7 +179,7 @@ impl Process {
 }
 
 /// Unix exit statuses
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(c_int);
 
 impl ExitStatus {
diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs
index a494f2d6b4c..77b675aaa4e 100644
--- a/library/std/src/sys/unsupported/process.rs
+++ b/library/std/src/sys/unsupported/process.rs
@@ -99,58 +99,59 @@ impl fmt::Debug for Command {
     }
 }
 
-pub struct ExitStatus(!);
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
+#[non_exhaustive]
+pub struct ExitStatus();
 
 impl ExitStatus {
     pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
-        self.0
+        Ok(())
     }
 
     pub fn code(&self) -> Option<i32> {
-        self.0
+        Some(0)
     }
 }
 
-impl Clone for ExitStatus {
-    fn clone(&self) -> ExitStatus {
-        self.0
+impl fmt::Display for ExitStatus {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "<dummy exit status>")
     }
 }
 
-impl Copy for ExitStatus {}
+pub struct ExitStatusError(!);
 
-impl PartialEq for ExitStatus {
-    fn eq(&self, _other: &ExitStatus) -> bool {
+impl Clone for ExitStatusError {
+    fn clone(&self) -> ExitStatusError {
         self.0
     }
 }
 
-impl Eq for ExitStatus {}
+impl Copy for ExitStatusError {}
 
-impl fmt::Debug for ExitStatus {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+impl PartialEq for ExitStatusError {
+    fn eq(&self, _other: &ExitStatusError) -> bool {
         self.0
     }
 }
 
-impl fmt::Display for ExitStatus {
+impl Eq for ExitStatusError {}
+
+impl fmt::Debug for ExitStatusError {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(ExitStatus);
-
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
-        self.0.0
+        self.0
     }
 }
 
 impl ExitStatusError {
     pub fn code(self) -> Option<NonZeroI32> {
-        self.0.0
+        self.0
     }
 }
 
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index e3493cbb850..2dd0c67acdb 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -652,7 +652,7 @@ impl Process {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(c::DWORD);
 
 impl ExitStatus {
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 2c63ec80c3e..62c7b96b5be 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -31,6 +31,7 @@ use crate::util::get_clang_cl_resource_dir;
 use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date};
 use crate::LLVM_TOOLS;
 use crate::{CLang, Compiler, DependencyType, GitRepo, Mode};
+use filetime::FileTime;
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Std {
@@ -904,19 +905,12 @@ impl Step for Rustc {
         // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with
         // debuginfo (via the debuginfo level of the executables using it): strip this debuginfo
         // away after the fact.
-        // FIXME: to make things simpler for now, limit this to the host and target where we know
-        // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
-        // cross-compiling. Expand this to other appropriate targets in the future.
         if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None
             && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None
-            && target == "x86_64-unknown-linux-gnu"
-            && target == builder.config.build
         {
             let target_root_dir = stamp.parent().unwrap();
             let rustc_driver = target_root_dir.join("librustc_driver.so");
-            if rustc_driver.exists() {
-                output(Command::new("strip").arg("--strip-debug").arg(rustc_driver));
-            }
+            strip_debug(builder, target, &rustc_driver);
         }
 
         builder.ensure(RustcLink::from_rustc(
@@ -1974,3 +1968,30 @@ pub enum CargoMessage<'a> {
         success: bool,
     },
 }
+
+pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) {
+    // FIXME: to make things simpler for now, limit this to the host and target where we know
+    // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
+    // cross-compiling. Expand this to other appropriate targets in the future.
+    if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() {
+        return;
+    }
+
+    let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap());
+    // Note: `output` will propagate any errors here.
+    output(Command::new("strip").arg("--strip-debug").arg(path));
+
+    // After running `strip`, we have to set the file modification time to what it was before,
+    // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time
+    // bootstrap is invoked.
+    //
+    // An example of this is if we run this on librustc_driver.so. In the first invocation:
+    // - Cargo will build librustc_driver.so (mtime of 1)
+    // - Cargo will build rustc-main (mtime of 2)
+    // - Bootstrap will strip librustc_driver.so (changing the mtime to 3).
+    //
+    // In the second invocation of bootstrap, Cargo will see that the mtime of librustc_driver.so
+    // is greater than the mtime of rustc-main, and will rebuild rustc-main. That will then cause
+    // everything else (standard library, future stages...) to be rebuilt.
+    t!(filetime::set_file_mtime(path, previous_mtime));
+}
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 8c674d075b8..e3a9434a164 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -133,7 +133,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
     // #[cfg(bootstrap)]
     (Some(Mode::Std), "target_vendor", Some(&["unikraft"])),
     (Some(Mode::Std), "target_env", Some(&["libnx"])),
-    // (Some(Mode::Std), "target_os", Some(&[])),
+    (Some(Mode::Std), "target_os", Some(&["teeos"])),
     // #[cfg(bootstrap)] mips32r6, mips64r6
     (
         Some(Mode::Std),
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 14ee5659ed5..4943f93fa9a 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -512,27 +512,21 @@ impl Step for Llvm {
         // When building LLVM as a shared library on linux, it can contain unexpected debuginfo:
         // some can come from the C++ standard library. Unless we're explicitly requesting LLVM to
         // be built with debuginfo, strip it away after the fact, to make dist artifacts smaller.
-        // FIXME: to make things simpler for now, limit this to the host and target where we know
-        // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
-        // cross-compiling. Expand this to other appropriate targets in the future.
         if builder.llvm_link_shared()
             && builder.config.llvm_optimize
             && !builder.config.llvm_release_debuginfo
-            && target == "x86_64-unknown-linux-gnu"
-            && target == builder.config.build
         {
             // Find the name of the LLVM shared library that we just built.
             let lib_name = find_llvm_lib_name("so");
 
             // If the shared library exists in LLVM's `/build/lib/` or `/lib/` folders, strip its
-            // debuginfo. Note: `output` will propagate any errors here.
-            let strip_if_possible = |path: PathBuf| {
-                if path.exists() {
-                    output(Command::new("strip").arg("--strip-debug").arg(path));
-                }
-            };
-            strip_if_possible(out_dir.join("lib").join(&lib_name));
-            strip_if_possible(out_dir.join("build").join("lib").join(&lib_name));
+            // debuginfo.
+            crate::compile::strip_debug(builder, target, &out_dir.join("lib").join(&lib_name));
+            crate::compile::strip_debug(
+                builder,
+                target,
+                &out_dir.join("build").join("lib").join(&lib_name),
+            );
         }
 
         t!(stamp.write());
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 851be1c0a2c..817abbfaf26 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -28,6 +28,7 @@
     - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
     - [\*-android and \*-androideabi](platform-support/android.md)
     - [\*-linux-ohos](platform-support/openharmony.md)
+    - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md)
     - [\*-esp-espidf](platform-support/esp-idf.md)
     - [\*-unknown-fuchsia](platform-support/fuchsia.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 1b791f5eb36..393719e7115 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -221,6 +221,7 @@ target | std | host | notes
 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * |  | ARM64 Nintendo Switch, Horizon
 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ |  | ARM64 OpenHarmony |
+[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? |  | ARM64 TEEOS |
 [`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/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
new file mode 100644
index 00000000000..8fc5e6dd92b
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
@@ -0,0 +1,100 @@
+# `aarch64-unknown-teeos`
+
+**Tier: 3**
+
+Target for the TEEOS operating system.
+
+TEEOS is a mini os run in TrustZone, for trusted/security apps. The kernel of TEEOS is HongMeng/ChCore micro kernel. The libc for TEEOS is a part of musl.
+It's very small that there is no RwLock, no network, no stdin, and no file system for apps in TEEOS.
+
+Some abbreviation:
+| Abbreviation | The full text | Description |
+|  ----  | ----  | ---- |
+| TEE | Trusted Execution Environment | ARM TrustZone devide the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. |
+| REE | Rich Execution Environment | The normal world. for example, Linux for Android phone is in REE side. |
+| TA | Trusted Application | The app run in TEE side system. |
+| CA | Client Application | The progress run in REE side system. |
+
+TEEOS is open source in progress. [MORE about](https://gitee.com/opentrustee-group)
+
+## Target maintainers
+
+- Petrochenkov Vadim
+- Sword-Destiny
+
+## Setup
+We use OpenHarmony SDK for TEEOS.
+
+The OpenHarmony SDK doesn't currently support Rust compilation directly, so
+some setup is required.
+
+First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes).
+Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system".
+
+Create the following shell scripts that wrap Clang from the OpenHarmony SDK:
+
+`aarch64-unknown-teeos-clang.sh`
+
+```sh
+#!/bin/sh
+exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \
+  --target aarch64-linux-gnu \
+  "$@"
+```
+
+`aarch64-unknown-teeos-clang++.sh`
+
+```sh
+#!/bin/sh
+exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
+  --target aarch64-linux-gnu \
+  "$@"
+```
+
+## Building the target
+
+To build a rust toolchain, create a `config.toml` with the following contents:
+
+```toml
+profile = "compiler"
+changelog-seen = 2
+
+[build]
+sanitizers = true
+profiler = true
+target = ["x86_64-unknown-linux-gnu", "aarch64-unknown-teeos"]
+submodules = false
+compiler-docs = false
+extended = true
+
+[install]
+bindir = "bin"
+libdir = "lib"
+
+[target.aarch64-unknown-teeos]
+cc = "/path/to/scripts/aarch64-unknown-teeos-clang.sh"
+cxx = "/path/to/scripts/aarch64-unknown-teeos-clang.sh"
+linker = "/path/to/scripts/aarch64-unknown-teeos-clang.sh"
+ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
+ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
+llvm-config = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-config"
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+You will need to configure the linker to use in `~/.cargo/config`:
+```toml
+[target.aarch64-unknown-teeos]
+linker = "/path/to/aarch64-unknown-teeos-clang.sh"
+```
+
+## Testing
+
+Running the Rust testsuite is not possible now.
+
+More information about how to test CA/TA. [See here](https://gitee.com/openharmony-sig/tee_tee_dev_kit/tree/master/docs)
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c1987420417..3d237eb25cc 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1645,7 +1645,7 @@ impl<'test> TestCx<'test> {
         if self.props.known_bug {
             if !expected_errors.is_empty() {
                 self.fatal_proc_rec(
-                    "`known_bug` tests should not have an expected errors",
+                    "`known_bug` tests should not have an expected error",
                     proc_res,
                 );
             }
diff --git a/tests/run-make/optimization-remarks-dir-pgo/Makefile b/tests/run-make/optimization-remarks-dir-pgo/Makefile
new file mode 100644
index 00000000000..c88ec1e6cb3
--- /dev/null
+++ b/tests/run-make/optimization-remarks-dir-pgo/Makefile
@@ -0,0 +1,20 @@
+# needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
+
+include ../tools.mk
+
+PROFILE_DIR=$(TMPDIR)/profiles
+
+check_hotness:
+	$(RUSTC) -Cprofile-generate="$(TMPDIR)"/profdata -O foo.rs -o$(TMPDIR)/foo
+	$(TMPDIR)/foo
+	"$(LLVM_BIN_DIR)"/llvm-profdata merge \
+		-o "$(TMPDIR)"/merged.profdata \
+		"$(TMPDIR)"/profdata/*.profraw
+	$(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata -O foo.rs -Cremark=all -Zremark-dir=$(PROFILE_DIR)
+
+	# Check that PGO hotness is included in the remark files
+	cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "Hotness"
diff --git a/tests/run-make/optimization-remarks-dir-pgo/foo.rs b/tests/run-make/optimization-remarks-dir-pgo/foo.rs
new file mode 100644
index 00000000000..f7ca1826338
--- /dev/null
+++ b/tests/run-make/optimization-remarks-dir-pgo/foo.rs
@@ -0,0 +1,6 @@
+#[inline(never)]
+pub fn bar() {}
+
+fn main() {
+    bar();
+}
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index 2ee4bce1015..0789d785f58 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -46,53 +46,53 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "mod": "rgb(57, 175, 215)",
-        "macro": "rgb(163, 122, 204)",
-        "struct": "rgb(255, 160, 165)",
-        "enum": "rgb(255, 160, 165)",
-        "trait": "rgb(57, 175, 215)",
-        "fn": "rgb(253, 214, 135)",
-        "type": "rgb(255, 160, 165)",
-        "union": "rgb(255, 160, 165)",
-        "keyword": "rgb(57, 175, 215)",
-        "sidebar": "rgb(83, 177, 219)",
-        "sidebar_current": "rgb(255, 180, 76)",
-        "sidebar_current_background": "rgba(0, 0, 0, 0)",
+        "mod": "#39afd7",
+        "macro": "#a37acc",
+        "struct": "#ffa0a5",
+        "enum": "#ffa0a5",
+        "trait": "#39afd7",
+        "fn": "#fdd687",
+        "type": "#ffa0a5",
+        "union": "#ffa0a5",
+        "keyword": "#39afd7",
+        "sidebar": "#53b1db",
+        "sidebar_current": "#ffb44c",
+        "sidebar_current_background": "transparent",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "mod": "rgb(210, 153, 29)",
-        "macro": "rgb(9, 189, 0)",
-        "struct": "rgb(45, 191, 184)",
-        "enum": "rgb(45, 191, 184)",
-        "trait": "rgb(183, 140, 242)",
-        "fn": "rgb(43, 171, 99)",
-        "type": "rgb(45, 191, 184)",
-        "union": "rgb(45, 191, 184)",
-        "keyword": "rgb(210, 153, 29)",
-        "sidebar": "rgb(253, 191, 53)",
-        "sidebar_current": "rgb(253, 191, 53)",
-        "sidebar_current_background": "rgb(68, 68, 68)",
+        "mod": "#d2991d",
+        "macro": "#09bd00",
+        "struct": "#2dbfb8",
+        "enum": "#2dbfb8",
+        "trait": "#b78cf2",
+        "fn": "#2bab63",
+        "type": "#2dbfb8",
+        "union": "#2dbfb8",
+        "keyword": "#d2991d",
+        "sidebar": "#fdbf35",
+        "sidebar_current": "#fdbf35",
+        "sidebar_current_background": "#444",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "mod": "rgb(56, 115, 173)",
-        "macro": "rgb(6, 128, 0)",
-        "struct": "rgb(173, 55, 138)",
-        "enum": "rgb(173, 55, 138)",
-        "trait": "rgb(110, 79, 201)",
-        "fn": "rgb(173, 124, 55)",
-        "type": "rgb(173, 55, 138)",
-        "union": "rgb(173, 55, 138)",
-        "keyword": "rgb(56, 115, 173)",
-        "sidebar": "rgb(53, 109, 164)",
-        "sidebar_current": "rgb(53, 109, 164)",
-        "sidebar_current_background": "rgb(255, 255, 255)",
+        "mod": "#3873ad",
+        "macro": "#068000",
+        "struct": "#ad378a",
+        "enum": "#ad378a",
+        "trait": "#6e4fc9",
+        "fn": "#ad7c37",
+        "type": "#ad378a",
+        "union": "#ad378a",
+        "keyword": "#3873ad",
+        "sidebar": "#356da4",
+        "sidebar_current": "#356da4",
+        "sidebar_current_background": "#fff",
     },
 )
diff --git a/tests/ui/check-cfg/values-target-json.stderr b/tests/ui/check-cfg/values-target-json.stderr
index eb81535e3ed..e773d5d83cc 100644
--- a/tests/ui/check-cfg/values-target-json.stderr
+++ b/tests/ui/check-cfg/values-target-json.stderr
@@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")]
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index 2d18cb82e03..1f775814656 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")]
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value
diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs
index 6e04cfaec31..88dff919206 100644
--- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs
+++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs
@@ -1,6 +1,6 @@
 // build-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Func<T> {
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
index 275f6995302..6b2a0153f51 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
@@ -1,4 +1,9 @@
 // check-fail
+// known-bug: #97477
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
 
 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place
 
@@ -27,6 +32,5 @@ where
 }
 
 fn main() {
-    let dst = Inline::<dyn Debug>::new(0); //~ ERROR
-    //~^ ERROR
+    let dst = Inline::<dyn Debug>::new(0);
 }
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
index dc3a400cbaa..79ed82e02e0 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -1,71 +1,10 @@
-error[E0080]: evaluation of `Inline::<dyn Debug>::{constant#0}` failed
+error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:272:21: SizeOf MIR operator called for unsized type dyn Debug
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-   |
-   = note: size_of called on unsized type `dyn Debug`
-   |
-note: inside `std::mem::size_of::<dyn Debug>`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-note: inside `Inline::<dyn Debug>::{constant#0}`
-  --> $DIR/issue-80742.rs:22:10
-   |
-LL |     [u8; size_of::<T>() + 1]: ,
-   |          ^^^^^^^^^^^^^^
-
-error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied
-  --> $DIR/issue-80742.rs:30:36
-   |
-LL | struct Inline<T>
-   | ---------------- function or associated item `new` not found for this struct
-...
-LL |     let dst = Inline::<dyn Debug>::new(0);
-   |                                    ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds
-  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
-   |
-   = note: doesn't satisfy `dyn Debug: Sized`
-   |
-note: trait bound `dyn Debug: Sized` was not satisfied
-  --> $DIR/issue-80742.rs:20:6
-   |
-LL | impl<T> Inline<T>
-   |      ^  ---------
-   |      |
-   |      unsatisfied trait bound introduced here
-help: consider relaxing the type parameter's implicit `Sized` bound
-   |
-LL | impl<T: ?Sized> Inline<T>
-   |       ++++++++
-
-error[E0080]: evaluation of `Inline::<dyn Debug>::{constant#0}` failed
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-   |
-   = note: size_of called on unsized type `dyn Debug`
-   |
-note: inside `std::mem::size_of::<dyn Debug>`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-note: inside `Inline::<dyn Debug>::{constant#0}`
-  --> $DIR/issue-80742.rs:14:10
-   |
-LL |     [u8; size_of::<T>() + 1]: ,
-   |          ^^^^^^^^^^^^^^
-
-error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
-  --> $DIR/issue-80742.rs:30:15
-   |
-LL |     let dst = Inline::<dyn Debug>::new(0);
-   |               ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Debug`
-note: required by a bound in `Inline`
-  --> $DIR/issue-80742.rs:12:15
-   |
-LL | struct Inline<T>
-   |               ^ required by this bound in `Inline`
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | struct Inline<T: ?Sized>
-   |                ++++++++
 
-error: aborting due to 4 previous errors
+Box<dyn Any>
+query stack during panic:
+#0 [eval_to_allocation_raw] const-evaluating + checking `<impl at $DIR/issue-80742.rs:25:1: 25:18>::{constant#0}`
+#1 [eval_to_valtree] evaluating type-level constant
+end of query stack
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0277, E0599.
-For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
index 7f28771cee8..eb71ebb62eb 100644
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -1,11 +1,39 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/unify-op-with-fn-call.rs:10:12
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:18:29
    |
-LL | impl const std::ops::Add for Foo {
-   |            ^^^^^^^^^^^^^
+LL | struct Evaluatable<const N: Foo>;
+   |                             ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
+   |
+
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:20:17
+   |
+LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
+   |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
+   |
+
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:24:17
+   |
+LL | fn bar<const N: Foo>() {}
+   |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/const-generics/lifetime-in-const-param.rs b/tests/ui/const-generics/lifetime-in-const-param.rs
new file mode 100644
index 00000000000..be90dbb213e
--- /dev/null
+++ b/tests/ui/const-generics/lifetime-in-const-param.rs
@@ -0,0 +1,9 @@
+// https://github.com/rust-lang/rust/issues/113462
+
+struct S2<'b>(&'b ());
+
+struct S<'a, const N: S2>(&'a ());
+//~^ ERROR missing lifetime specifier [E0106]
+//~| ERROR `S2<'_>` is forbidden as the type of a const generic parameter
+
+fn main() {}
diff --git a/tests/ui/const-generics/lifetime-in-const-param.stderr b/tests/ui/const-generics/lifetime-in-const-param.stderr
new file mode 100644
index 00000000000..8fd9068e8ef
--- /dev/null
+++ b/tests/ui/const-generics/lifetime-in-const-param.stderr
@@ -0,0 +1,18 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/lifetime-in-const-param.rs:5:23
+   |
+LL | struct S<'a, const N: S2>(&'a ());
+   |                       ^^ expected named lifetime parameter
+
+error: `S2<'_>` is forbidden as the type of a const generic parameter
+  --> $DIR/lifetime-in-const-param.rs:5:23
+   |
+LL | struct S<'a, const N: S2>(&'a ());
+   |                       ^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr
index 37014f9b83f..94f4153a29e 100644
--- a/tests/ui/consts/const-try.stderr
+++ b/tests/ui/consts/const-try.stderr
@@ -1,20 +1,29 @@
-error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
-  --> $DIR/const-try.rs:15:12
+error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions
+  --> $DIR/const-try.rs:33:5
    |
-LL | impl const FromResidual<Error> for TryMe {
-   |            ^^^^^^^^^^^^^^^^^^^
+LL |     TryMe?;
+   |     ^^^^^^
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
-  --> $DIR/const-try.rs:21:12
+note: impl defined here, but it is not `const`
+  --> $DIR/const-try.rs:21:1
    |
 LL | impl const Try for TryMe {
-   |            ^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions
+  --> $DIR/const-try.rs:33:5
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL |     TryMe?;
+   |     ^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/const-try.rs:15:1
+   |
+LL | impl const FromResidual<Error> for TryMe {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs
index a1a741e80e5..2b67c2f2cff 100644
--- a/tests/ui/consts/rustc-impl-const-stability.rs
+++ b/tests/ui/consts/rustc-impl-const-stability.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 #![feature(staged_api)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![stable(feature = "foo", since = "1.0.0")]
 
 #[stable(feature = "potato", since = "1.27.0")]
diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr
index e6930da71ec..ba8e6c1555c 100644
--- a/tests/ui/consts/rustc-impl-const-stability.stderr
+++ b/tests/ui/consts/rustc-impl-const-stability.stderr
@@ -7,5 +7,15 @@ LL | impl const Default for Data {
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to previous error
+error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/rustc-impl-const-stability.rs:15:6
+   |
+LL | impl const Default for Data {
+   |      ^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/generic-associated-types/streaming_iterator.rs b/tests/ui/generic-associated-types/streaming_iterator.rs
index 408b8dc99eb..656fb743ee4 100644
--- a/tests/ui/generic-associated-types/streaming_iterator.rs
+++ b/tests/ui/generic-associated-types/streaming_iterator.rs
@@ -15,8 +15,7 @@ struct Foo<T: StreamingIterator + 'static> {
 
 // Users can bound parameters by the type constructed by that trait's associated type constructor
 // of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid:
-//FIXME(#44265): This next line should parse and be valid
-//fn foo<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(_iter: T) { /* ... */ }
+fn _bar<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(_iter: T) { /* ... */ }
 fn _foo<T>(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ }
 
 // Full example of enumerate iterator
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr
index 4994e4dc444..01ec69a6110 100644
--- a/tests/ui/lifetimes/unusual-rib-combinations.stderr
+++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr
@@ -3,11 +3,6 @@ error[E0106]: missing lifetime specifier
    |
 LL | fn d<const C: S>() {}
    |               ^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL | fn d<'a, const C: S<'a>>() {}
-   |      +++           ++++
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/unusual-rib-combinations.rs:29:22
diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs
index d6b06719277..eeb51196236 100644
--- a/tests/ui/lto/issue-100772.rs
+++ b/tests/ui/lto/issue-100772.rs
@@ -1,6 +1,6 @@
-// run-pass
+// build-pass
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+// compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
 // no-prefer-dynamic
 // only-x86_64-unknown-linux-gnu
 
diff --git a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs
new file mode 100644
index 00000000000..a8a478ffc74
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs
@@ -0,0 +1,11 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type="lib"]
+
+// Issue 111888: this crate (1.) is imported by a proc-macro crate and (2.)
+// exports a no_mangle function; that combination of acts was broken for some
+// period of time. See further discussion in the test file that imports this
+// crate.
+
+#[no_mangle]
+pub fn some_no_mangle_function() { }
diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
new file mode 100644
index 00000000000..4e5208e5058
--- /dev/null
+++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
@@ -0,0 +1,22 @@
+// build-pass
+// force-host
+// no-prefer-dynamic
+// aux-build:exports_no_mangle.rs
+#![crate_type = "proc-macro"]
+
+// Issue #111888: this proc-macro crate imports another crate that itself
+// exports a no_mangle function.
+//
+// That combination was broken for a period of time, because:
+//
+// In PR #99944 we *stopped* exporting no_mangle symbols from
+// proc-macro crates. The constructed linker version script still referred
+// to them, but resolving that discrepancy was left as a FIXME in the code.
+//
+// In PR #108017 we started telling the linker to check (via the
+// `--no-undefined-version` linker invocation flag) that every symbol referenced
+// in the "linker version script" is actually present in the linker input. So
+// the unresolved discrepancy from #99944 started surfacing as a compile-time
+// error.
+
+extern crate exports_no_mangle;
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
index e73082c1127..f40dc27cb4c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait MyTrait {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
index 589e3f02420..687cb128b05 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
index 646955fd867..771c35cf6ab 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait Plus {
@@ -23,7 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
 
 pub const fn add_u32(a: u32, b: u32) -> u32 {
     a.plus(b)
-    //~^ ERROR cannot call
+    //~^ ERROR the trait bound
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
index 0ee1b1a5cb2..2d9c49af85a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
+error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
   --> $DIR/call-const-trait-method-fail.rs:25:7
    |
 LL |     a.plus(b)
-   |       ^^^^^^^
+   |       ^^^^ the trait `Plus` is not implemented for `u32`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `Plus` is implemented for `u32`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
index ff53eea1110..60cd000f2d8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
@@ -1,20 +1,24 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:7:12
+error[E0015]: cannot call non-const fn `<i32 as Plus>::plus` in constant functions
+  --> $DIR/call-const-trait-method-pass.rs:36:7
    |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
+LL |     a.plus(b)
+   |       ^^^^^^^
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:15:12
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/call-const-trait-method-pass.rs:39:22
+   |
+LL | const ADD_INT: Int = Int(1i32) + Int(2i32);
+   |                      ^^^^^^^^^^^^^^^^^^^^^
    |
-LL | impl const PartialEq for Int {
-   |            ^^^^^^^^^
+note: impl defined here, but it is not `const`
+  --> $DIR/call-const-trait-method-pass.rs:7:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const std::ops::Add for Int {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
index 529a472e0bd..37faa3f6bce 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-chain.rs:9:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-chain.rs:18:32
    |
@@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
    |                                        ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
index bdc6ccc8aec..90cfe04a9a8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-dup-bound.rs:7:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-dup-bound.rs:18:44
    |
@@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
    |                                     ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
index 7fbe89dba3c..bea1846e79b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
@@ -1,17 +1,8 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-pass.rs:9:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-pass.rs:18:32
    |
 LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
    |                                ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
index 4f858d61eeb..54bc4347722 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
@@ -1,20 +1,25 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:7:12
+error[E0117]: only traits defined in the current crate can be implemented for primitive types
+  --> $DIR/const-and-non-const-impl.rs:7:1
    |
 LL | impl const std::ops::Add for i32 {
-   |            ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^-------------^^^^^---
+   | |          |                 |
+   | |          |                 `i32` is not defined in the current crate
+   | |          `i32` is not defined in the current crate
+   | impl doesn't use only types from inside the current crate
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: define and implement a trait or new type instead
 
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:23:12
+error[E0119]: conflicting implementations of trait `Add` for type `Int`
+  --> $DIR/const-and-non-const-impl.rs:23:1
    |
+LL | impl std::ops::Add for Int {
+   | -------------------------- first implementation here
+...
 LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int`
 
 error: aborting due to 2 previous errors
 
+Some errors have detailed explanations: E0117, E0119.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
index 52984fb6be4..4854f41bf04 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 struct S;
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
index 3370f32061c..be668b4f13a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait ConstDefaultFn: Sized {
@@ -22,7 +22,7 @@ impl const ConstDefaultFn for ConstImpl {
 
 const fn test() {
     NonConstImpl.a();
-    //~^ ERROR cannot call
+    //~^ ERROR the trait bound
     ConstImpl.a();
 }
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
index 414688f71ed..7b558e3f773 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
+error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
   --> $DIR/const-default-method-bodies.rs:24:18
    |
 LL |     NonConstImpl.a();
-   |                  ^^^
+   |                  ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
index 3de9d37d493..747ccbf0fab 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
@@ -18,6 +18,10 @@ trait A { fn a() { } }
 
 impl A for NonTrivialDrop {}
 
+const fn check<T: ~const Destruct>(_: T) {}
+
+
+/* FIXME(effects)
 struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
 
 impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
@@ -26,11 +30,10 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
     }
 }
 
-const fn check<T: ~const Destruct>(_: T) {}
-
 const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
     ConstDropImplWithBounds(PhantomData)
 );
+*/
 
 struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
index 7de33003c48..100d1df87d6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
@@ -1,28 +1,11 @@
-error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
-  --> $DIR/const-drop-fail-2.rs:25:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop-fail-2.rs:29:36
+  --> $DIR/const-drop-fail-2.rs:21:36
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                                    ^      - value is dropped here
    |                                    |
    |                                    the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
-  --> $DIR/const-drop-fail-2.rs:39:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
index b28584e7e36..23e36887025 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
@@ -14,15 +14,6 @@ LL |     let _ = S(&mut c);
    |             |
    |             the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
-  --> $DIR/const-drop.rs:70:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
index b28584e7e36..23e36887025 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
@@ -14,15 +14,6 @@ LL |     let _ = S(&mut c);
    |             |
    |             the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
-  --> $DIR/const-drop.rs:70:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
index 2b4963991db..fc3a83876c5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
@@ -1,9 +1,11 @@
-#![feature(const_trait_impl)]
+// known-bug: #110395
+
+#![feature(const_trait_impl, effects)]
 
 pub trait A {}
-//~^ HELP: mark `A` as const
+// FIXME ~^ HELP: mark `A` as const
 
 impl const A for () {}
-//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
+// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
index 478adcf3e9e..c45af1a9f8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
@@ -1,5 +1,5 @@
 error: const `impl` for trait `A` which is not marked with `#[const_trait]`
-  --> $DIR/const-impl-requires-const-trait.rs:6:12
+  --> $DIR/const-impl-requires-const-trait.rs:8:12
    |
 LL | pub trait A {}
    | - help: mark `A` as const: `#[const_trait]`
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
index dba3ad7f870..348ca0ab190 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
@@ -1,5 +1,4 @@
 #[derive_const(Default)] //~ ERROR use of unstable library feature
-//~^ ERROR not marked with `#[const_trait]`
 pub struct S;
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
index 6a81f96d88d..cc9bdd2715f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
@@ -6,16 +6,6 @@ LL | #[derive_const(Default)]
    |
    = help: add `#![feature(derive_const)]` to the crate attributes to enable
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-gate.rs:1:16
-   |
-LL | #[derive_const(Default)]
-   |                ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
index b575ea8dae2..ce39045d71b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
@@ -1,5 +1,5 @@
 // known-bug: #110395
-#![feature(derive_const)]
+#![feature(derive_const, effects)]
 
 pub struct A;
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
index 88054096e63..046dbae0eae 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
@@ -10,44 +10,6 @@ error[E0635]: unknown feature `const_default_impls`
 LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
    |                                         ^^^^^^^^^^^^^^^^^^^
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:6:12
-   |
-LL | impl const Default for A {
-   |            ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:10:12
-   |
-LL | impl const PartialEq for A {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:14:16
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:14:25
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                         ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0635`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
index fa78326587c..37d123e4ccc 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
@@ -1,13 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-with-params.rs:6:16
-   |
-LL | #[derive_const(PartialEq)]
-   |                ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/derive-const-with-params.rs:6:16
    |
@@ -16,5 +6,5 @@ LL | #[derive_const(PartialEq)]
    |
    = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
index c936270de26..428286e0b12 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
   --> $DIR/cross-crate.rs:17:14
    |
 LL |     NonConst.func();
-   |              ^^^^^^
+   |              ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
index 1f78af79418..95edbdc0efa 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
@@ -1,6 +1,6 @@
 // revisions: stock gated stocknc gatednc
 // [gated] check-pass
-#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))]
+#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))]
 
 // aux-build: cross-crate.rs
 extern crate cross_crate;
@@ -16,7 +16,7 @@ const fn const_context() {
     #[cfg(any(stocknc, gatednc))]
     NonConst.func();
     //[stocknc]~^ ERROR: cannot call
-    //[gatednc]~^^ ERROR: cannot call
+    //[gatednc]~^^ ERROR: the trait bound
     Const.func();
     //[stock]~^ ERROR: cannot call
     //[stocknc]~^^ ERROR: cannot call
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
index c21c73f40f2..a6881b8fed5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `(): Tr` is not satisfied
+error[E0277]: the trait bound `(): ~const Tr` is not satisfied
   --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
    |
 LL |         ().a()
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
index 730e268c091..5a0db816a2b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
@@ -1,5 +1,5 @@
 // check-pass
-#![feature(const_trait_impl, rustc_attrs)]
+#![feature(const_trait_impl, rustc_attrs, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
index 49457354cc9..e7ba0505d9b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
@@ -7,7 +7,7 @@
 
 // ensure we are passing in the correct host effect in always const contexts.
 
-pub const fn hmm</* T, */ #[rustc_host] const host: bool = true>() -> usize {
+pub const fn hmm<T, #[rustc_host] const host: bool = true>() -> usize {
     if host {
         1
     } else {
@@ -16,14 +16,12 @@ pub const fn hmm</* T, */ #[rustc_host] const host: bool = true>() -> usize {
 }
 
 const _: () = {
-    let x = hmm();
+    let x = hmm::<()>();
     assert!(0 == x);
 };
 
-/* FIXME(effects)
 pub const fn uwu(x: [u8; hmm::<()>()]) {
     let [] = x;
 }
-*/
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
index 1b21d7c0e0e..6a177592b64 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
@@ -1,11 +1,16 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/generic-bound.rs:16:15
+error[E0015]: cannot call non-const operator in constant functions
+  --> $DIR/generic-bound.rs:25:5
    |
-LL | impl<T> const std::ops::Add for S<T> {
-   |               ^^^^^^^^^^^^^
+LL |     arg + arg
+   |     ^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/generic-bound.rs:16:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl<T> const std::ops::Add for S<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
index 337c733403b..426534deb67 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
@@ -1,6 +1,6 @@
 // Regression test for #69615.
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait MyTrait {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
index a3bb9b3f93e..9a93d01ed06 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -1,6 +1,6 @@
 // Tests that specializing trait impls must be at least as const as the default impl.
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(min_specialization)]
 
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
index 0a28da9e65e..7206a89e5c5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl, min_specialization, rustc_attrs)]
+#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)]
 
 #[rustc_specialization_trait]
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
index 1d79f5adf93..b3977e6cede 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
@@ -1,7 +1,7 @@
 // revisions: stable unstable
 
 #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file.
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
index 35dc1ca129b..deed05ae179 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
@@ -1,20 +1,29 @@
-error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
-  --> $DIR/trait-default-body-stability.rs:18:12
+error[E0015]: `?` cannot determine the branch of `T` in constant functions
+  --> $DIR/trait-default-body-stability.rs:44:9
    |
-LL | impl const Try for T {
-   |            ^^^
+LL |         T?
+   |         ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/trait-default-body-stability.rs:18:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const Try for T {
+   | ^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
-  --> $DIR/trait-default-body-stability.rs:33:12
+error[E0015]: `?` cannot convert from residual of `T` in constant functions
+  --> $DIR/trait-default-body-stability.rs:44:9
    |
-LL | impl const FromResidual for T {
-   |            ^^^^^^^^^^^^
+LL |         T?
+   |         ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/trait-default-body-stability.rs:33:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const FromResidual for T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
index 29809a2ee56..6e1074035b7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
@@ -1,7 +1,7 @@
 // known-bug: #110395
 // FIXME run-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Bar {
diff --git a/tests/ui/sanitize/issue-111184-generator-witness.rs b/tests/ui/sanitize/issue-111184-generator-witness.rs
index 8f4118057ce..d36d8bce561 100644
--- a/tests/ui/sanitize/issue-111184-generator-witness.rs
+++ b/tests/ui/sanitize/issue-111184-generator-witness.rs
@@ -2,10 +2,10 @@
 // encode_ty and caused the compiler to ICE.
 //
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
+// compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
 // no-prefer-dynamic
 // only-x86_64-unknown-linux-gnu
-// run-pass
+// build-pass
 
 use std::future::Future;
 
diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
index 29e32889fcc..e9a49dd3ff1 100644
--- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
+++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
@@ -1,4 +1,4 @@
-// Verifies that `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`.
+// Verifies that `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`.
 //
 // needs-sanitizer-cfi
 // compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
index 5e706b513b9..8cd9c544417 100644
--- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
+++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
@@ -1,4 +1,4 @@
-error: `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`
+error: `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs
new file mode 100644
index 00000000000..a13c12c1787
--- /dev/null
+++ b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs
@@ -0,0 +1,8 @@
+// Verifies that `-Zsanitizer=cfi` with `-Clto` or `-Clto=thin` requires `-Ccodegen-units=1`.
+//
+// needs-sanitizer-cfi
+// compile-flags: -Ccodegen-units=2 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr
new file mode 100644
index 00000000000..136f4936084
--- /dev/null
+++ b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr
@@ -0,0 +1,4 @@
+error: `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 6eff899bfbf..621e8576249 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -1,5 +1,5 @@
 #![feature(staged_api)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![stable(feature = "stable", since = "1.0.0")]
 
 #[stable(feature = "stable", since = "1.0.0")]
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
new file mode 100644
index 00000000000..f06b98a79cf
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
@@ -0,0 +1,46 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs, trivial_bounds)]
+
+// We have to be careful here:
+//
+// We either have the provisional result of `A -> B -> A` on the
+// stack, which is a fully coinductive cycle. Accessing the
+// provisional result for `B` as part of the `A -> C -> B -> A` cycle
+// has to make sure we don't just use the result of `A -> B -> A` as the
+// new cycle is inductive.
+//
+// Alternatively, if we have `A -> C -> A` first, then `A -> B -> A` has
+// a purely inductive stack, so something could also go wrong here.
+
+#[rustc_coinductive]
+trait A {}
+#[rustc_coinductive]
+trait B {}
+trait C {}
+
+impl<T: B + C> A for T {}
+impl<T: A> B for T {}
+impl<T: B> C for T {}
+
+fn impls_a<T: A>() {}
+
+// The same test with reordered where clauses to make sure we're actually testing anything.
+#[rustc_coinductive]
+trait AR {}
+#[rustc_coinductive]
+trait BR {}
+trait CR {}
+
+impl<T: CR + BR> AR for T {}
+impl<T: AR> BR for T {}
+impl<T: BR> CR for T {}
+
+fn impls_ar<T: AR>() {}
+
+fn main() {
+    impls_a::<()>();
+    //~^ ERROR overflow evaluating the requirement `(): A`
+
+    impls_ar::<()>();
+    //~^ ERROR overflow evaluating the requirement `(): AR`
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
new file mode 100644
index 00000000000..33fac603cbd
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
@@ -0,0 +1,29 @@
+error[E0275]: overflow evaluating the requirement `(): A`
+  --> $DIR/inductive-not-on-stack.rs:41:5
+   |
+LL |     impls_a::<()>();
+   |     ^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
+note: required by a bound in `impls_a`
+  --> $DIR/inductive-not-on-stack.rs:25:15
+   |
+LL | fn impls_a<T: A>() {}
+   |               ^ required by this bound in `impls_a`
+
+error[E0275]: overflow evaluating the requirement `(): AR`
+  --> $DIR/inductive-not-on-stack.rs:44:5
+   |
+LL |     impls_ar::<()>();
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
+note: required by a bound in `impls_ar`
+  --> $DIR/inductive-not-on-stack.rs:38:16
+   |
+LL | fn impls_ar<T: AR>() {}
+   |                ^^ required by this bound in `impls_ar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.