about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-22 06:31:10 +0000
committerbors <bors@rust-lang.org>2024-09-22 06:31:10 +0000
commitee20c8628224ceae61f5f3dac98a18ede8872571 (patch)
treed6de38b7510e7603d988ab5b33a317d201f32070
parenta3fea24971e748914354acaf90033bbe594a4fa5 (diff)
parentd877ec2a3e7235c32e0fd094fb1cf813586b2665 (diff)
downloadrust-ee20c8628224ceae61f5f3dac98a18ede8872571.tar.gz
rust-ee20c8628224ceae61f5f3dac98a18ede8872571.zip
Auto merge of #3902 - RalfJung:rustup, r=RalfJung
Rustup
-rw-r--r--compiler/rustc_abi/src/lib.rs10
-rw-r--r--compiler/rustc_ast/src/ast.rs11
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs29
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs80
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs26
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0775.md7
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0776.md4
-rw-r--r--compiler/rustc_error_codes/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/expand.rs12
-rw-r--r--compiler/rustc_expand/src/module.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs4
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl6
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs67
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs181
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs336
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs128
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs3
-rw-r--r--compiler/rustc_lint/src/types.rs5
-rw-r--r--compiler/rustc_middle/messages.ftl2
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs4
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs13
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs11
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs85
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs24
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs104
-rw-r--r--compiler/rustc_resolve/src/late.rs40
-rw-r--r--compiler/rustc_resolve/src/lib.rs5
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/abi.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs1
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs2
-rw-r--r--compiler/rustc_target/src/json.rs1
-rw-r--r--compiler/rustc_target/src/spec/abi/mod.rs23
-rw-r--r--compiler/rustc_target/src/spec/mod.rs5
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs4
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs1
-rw-r--r--compiler/stable_mir/src/abi.rs1
-rw-r--r--compiler/stable_mir/src/ty.rs1
-rw-r--r--library/alloc/src/string.rs26
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/string.rs37
-rw-r--r--library/core/src/primitive_docs.rs2
-rw-r--r--src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile2
-rw-r--r--src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md8
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/rustfmt.toml2
-rw-r--r--src/tools/miri/tests/fail/type-too-large.stderr4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs1
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs1
-rw-r--r--src/tools/tidy/src/issues.txt3
-rw-r--r--tests/assembly/cmse.rs26
-rw-r--r--tests/codegen/constant-branch.rs14
-rw-r--r--tests/codegen/no-alloca-inside-if-false.rs27
-rw-r--r--tests/crashes/125476.rs2
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs18
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr39
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bare-path.rs5
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr51
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs52
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.stderr11
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.rs42
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.stderr11
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs7
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr19
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/not-a-method.rs42
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/not-a-method.stderr49
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.rs27
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.stderr54
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.rs24
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.stderr11
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.rs25
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.stderr34
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-missing.rs25
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr33
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-no-qself.rs15
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-no-qself.stderr23
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.rs21
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.stderr30
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-self-qself.rs27
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-self-qself.stderr11
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-type-param.rs22
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-type-param.stderr29
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.rs25
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.stderr36
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-works.rs23
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/path-works.stderr11
-rw-r--r--tests/ui/attributes/issue-105594-invalid-attr-validation.rs6
-rw-r--r--tests/ui/attributes/issue-105594-invalid-attr-validation.stderr21
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs20
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.rs7
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.stderr18
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs9
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr11
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs12
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs17
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr9
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs25
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr9
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr9
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr9
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs16
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr9
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.rs14
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.stderr14
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.rs15
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr15
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.rs15
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr15
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-nested-braces.rs9
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr11
-rw-r--r--tests/ui/const-generics/issue-112505-overflow.rs7
-rw-r--r--tests/ui/const-generics/issue-112505-overflow.stderr12
-rw-r--r--tests/ui/const-generics/transmute-fail.rs10
-rw-r--r--tests/ui/const-generics/transmute-fail.stderr43
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs2
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr2
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs2
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr2
-rw-r--r--tests/ui/extern/extern-static-size-overflow.rs30
-rw-r--r--tests/ui/extern/extern-static-size-overflow.stderr12
-rw-r--r--tests/ui/layout/size-of-val-raw-too-big.rs2
-rw-r--r--tests/ui/layout/size-of-val-raw-too-big.stderr2
-rw-r--r--tests/ui/layout/too-big-with-padding.rs2
-rw-r--r--tests/ui/layout/too-big-with-padding.stderr2
-rw-r--r--tests/ui/limits/huge-array-simple-32.rs2
-rw-r--r--tests/ui/limits/huge-array-simple-32.stderr2
-rw-r--r--tests/ui/limits/huge-array-simple-64.rs2
-rw-r--r--tests/ui/limits/huge-array-simple-64.stderr2
-rw-r--r--tests/ui/limits/huge-array.stderr2
-rw-r--r--tests/ui/limits/huge-enum.rs4
-rw-r--r--tests/ui/limits/huge-enum.stderr2
-rw-r--r--tests/ui/limits/huge-static.rs (renamed from tests/ui/limits/issue-56762.rs)7
-rw-r--r--tests/ui/limits/huge-static.stderr (renamed from tests/ui/limits/issue-56762.stderr)8
-rw-r--r--tests/ui/limits/huge-struct.rs6
-rw-r--r--tests/ui/limits/huge-struct.stderr4
-rw-r--r--tests/ui/limits/issue-15919-32.stderr2
-rw-r--r--tests/ui/limits/issue-15919-64.stderr2
-rw-r--r--tests/ui/limits/issue-17913.rs2
-rw-r--r--tests/ui/limits/issue-17913.stderr2
-rw-r--r--tests/ui/limits/issue-55878.rs2
-rw-r--r--tests/ui/limits/issue-55878.stderr2
-rw-r--r--tests/ui/limits/issue-69485-var-size-diffs-too-large.rs2
-rw-r--r--tests/ui/limits/issue-69485-var-size-diffs-too-large.stderr2
-rw-r--r--tests/ui/limits/issue-75158-64.stderr2
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin2.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin3.rs8
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.stderr14
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.rs7
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.stderr14
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr (renamed from tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.stderr)4
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr (renamed from tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.stderr)4
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr (renamed from tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.stderr)4
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr (renamed from tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.stderr)4
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr14
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs29
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr14
-rw-r--r--tests/ui/lint/rust-cold-fn-accept-improper-ctypes.rs14
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs6
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr8
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs6
-rw-r--r--tests/ui/print-calling-conventions.stdout1
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs1
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr14
-rw-r--r--tests/ui/suggestions/let-binding-init-expr-as-ty.rs4
-rw-r--r--tests/ui/suggestions/let-binding-init-expr-as-ty.stderr23
-rw-r--r--tests/ui/transmutability/arrays/huge-len.stderr4
191 files changed, 2412 insertions, 746 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 7bd2507d1ad..904c5933a18 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -337,23 +337,21 @@ impl TargetDataLayout {
         Ok(dl)
     }
 
-    /// Returns exclusive upper bound on object size.
+    /// Returns **exclusive** upper bound on object size in bytes.
     ///
     /// The theoretical maximum object size is defined as the maximum positive `isize` value.
     /// This ensures that the `offset` semantics remain well-defined by allowing it to correctly
     /// index every address within an object along with one byte past the end, along with allowing
     /// `isize` to store the difference between any two pointers into an object.
     ///
-    /// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer
-    /// to represent object size in bits. It would need to be 1 << 61 to account for this, but is
-    /// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
-    /// address space on 64-bit ARMv8 and x86_64.
+    /// LLVM uses a 64-bit integer to represent object size in *bits*, but we care only for bytes,
+    /// so we adopt such a more-constrained size bound due to its technical limitations.
     #[inline]
     pub fn obj_size_bound(&self) -> u64 {
         match self.pointer_size.bits() {
             16 => 1 << 15,
             32 => 1 << 31,
-            64 => 1 << 47,
+            64 => 1 << 61,
             bits => panic!("obj_size_bound: unknown pointer bit size {bits}"),
         }
     }
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index ac65b7b22bc..d49265de202 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1187,8 +1187,8 @@ impl Expr {
     /// `min_const_generics` as more complex expressions are not supported.
     ///
     /// Does not ensure that the path resolves to a const param, the caller should check this.
-    pub fn is_potential_trivial_const_arg(&self) -> bool {
-        let this = self.maybe_unwrap_block();
+    pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool {
+        let this = if strip_identity_block { self.maybe_unwrap_block().1 } else { self };
 
         if let ExprKind::Path(None, path) = &this.kind
             && path.is_potential_trivial_const_arg()
@@ -1199,14 +1199,15 @@ impl Expr {
         }
     }
 
-    pub fn maybe_unwrap_block(&self) -> &Expr {
+    /// Returns an expression with (when possible) *one* outter brace removed
+    pub fn maybe_unwrap_block(&self) -> (bool, &Expr) {
         if let ExprKind::Block(block, None) = &self.kind
             && let [stmt] = block.stmts.as_slice()
             && let StmtKind::Expr(expr) = &stmt.kind
         {
-            expr
+            (true, expr)
         } else {
-            self
+            (false, self)
         }
     }
 
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index a9d1ee5c9c1..11867c39e02 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -20,8 +20,8 @@ use super::errors::{
 };
 use super::LoweringContext;
 use crate::{
-    fluent_generated as fluent, ImplTraitContext, ImplTraitPosition, ParamMode,
-    ResolverAstLoweringExt,
+    fluent_generated as fluent, AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition,
+    ParamMode, ResolverAstLoweringExt,
 };
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
@@ -201,6 +201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 &sym.qself,
                                 &sym.path,
                                 ParamMode::Optional,
+                                AllowReturnTypeNotation::No,
                                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                                 None,
                             );
@@ -220,7 +221,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             let parent_def_id = self.current_def_id_parent;
                             let node_id = self.next_node_id();
                             // HACK(min_generic_const_args): see lower_anon_const
-                            if !expr.is_potential_trivial_const_arg() {
+                            if !expr.is_potential_trivial_const_arg(true) {
                                 self.create_def(
                                     parent_def_id,
                                     node_id,
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index ac527df474a..97483e85f77 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -52,7 +52,7 @@ use rustc_target::spec::abi;
 use {rustc_ast as ast, rustc_hir as hir};
 
 use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
-use crate::{ImplTraitPosition, ResolverAstLoweringExt};
+use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
 
 pub(crate) struct DelegationResults<'hir> {
     pub body_id: hir::BodyId,
@@ -340,6 +340,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 &delegation.qself,
                 &delegation.path,
                 ParamMode::Optional,
+                AllowReturnTypeNotation::No,
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index e105026ebd1..d828c9856b9 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -23,7 +23,7 @@ use super::{
     GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
 };
 use crate::errors::YieldInClosure;
-use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
+use crate::{fluent_generated, AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition};
 
 impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
@@ -281,6 +281,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
+                        AllowReturnTypeNotation::No,
                         ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                     );
@@ -328,6 +329,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.qself,
                             &se.path,
                             ParamMode::Optional,
+                            AllowReturnTypeNotation::No,
                             ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         )),
@@ -387,7 +389,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let node_id = self.next_node_id();
 
                 // HACK(min_generic_const_args): see lower_anon_const
-                if !arg.is_potential_trivial_const_arg() {
+                if !arg.is_potential_trivial_const_arg(true) {
                     // Add a definition for the in-band const def.
                     self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
                 }
@@ -1291,6 +1293,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
+                        AllowReturnTypeNotation::No,
                         ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                     );
@@ -1311,6 +1314,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
+                        AllowReturnTypeNotation::No,
                         ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                     );
@@ -1336,6 +1340,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.qself,
                     &se.path,
                     ParamMode::Optional,
+                    AllowReturnTypeNotation::No,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     None,
                 );
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index efd3ae336af..3f48fe67dbb 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -485,9 +485,23 @@ enum ParamMode {
     Optional,
 }
 
+#[derive(Copy, Clone, Debug)]
+enum AllowReturnTypeNotation {
+    /// Only in types, since RTN is denied later during HIR lowering.
+    Yes,
+    /// All other positions (path expr, method, use tree).
+    No,
+}
+
 enum GenericArgsMode {
+    /// Allow paren sugar, don't allow RTN.
     ParenSugar,
+    /// Allow RTN, don't allow paren sugar.
+    ReturnTypeNotation,
+    // Error if parenthesized generics or RTN are encountered.
     Err,
+    /// Silence errors when lowering generics. Only used with `Res::Err`.
+    Silence,
 }
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
@@ -1226,7 +1240,15 @@ 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, None);
+        let qpath = self.lower_qpath(
+            t.id,
+            qself,
+            path,
+            param_mode,
+            AllowReturnTypeNotation::Yes,
+            itctx,
+            None,
+        );
         self.ty_path(id, t.span, qpath)
     }
 
@@ -2203,6 +2225,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             &None,
             &p.path,
             ParamMode::Explicit,
+            AllowReturnTypeNotation::No,
             itctx,
             Some(modifiers),
         ) {
@@ -2341,6 +2364,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     &None,
                     path,
                     ParamMode::Optional,
+                    AllowReturnTypeNotation::No,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     None,
                 );
@@ -2419,6 +2443,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 qself,
                 path,
                 ParamMode::Optional,
+                AllowReturnTypeNotation::No,
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
@@ -2441,7 +2466,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     /// See [`hir::ConstArg`] for when to use this function vs
     /// [`Self::lower_anon_const_to_const_arg`].
     fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
-        if c.value.is_potential_trivial_const_arg() {
+        if c.value.is_potential_trivial_const_arg(true) {
             // HACK(min_generic_const_args): see DefCollector::visit_anon_const
             // Over there, we guess if this is a bare param and only create a def if
             // we think it's not. However we may can guess wrong (see there for example)
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index d82bdd526b7..584d94ebe2d 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -11,7 +11,7 @@ use super::errors::{
     ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
 };
 use super::{ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt};
-use crate::ImplTraitPosition;
+use crate::{AllowReturnTypeNotation, ImplTraitPosition};
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> {
@@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
+                            AllowReturnTypeNotation::No,
                             ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         );
@@ -55,6 +56,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
+                            AllowReturnTypeNotation::No,
                             ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         );
@@ -66,6 +68,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
+                            AllowReturnTypeNotation::No,
                             ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         );
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 2ab30eff6d8..03c8097e4c3 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -5,6 +5,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::GenericArg;
 use rustc_middle::span_bug;
+use rustc_session::parse::add_feature_diagnostics;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{BytePos, DesugaringKind, Span, Symbol, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
@@ -15,10 +16,9 @@ use super::errors::{
     GenericTypeWithParentheses, UseAngleBrackets,
 };
 use super::{
-    GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
-    ResolverAstLoweringExt,
+    AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition,
+    LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt,
 };
-use crate::ImplTraitPosition;
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     #[instrument(level = "trace", skip(self))]
@@ -28,6 +28,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         qself: &Option<ptr::P<QSelf>>,
         p: &Path,
         param_mode: ParamMode,
+        allow_return_type_notation: AllowReturnTypeNotation,
         itctx: ImplTraitContext,
         // modifiers of the impl/bound if this is a trait path
         modifiers: Option<ast::TraitBoundModifiers>,
@@ -103,8 +104,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         {
                             GenericArgsMode::ParenSugar
                         }
+                        Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => {
+                            match allow_return_type_notation {
+                                AllowReturnTypeNotation::Yes => GenericArgsMode::ReturnTypeNotation,
+                                AllowReturnTypeNotation::No => GenericArgsMode::Err,
+                            }
+                        }
                         // Avoid duplicated errors.
-                        Res::Err => GenericArgsMode::ParenSugar,
+                        Res::Err => GenericArgsMode::Silence,
                         // An error
                         _ => GenericArgsMode::Err,
                     };
@@ -164,11 +171,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
+            // If this is a type-dependent `T::method(..)`.
+            let generic_args_mode = if i + 1 == p.segments.len()
+                && matches!(allow_return_type_notation, AllowReturnTypeNotation::Yes)
+            {
+                GenericArgsMode::ReturnTypeNotation
+            } else {
+                GenericArgsMode::Err
+            };
+
             let hir_segment = self.arena.alloc(self.lower_path_segment(
                 p.span,
                 segment,
                 param_mode,
-                GenericArgsMode::Err,
+                generic_args_mode,
                 itctx,
                 None,
             ));
@@ -238,11 +254,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                 }
                 GenericArgs::Parenthesized(data) => match generic_args_mode {
-                    GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data(
-                        data,
-                        itctx,
-                        bound_modifier_allowed_features,
-                    ),
+                    GenericArgsMode::ReturnTypeNotation => {
+                        let mut err = if !data.inputs.is_empty() {
+                            self.dcx().create_err(BadReturnTypeNotation::Inputs {
+                                span: data.inputs_span,
+                            })
+                        } else if let FnRetTy::Ty(ty) = &data.output {
+                            self.dcx().create_err(BadReturnTypeNotation::Output {
+                                span: data.inputs_span.shrink_to_hi().to(ty.span),
+                            })
+                        } else {
+                            self.dcx().create_err(BadReturnTypeNotation::NeedsDots {
+                                span: data.inputs_span,
+                            })
+                        };
+                        if !self.tcx.features().return_type_notation
+                            && self.tcx.sess.is_nightly_build()
+                        {
+                            add_feature_diagnostics(
+                                &mut err,
+                                &self.tcx.sess,
+                                sym::return_type_notation,
+                            );
+                        }
+                        err.emit();
+                        (
+                            GenericArgsCtor {
+                                args: Default::default(),
+                                constraints: &[],
+                                parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
+                                span: path_span,
+                            },
+                            false,
+                        )
+                    }
+                    GenericArgsMode::ParenSugar | GenericArgsMode::Silence => self
+                        .lower_parenthesized_parameter_data(
+                            data,
+                            itctx,
+                            bound_modifier_allowed_features,
+                        ),
                     GenericArgsMode::Err => {
                         // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
                         let sub = if !data.inputs.is_empty() {
@@ -279,7 +330,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }
                 },
                 GenericArgs::ParenthesizedElided(span) => {
-                    self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
+                    match generic_args_mode {
+                        GenericArgsMode::ReturnTypeNotation | GenericArgsMode::Silence => {
+                            // Ok
+                        }
+                        GenericArgsMode::ParenSugar | GenericArgsMode::Err => {
+                            self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
+                        }
+                    }
                     (
                         GenericArgsCtor {
                             args: Default::default(),
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 24cf3f061a5..8838b15d29d 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -61,6 +61,9 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
         Conv::CCmseNonSecureCall => {
             sess.dcx().fatal("C-cmse-nonsecure-call call conv is not yet implemented");
         }
+        Conv::CCmseNonSecureEntry => {
+            sess.dcx().fatal("C-cmse-nonsecure-entry call conv is not yet implemented");
+        }
 
         Conv::Msp430Intr | Conv::PtxKernel | Conv::AvrInterrupt | Conv::AvrNonBlockingInterrupt => {
             unreachable!("tried to use {c:?} call conv which only exists on an unsupported target");
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 26718792f5f..0fa8c9d3f19 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -422,6 +422,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
         if let Conv::RiscvInterrupt { kind } = self.conv {
             func_attrs.push(llvm::CreateAttrStringValue(cx.llcx, "interrupt", kind.as_str()));
         }
+        if let Conv::CCmseNonSecureEntry = self.conv {
+            func_attrs.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"))
+        }
         attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &{ func_attrs });
 
         let mut i = 0;
@@ -659,9 +662,11 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
 impl From<Conv> for llvm::CallConv {
     fn from(conv: Conv) -> Self {
         match conv {
-            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall | Conv::RiscvInterrupt { .. } => {
-                llvm::CCallConv
-            }
+            Conv::C
+            | Conv::Rust
+            | Conv::CCmseNonSecureCall
+            | Conv::CCmseNonSecureEntry
+            | Conv::RiscvInterrupt { .. } => llvm::CCallConv,
             Conv::Cold => llvm::ColdCallConv,
             Conv::PreserveMost => llvm::PreserveMost,
             Conv::PreserveAll => llvm::PreserveAll,
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 6df63eec513..489259da856 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -483,9 +483,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
         attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
     }
-    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) {
-        to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"));
-    }
     if let Some(align) = codegen_fn_attrs.alignment {
         llvm::set_alignment(llfn, align);
     }
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 137e481f08c..9bd8a84f5a3 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -195,24 +195,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     }
                 }
             }
-            sym::cmse_nonsecure_entry => {
-                if let Some(fn_sig) = fn_sig()
-                    && !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. })
-                {
-                    struct_span_code_err!(
-                        tcx.dcx(),
-                        attr.span,
-                        E0776,
-                        "`#[cmse_nonsecure_entry]` requires C ABI"
-                    )
-                    .emit();
-                }
-                if !tcx.sess.target.llvm_target.contains("thumbv8m") {
-                    struct_span_code_err!(tcx.dcx(), attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension")
-                    .emit();
-                }
-                codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY
-            }
             sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
             sym::track_caller => {
                 let is_closure = tcx.is_closure_like(did.to_def_id());
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index f13c46e8bef..25712095e76 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -15,6 +15,7 @@ use crate::traits::*;
 
 pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     fx: &FunctionCx<'a, 'tcx, Bx>,
+    traversal_order: &[mir::BasicBlock],
 ) -> BitSet<mir::Local> {
     let mir = fx.mir;
     let dominators = mir.basic_blocks.dominators();
@@ -24,13 +25,7 @@ pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         .map(|decl| {
             let ty = fx.monomorphize(decl.ty);
             let layout = fx.cx.spanned_layout_of(ty, decl.source_info.span);
-            if layout.is_zst() {
-                LocalKind::ZST
-            } else if fx.cx.is_backend_immediate(layout) || fx.cx.is_backend_scalar_pair(layout) {
-                LocalKind::Unused
-            } else {
-                LocalKind::Memory
-            }
+            if layout.is_zst() { LocalKind::ZST } else { LocalKind::Unused }
         })
         .collect();
 
@@ -44,7 +39,8 @@ pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     // If there exists a local definition that dominates all uses of that local,
     // the definition should be visited first. Traverse blocks in an order that
     // is a topological sort of dominance partial order.
-    for (bb, data) in traversal::reverse_postorder(mir) {
+    for bb in traversal_order.iter().copied() {
+        let data = &mir.basic_blocks[bb];
         analyzer.visit_basic_block_data(bb, data);
     }
 
@@ -77,11 +73,22 @@ struct LocalAnalyzer<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> {
 
 impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> {
     fn define(&mut self, local: mir::Local, location: DefLocation) {
+        let fx = self.fx;
         let kind = &mut self.locals[local];
+        let decl = &fx.mir.local_decls[local];
         match *kind {
             LocalKind::ZST => {}
             LocalKind::Memory => {}
-            LocalKind::Unused => *kind = LocalKind::SSA(location),
+            LocalKind::Unused => {
+                let ty = fx.monomorphize(decl.ty);
+                let layout = fx.cx.spanned_layout_of(ty, decl.source_info.span);
+                *kind =
+                    if fx.cx.is_backend_immediate(layout) || fx.cx.is_backend_scalar_pair(layout) {
+                        LocalKind::SSA(location)
+                    } else {
+                        LocalKind::Memory
+                    };
+            }
             LocalKind::SSA(_) => *kind = LocalKind::Memory,
         }
     }
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 61e9b9bd774..68fb5cb2206 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -218,7 +218,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
     fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
 
-    let memory_locals = analyze::non_ssa_locals(&fx);
+    let traversal_order = traversal::mono_reachable_reverse_postorder(mir, cx.tcx(), instance);
+    let memory_locals = analyze::non_ssa_locals(&fx, &traversal_order);
 
     // Allocate variable and temp allocas
     let local_values = {
@@ -277,17 +278,20 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     // So drop the builder of `start_llbb` to avoid having two at the same time.
     drop(start_bx);
 
-    let reachable_blocks = traversal::mono_reachable_as_bitset(mir, cx.tcx(), instance);
+    let mut unreached_blocks = BitSet::new_filled(mir.basic_blocks.len());
+    // Codegen the body of each reachable block using our reverse postorder list.
+    for bb in traversal_order {
+        fx.codegen_block(bb);
+        unreached_blocks.remove(bb);
+    }
 
-    // Codegen the body of each block using reverse postorder
-    for (bb, _) in traversal::reverse_postorder(mir) {
-        if reachable_blocks.contains(bb) {
-            fx.codegen_block(bb);
-        } else {
-            // We want to skip this block, because it's not reachable. But we still create
-            // the block so terminators in other blocks can reference it.
-            fx.codegen_block_as_unreachable(bb);
-        }
+    // FIXME: These empty unreachable blocks are *mostly* a waste. They are occasionally
+    // targets for a SwitchInt terminator, but the reimplementation of the mono-reachable
+    // simplification in SwitchInt lowering sometimes misses cases that
+    // mono_reachable_reverse_postorder manages to figure out.
+    // The solution is to do something like post-mono GVN. But for now we have this hack.
+    for bb in unreached_blocks.iter() {
+        fx.codegen_block_as_unreachable(bb);
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0775.md b/compiler/rustc_error_codes/src/error_codes/E0775.md
index 9bafd52f75c..efbd51e89ea 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0775.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0775.md
@@ -1,13 +1,14 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M
 extension.
 
 Erroneous code example:
 
-```compile_fail,E0775
+```ignore (no longer emitted)
 #![feature(cmse_nonsecure_entry)]
 
-#[cmse_nonsecure_entry]
-pub extern "C" fn entry_function() {}
+pub extern "C-cmse-nonsecure-entry" fn entry_function() {}
 ```
 
 To fix this error, compile your code for a Rust target that supports the
diff --git a/compiler/rustc_error_codes/src/error_codes/E0776.md b/compiler/rustc_error_codes/src/error_codes/E0776.md
index d65beebe07c..e46d498d1c2 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0776.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0776.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 `#[cmse_nonsecure_entry]` functions require a C ABI
 
 Erroneous code example:
 
-```compile_fail,E0776
+```ignore (no longer emitted)
 #![feature(cmse_nonsecure_entry)]
 
 #[no_mangle]
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 11cad0b8f97..8631de65ec8 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -681,4 +681,5 @@ E0800: 0800,
 //  E0723, // unstable feature in `const` context
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
 //  E0744, // merged into E0728
+//  E0776, // Removed; cmse_nonsecure_entry is now `C-cmse-nonsecure-entry`
 //  E0796, // unused error code. We use `static_mut_refs` lint instead.
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 0d56a005f15..84ae351ed72 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -41,7 +41,9 @@ use crate::errors::{
 };
 use crate::fluent_generated;
 use crate::mbe::diagnostics::annotate_err_with_kind;
-use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
+use crate::module::{
+    mod_dir_path, mod_file_path_from_attr, parse_external_mod, DirOwnership, ParsedExternalMod,
+};
 use crate::placeholders::{placeholder, PlaceholderExpander};
 
 macro_rules! ast_fragments {
@@ -1202,8 +1204,14 @@ impl InvocationCollectorNode for P<ast::Item> {
                     ecx.current_expansion.dir_ownership,
                     *inline,
                 );
+                // If the module was parsed from an external file, recover its path.
+                // This lets `parse_external_mod` catch cycles if it's self-referential.
+                let file_path = match inline {
+                    Inline::Yes => None,
+                    Inline::No => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path),
+                };
                 node.attrs = attrs;
-                (None, dir_path, dir_ownership)
+                (file_path, dir_path, dir_ownership)
             }
             ModKind::Unloaded => {
                 // We have an outline `mod foo;` so we need to parse the file.
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 13348376851..27a9a330f3c 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -171,7 +171,7 @@ fn mod_file_path<'a>(
 
 /// Derive a submodule path from the first found `#[path = "path_string"]`.
 /// The provided `dir_path` is joined with the `path_string`.
-fn mod_file_path_from_attr(
+pub(crate) fn mod_file_path_from_attr(
     sess: &Session,
     attrs: &[Attribute],
     dir_path: &Path,
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 3b7e0d82d0f..fa5f152132a 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -551,10 +551,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::No, experimental!(register_tool),
     ),
 
-    gated!(
-        cmse_nonsecure_entry, Normal, template!(Word), WarnFollowing,
-        EncodeCrossCrate::No, experimental!(cmse_nonsecure_entry)
-    ),
     // RFC 2632
     gated!(
         const_trait, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, const_trait_impl,
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 40333c3953a..edc8e5f0752 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -395,7 +395,7 @@ declare_features! (
     (unstable, closure_lifetime_binder, "1.64.0", Some(97362)),
     /// Allows `#[track_caller]` on closures and coroutines.
     (unstable, closure_track_caller, "1.57.0", Some(87417)),
-    /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
+    /// Allows `extern "C-cmse-nonsecure-entry" fn()`.
     (unstable, cmse_nonsecure_entry, "1.48.0", Some(75835)),
     /// Allows `async {}` expressions in const contexts.
     (unstable, const_async_blocks, "1.53.0", Some(85368)),
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 633ccacedfc..09d466339ff 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -37,7 +37,7 @@ hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}
 
 hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg = consider adding braces here
 
-hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the associated type of a trait with uninferred generic parameters
+hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the associated {$what} of a trait with uninferred generic parameters
     .suggestion = use a fully qualified path with inferred lifetimes
 
 hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
@@ -48,6 +48,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
 
 hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found}
 
+hir_analysis_bad_return_type_notation_position = return type notation not allowed in this position yet
+
 hir_analysis_cannot_capture_late_bound_const =
     cannot capture late-bound const parameter in {$what}
     .label = parameter defined here
@@ -478,7 +480,7 @@ hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`, bu
 
 hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
 
-hir_analysis_too_large_static = extern static is too large for the current architecture
+hir_analysis_too_large_static = extern static is too large for the target architecture
 
 hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]`
     .suggestion = remove this annotation
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index d0b0c08aa79..14ea7816291 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -9,6 +9,8 @@ use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
 
+use crate::hir_ty_lowering::OnlySelfBounds;
+
 /// Collects together a list of type bounds. These lists of bounds occur in many places
 /// in Rust's syntax:
 ///
@@ -50,6 +52,7 @@ impl<'tcx> Bounds<'tcx> {
         span: Span,
         polarity: ty::PredicatePolarity,
         constness: ty::BoundConstness,
+        only_self_bounds: OnlySelfBounds,
     ) {
         let clause = (
             bound_trait_ref
@@ -66,7 +69,10 @@ impl<'tcx> Bounds<'tcx> {
             self.clauses.push(clause);
         }
 
-        if !tcx.features().effects {
+        // FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else.
+        // Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated
+        // type bounds.
+        if !tcx.features().effects || only_self_bounds.0 {
             return;
         }
         // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index ac9976148e2..4c59f7540ee 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -460,7 +460,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                                 [] => (generics.span, format!("<{lt_name}>")),
                                 [bound, ..] => (bound.span.shrink_to_lo(), format!("{lt_name}, ")),
                             };
-                            mpart_sugg = Some(errors::AssociatedTypeTraitUninferredGenericParamsMultipartSuggestion {
+                            mpart_sugg = Some(errors::AssociatedItemTraitUninferredGenericParamsMultipartSuggestion {
                                 fspan: lt_sp,
                                 first: sugg,
                                 sspan: span.with_hi(item_segment.ident.span.lo()),
@@ -502,11 +502,12 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
             }
             Ty::new_error(
                 self.tcx(),
-                self.tcx().dcx().emit_err(errors::AssociatedTypeTraitUninferredGenericParams {
+                self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
                     span,
                     inferred_sugg,
                     bound,
                     mpart_sugg,
+                    what: "type",
                 }),
             )
         }
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index d62727e76b5..7a254c884c2 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -10,6 +10,7 @@ use rustc_span::Span;
 use rustc_type_ir::Upcast;
 use tracing::{debug, instrument};
 
+use super::predicates_of::assert_only_contains_predicates_from;
 use super::ItemCtxt;
 use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
 
@@ -56,6 +57,9 @@ fn associated_type_bounds<'tcx>(
         tcx.def_path_str(assoc_item_def_id.to_def_id()),
         all_bounds
     );
+
+    assert_only_contains_predicates_from(filter, all_bounds, item_ty);
+
     all_bounds
 }
 
@@ -108,18 +112,21 @@ pub(super) fn explicit_item_bounds_with_filter(
         Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
             let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
             let opaque_ty = item.expect_opaque_ty();
-            return ty::EarlyBinder::bind(opaque_type_bounds(
+            let item_ty = Ty::new_projection_from_args(
+                tcx,
+                def_id.to_def_id(),
+                ty::GenericArgs::identity_for_item(tcx, def_id),
+            );
+            let bounds = opaque_type_bounds(
                 tcx,
                 opaque_def_id.expect_local(),
                 opaque_ty.bounds,
-                Ty::new_projection_from_args(
-                    tcx,
-                    def_id.to_def_id(),
-                    ty::GenericArgs::identity_for_item(tcx, def_id),
-                ),
+                item_ty,
                 item.span,
                 filter,
-            ));
+            );
+            assert_only_contains_predicates_from(filter, bounds, item_ty);
+            return ty::EarlyBinder::bind(bounds);
         }
         Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
             tcx.def_span(def_id),
@@ -167,7 +174,9 @@ pub(super) fn explicit_item_bounds_with_filter(
         }) => {
             let args = GenericArgs::identity_for_item(tcx, def_id);
             let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
-            opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
+            let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
+            assert_only_contains_predicates_from(filter, bounds, item_ty);
+            bounds
         }
         // Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
         // asking for the item bounds of the *opaques* in a trait's default method signature, we
@@ -184,15 +193,18 @@ pub(super) fn explicit_item_bounds_with_filter(
             };
             let args = GenericArgs::identity_for_item(tcx, def_id);
             let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
-            tcx.arena.alloc_slice(
+            let bounds = &*tcx.arena.alloc_slice(
                 &opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
                     .to_vec()
                     .fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
-            )
+            );
+            assert_only_contains_predicates_from(filter, bounds, item_ty);
+            bounds
         }
         hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
         _ => bug!("item_bounds called on {:?}", def_id),
     };
+
     ty::EarlyBinder::bind(bounds)
 }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 7243e85ce98..67d8813d1f7 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -240,7 +240,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     for predicate in hir_generics.predicates {
         match predicate {
             hir::WherePredicate::BoundPredicate(bound_pred) => {
-                let ty = icx.lower_ty(bound_pred.bounded_ty);
+                let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
+
                 let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
                 // Keep the type around in a dummy predicate, in case of no bounds.
                 // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
@@ -676,9 +677,63 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
         _ => {}
     }
 
+    assert_only_contains_predicates_from(filter, implied_bounds, tcx.types.self_param);
+
     ty::EarlyBinder::bind(implied_bounds)
 }
 
+// Make sure when elaborating supertraits, probing for associated types, etc.,
+// we really truly are elaborating clauses that have `Self` as their self type.
+// This is very important since downstream code relies on this being correct.
+pub(super) fn assert_only_contains_predicates_from<'tcx>(
+    filter: PredicateFilter,
+    bounds: &'tcx [(ty::Clause<'tcx>, Span)],
+    ty: Ty<'tcx>,
+) {
+    if !cfg!(debug_assertions) {
+        return;
+    }
+
+    match filter {
+        PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
+            for (clause, _) in bounds {
+                match clause.kind().skip_binder() {
+                    ty::ClauseKind::Trait(trait_predicate) => {
+                        assert_eq!(
+                            trait_predicate.self_ty(),
+                            ty,
+                            "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                    ty::ClauseKind::Projection(projection_predicate) => {
+                        assert_eq!(
+                            projection_predicate.self_ty(),
+                            ty,
+                            "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                    ty::ClauseKind::TypeOutlives(outlives_predicate) => {
+                        assert_eq!(
+                            outlives_predicate.0, ty,
+                            "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+
+                    ty::ClauseKind::RegionOutlives(_)
+                    | ty::ClauseKind::ConstArgHasType(_, _)
+                    | ty::ClauseKind::WellFormed(_)
+                    | ty::ClauseKind::ConstEvaluatable(_) => {
+                        bug!(
+                            "unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                }
+            }
+        }
+        PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {}
+    }
+}
+
 /// Returns the predicates defined on `item_def_id` of the form
 /// `X: Foo` where `X` is the type parameter `def_id`.
 #[instrument(level = "trace", skip(tcx))]
@@ -770,6 +825,10 @@ impl<'tcx> ItemCtxt<'tcx> {
                 continue;
             };
 
+            // Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
+            // want to only consider predicates with `Self: ...`, but we don't want
+            // `OnlySelfBounds(true)` since we want to collect the nested associated
+            // type bound as well.
             let (only_self_bounds, assoc_name) = match filter {
                 PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
                     (OnlySelfBounds(false), None)
@@ -780,14 +839,10 @@ impl<'tcx> ItemCtxt<'tcx> {
                 }
             };
 
-            // Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
-            // want to only consider predicates with `Self: ...`, but we don't want
-            // `OnlySelfBounds(true)` since we want to collect the nested associated
-            // type bound as well.
             let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
                 ty
             } else if matches!(filter, PredicateFilter::All) {
-                self.lower_ty(predicate.bounded_ty)
+                self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty)
             } else {
                 continue;
             };
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 53dcede91c3..d1601446b6f 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -889,7 +889,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                             (pair, r)
                         })
                         .unzip();
+
                 self.record_late_bound_vars(hir_id, binders);
+
+                // If this is an RTN type in the self type, then append those to the binder.
+                self.try_append_return_type_notation_params(hir_id, bounded_ty);
+
                 // Even if there are no lifetimes defined here, we still wrap it in a binder
                 // scope. If there happens to be a nested poly trait ref (an error), that
                 // will be `Concatenating` anyways, so we don't have to worry about the depth
@@ -1635,9 +1640,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             // }
             // ```
             // and a bound that looks like:
-            //    `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>`
+            //    `for<'a> T::Trait<'a, x(..): for<'b> Other<'b>>`
             // this is going to expand to something like:
-            //    `for<'a> for<'r, T> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`.
+            //    `for<'a> for<'r> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`.
             if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation
             {
                 let bound_vars = if let Some(type_def_id) = type_def_id
@@ -1839,6 +1844,178 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         let old_value = self.map.defs.swap_remove(&lifetime_ref.hir_id);
         assert_eq!(old_value, Some(bad_def));
     }
+
+    // When we have a return type notation type in a where clause, like
+    // `where <T as Trait>::method(..): Send`, we need to introduce new bound
+    // vars to the existing where clause's binder, to represent the lifetimes
+    // elided by the return-type-notation syntax.
+    //
+    // For example, given
+    // ```
+    // trait Foo {
+    //     async fn x<'r>();
+    // }
+    // ```
+    // and a bound that looks like:
+    //    `for<'a, 'b> <T as Trait<'a>>::x(): Other<'b>`
+    // this is going to expand to something like:
+    //    `for<'a, 'b, 'r> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: Other<'b>`.
+    //
+    // We handle this similarly for associated-type-bound style return-type-notation
+    // in `visit_segment_args`.
+    fn try_append_return_type_notation_params(
+        &mut self,
+        hir_id: HirId,
+        hir_ty: &'tcx hir::Ty<'tcx>,
+    ) {
+        let hir::TyKind::Path(qpath) = hir_ty.kind else {
+            // We only care about path types here. All other self types
+            // (including nesting the RTN type in another type) don't do
+            // anything.
+            return;
+        };
+
+        let (mut bound_vars, item_def_id, item_segment) = match qpath {
+            // If we have a fully qualified method, then we don't need to do any special lookup.
+            hir::QPath::Resolved(_, path)
+                if let [.., item_segment] = &path.segments[..]
+                    && item_segment.args.is_some_and(|args| {
+                        matches!(
+                            args.parenthesized,
+                            hir::GenericArgsParentheses::ReturnTypeNotation
+                        )
+                    }) =>
+            {
+                match path.res {
+                    Res::Err => return,
+                    Res::Def(DefKind::AssocFn, item_def_id) => (vec![], item_def_id, item_segment),
+                    _ => bug!("only expected method resolution for fully qualified RTN"),
+                }
+            }
+
+            // If we have a type-dependent path, then we do need to do some lookup.
+            hir::QPath::TypeRelative(qself, item_segment)
+                if item_segment.args.is_some_and(|args| {
+                    matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
+                }) =>
+            {
+                // First, ignore a qself that isn't a type or `Self` param. Those are the
+                // only ones that support `T::Assoc` anyways in HIR lowering.
+                let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = qself.kind else {
+                    return;
+                };
+                match path.res {
+                    Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { trait_: _ } => {
+                        // Get the generics of this type's hir owner. This is *different*
+                        // from the generics of the parameter's definition, since we want
+                        // to be able to resolve an RTN path on a nested body (e.g. method
+                        // inside an impl) using the where clauses on the method.
+                        // FIXME(return_type_notation): Think of some better way of doing this.
+                        let Some(generics) = self.tcx.hir_owner_node(hir_id.owner).generics()
+                        else {
+                            return;
+                        };
+
+                        // Look for the first bound that contains an associated type that
+                        // matches the segment that we're looking for. We ignore any subsequent
+                        // bounds since we'll be emitting a hard error in HIR lowering, so this
+                        // is purely speculative.
+                        let one_bound = generics.predicates.iter().find_map(|predicate| {
+                            let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
+                                return None;
+                            };
+                            let hir::TyKind::Path(hir::QPath::Resolved(None, bounded_path)) =
+                                predicate.bounded_ty.kind
+                            else {
+                                return None;
+                            };
+                            if bounded_path.res != path.res {
+                                return None;
+                            }
+                            predicate.bounds.iter().find_map(|bound| {
+                                let hir::GenericBound::Trait(trait_, _) = bound else {
+                                    return None;
+                                };
+                                BoundVarContext::supertrait_hrtb_vars(
+                                    self.tcx,
+                                    trait_.trait_ref.trait_def_id()?,
+                                    item_segment.ident,
+                                    ty::AssocKind::Fn,
+                                )
+                            })
+                        });
+                        let Some((bound_vars, assoc_item)) = one_bound else {
+                            return;
+                        };
+                        (bound_vars, assoc_item.def_id, item_segment)
+                    }
+                    // If we have a self type alias (in an impl), try to resolve an
+                    // associated item from one of the supertraits of the impl's trait.
+                    Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. } => {
+                        let hir::ItemKind::Impl(hir::Impl { of_trait: Some(trait_ref), .. }) = self
+                            .tcx
+                            .hir_node_by_def_id(impl_def_id.expect_local())
+                            .expect_item()
+                            .kind
+                        else {
+                            return;
+                        };
+                        let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                            return;
+                        };
+                        let Some((bound_vars, assoc_item)) = BoundVarContext::supertrait_hrtb_vars(
+                            self.tcx,
+                            trait_def_id,
+                            item_segment.ident,
+                            ty::AssocKind::Fn,
+                        ) else {
+                            return;
+                        };
+                        (bound_vars, assoc_item.def_id, item_segment)
+                    }
+                    _ => return,
+                }
+            }
+
+            _ => return,
+        };
+
+        // Append the early-bound vars on the function, and then the late-bound ones.
+        // We actually turn type parameters into higher-ranked types here, but we
+        // deny them later in HIR lowering.
+        bound_vars.extend(self.tcx.generics_of(item_def_id).own_params.iter().map(|param| {
+            match param.kind {
+                ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region(
+                    ty::BoundRegionKind::BrNamed(param.def_id, param.name),
+                ),
+                ty::GenericParamDefKind::Type { .. } => {
+                    ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(param.def_id, param.name))
+                }
+                ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const,
+            }
+        }));
+        bound_vars.extend(self.tcx.fn_sig(item_def_id).instantiate_identity().bound_vars());
+
+        // SUBTLE: Stash the old bound vars onto the *item segment* before appending
+        // the new bound vars. We do this because we need to know how many bound vars
+        // are present on the binder explicitly (i.e. not return-type-notation vars)
+        // to do bound var shifting correctly in HIR lowering.
+        //
+        // For example, in `where for<'a> <T as Trait<'a>>::method(..): Other`,
+        // the `late_bound_vars` of the where clause predicate (i.e. this HIR ty's
+        // parent) will include `'a` AND all the early- and late-bound vars of the
+        // method. But when lowering the RTN type, we just want the list of vars
+        // we used to resolve the trait ref. We explicitly stored those back onto
+        // the item segment, since there's no other good place to put them.
+        //
+        // See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`.
+        // And this is exercised in:
+        // `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`.
+        let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id).unwrap();
+        let existing_bound_vars_saved = existing_bound_vars.clone();
+        existing_bound_vars.extend(bound_vars);
+        self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved);
+    }
 }
 
 /// Detects late-bound lifetimes and inserts them into
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index e4e5f76ae32..4edb68e6199 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -780,14 +780,15 @@ pub(crate) struct PlaceholderNotAllowedItemSignatures {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_associated_type_trait_uninferred_generic_params, code = E0212)]
-pub(crate) struct AssociatedTypeTraitUninferredGenericParams {
+pub(crate) struct AssociatedItemTraitUninferredGenericParams {
     #[primary_span]
     pub span: Span,
     #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "{bound}")]
     pub inferred_sugg: Option<Span>,
     pub bound: String,
     #[subdiagnostic]
-    pub mpart_sugg: Option<AssociatedTypeTraitUninferredGenericParamsMultipartSuggestion>,
+    pub mpart_sugg: Option<AssociatedItemTraitUninferredGenericParamsMultipartSuggestion>,
+    pub what: &'static str,
 }
 
 #[derive(Subdiagnostic)]
@@ -795,7 +796,7 @@ pub(crate) struct AssociatedTypeTraitUninferredGenericParams {
     hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion,
     applicability = "maybe-incorrect"
 )]
-pub(crate) struct AssociatedTypeTraitUninferredGenericParamsMultipartSuggestion {
+pub(crate) struct AssociatedItemTraitUninferredGenericParamsMultipartSuggestion {
     #[suggestion_part(code = "{first}")]
     pub fspan: Span,
     pub first: String,
@@ -1693,3 +1694,10 @@ pub(crate) struct CmseCallGeneric {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_bad_return_type_notation_position)]
+pub(crate) struct BadReturnTypeNotation {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index bffe68f9b74..6f7f3128347 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -6,6 +6,7 @@ use rustc_errors::struct_span_code_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::HirId;
 use rustc_middle::bug;
 use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
 use rustc_span::symbol::Ident;
@@ -15,6 +16,7 @@ use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 use smallvec::SmallVec;
 use tracing::{debug, instrument};
 
+use super::errors::GenericsArgsErrExtend;
 use crate::bounds::Bounds;
 use crate::errors;
 use crate::hir_ty_lowering::{
@@ -332,74 +334,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .or_insert(constraint.span);
 
         let projection_term = if let ty::AssocKind::Fn = assoc_kind {
-            let mut emitted_bad_param_err = None;
-            // If we have an method return type bound, then we need to instantiate
-            // the method's early bound params with suitable late-bound params.
-            let mut num_bound_vars = candidate.bound_vars().len();
-            let args =
-                candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
-                    let arg = match param.kind {
-                        ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
-                            tcx,
-                            ty::INNERMOST,
-                            ty::BoundRegion {
-                                var: ty::BoundVar::from_usize(num_bound_vars),
-                                kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name),
-                            },
-                        )
-                        .into(),
-                        ty::GenericParamDefKind::Type { .. } => {
-                            let guar = *emitted_bad_param_err.get_or_insert_with(|| {
-                                self.dcx().emit_err(
-                                    crate::errors::ReturnTypeNotationIllegalParam::Type {
-                                        span: path_span,
-                                        param_span: tcx.def_span(param.def_id),
-                                    },
-                                )
-                            });
-                            Ty::new_error(tcx, guar).into()
-                        }
-                        ty::GenericParamDefKind::Const { .. } => {
-                            let guar = *emitted_bad_param_err.get_or_insert_with(|| {
-                                self.dcx().emit_err(
-                                    crate::errors::ReturnTypeNotationIllegalParam::Const {
-                                        span: path_span,
-                                        param_span: tcx.def_span(param.def_id),
-                                    },
-                                )
-                            });
-                            ty::Const::new_error(tcx, guar).into()
-                        }
-                    };
-                    num_bound_vars += 1;
-                    arg
-                });
-
-            // Next, we need to check that the return-type notation is being used on
-            // an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait).
-            let output = tcx.fn_sig(assoc_item.def_id).skip_binder().output();
-            let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
-                && tcx.is_impl_trait_in_trait(alias_ty.def_id)
-            {
-                alias_ty.into()
-            } else {
-                return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
-                    span: constraint.span,
-                    ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
-                    fn_span: tcx.hir().span_if_local(assoc_item.def_id),
-                    note: (),
-                }));
-            };
-
-            // Finally, move the fn return type's bound vars over to account for the early bound
-            // params (and trait ref's late bound params). This logic is very similar to
-            // `rustc_middle::ty::predicate::Clause::instantiate_supertrait`
-            // and it's no coincidence why.
-            let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
-            let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
-
             let bound_vars = tcx.late_bound_vars(constraint.hir_id);
-            ty::Binder::bind_with_vars(instantiation_output, bound_vars)
+            ty::Binder::bind_with_vars(
+                self.lower_return_type_notation_ty(candidate, assoc_item.def_id, path_span)?.into(),
+                bound_vars,
+            )
         } else {
             // Create the generic arguments for the associated type or constant by joining the
             // parent arguments (the arguments of the trait) and the own arguments (the ones of
@@ -525,6 +464,269 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
         Ok(())
     }
+
+    /// Lower a type, possibly specially handling the type if it's a return type notation
+    /// which we otherwise deny in other positions.
+    pub fn lower_ty_maybe_return_type_notation(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
+        let hir::TyKind::Path(qpath) = hir_ty.kind else {
+            return self.lower_ty(hir_ty);
+        };
+
+        let tcx = self.tcx();
+        match qpath {
+            hir::QPath::Resolved(opt_self_ty, path)
+                if let [mod_segments @ .., trait_segment, item_segment] = &path.segments[..]
+                    && item_segment.args.is_some_and(|args| {
+                        matches!(
+                            args.parenthesized,
+                            hir::GenericArgsParentheses::ReturnTypeNotation
+                        )
+                    }) =>
+            {
+                // We don't allow generics on the module segments.
+                let _ =
+                    self.prohibit_generic_args(mod_segments.iter(), GenericsArgsErrExtend::None);
+
+                let item_def_id = match path.res {
+                    Res::Def(DefKind::AssocFn, item_def_id) => item_def_id,
+                    Res::Err => {
+                        return Ty::new_error_with_message(
+                            tcx,
+                            hir_ty.span,
+                            "failed to resolve RTN",
+                        );
+                    }
+                    _ => bug!("only expected method resolution for fully qualified RTN"),
+                };
+                let trait_def_id = tcx.parent(item_def_id);
+
+                // Good error for `where Trait::method(..): Send`.
+                let Some(self_ty) = opt_self_ty else {
+                    return self.error_missing_qpath_self_ty(
+                        trait_def_id,
+                        hir_ty.span,
+                        item_segment,
+                    );
+                };
+                let self_ty = self.lower_ty(self_ty);
+
+                let trait_ref = self.lower_mono_trait_ref(
+                    hir_ty.span,
+                    trait_def_id,
+                    self_ty,
+                    trait_segment,
+                    false,
+                    ty::BoundConstness::NotConst,
+                );
+
+                // SUBTLE: As noted at the end of `try_append_return_type_notation_params`
+                // in `resolve_bound_vars`, we stash the explicit bound vars of the where
+                // clause onto the item segment of the RTN type. This allows us to know
+                // how many bound vars are *not* coming from the signature of the function
+                // from lowering RTN itself.
+                //
+                // For example, in `where for<'a> <T as Trait<'a>>::method(..): Other`,
+                // the `late_bound_vars` of the where clause predicate (i.e. this HIR ty's
+                // parent) will include `'a` AND all the early- and late-bound vars of the
+                // method. But when lowering the RTN type, we just want the list of vars
+                // we used to resolve the trait ref. We explicitly stored those back onto
+                // the item segment, since there's no other good place to put them.
+                let candidate =
+                    ty::Binder::bind_with_vars(trait_ref, tcx.late_bound_vars(item_segment.hir_id));
+
+                match self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span) {
+                    Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
+                    Err(guar) => Ty::new_error(tcx, guar),
+                }
+            }
+            hir::QPath::TypeRelative(qself, item_segment)
+                if item_segment.args.is_some_and(|args| {
+                    matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
+                }) =>
+            {
+                match self
+                    .resolve_type_relative_return_type_notation(
+                        qself,
+                        item_segment,
+                        hir_ty.hir_id,
+                        hir_ty.span,
+                    )
+                    .and_then(|(candidate, item_def_id)| {
+                        self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span)
+                    }) {
+                    Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
+                    Err(guar) => Ty::new_error(tcx, guar),
+                }
+            }
+            _ => self.lower_ty(hir_ty),
+        }
+    }
+
+    /// Perform type-dependent lookup for a *method* for return type notation.
+    /// This generally mirrors `<dyn HirTyLowerer>::lower_assoc_path`.
+    fn resolve_type_relative_return_type_notation(
+        &self,
+        qself: &'tcx hir::Ty<'tcx>,
+        item_segment: &'tcx hir::PathSegment<'tcx>,
+        qpath_hir_id: HirId,
+        span: Span,
+    ) -> Result<(ty::PolyTraitRef<'tcx>, DefId), ErrorGuaranteed> {
+        let tcx = self.tcx();
+        let qself_ty = self.lower_ty(qself);
+        let assoc_ident = item_segment.ident;
+        let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
+            path.res
+        } else {
+            Res::Err
+        };
+
+        let bound = match (qself_ty.kind(), qself_res) {
+            (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
+                // `Self` in an impl of a trait -- we have a concrete self type and a
+                // trait reference.
+                let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
+                    // A cycle error occurred, most likely.
+                    self.dcx().span_bug(span, "expected cycle error");
+                };
+
+                self.probe_single_bound_for_assoc_item(
+                    || {
+                        traits::supertraits(
+                            tcx,
+                            ty::Binder::dummy(trait_ref.instantiate_identity()),
+                        )
+                    },
+                    AssocItemQSelf::SelfTyAlias,
+                    ty::AssocKind::Fn,
+                    assoc_ident,
+                    span,
+                    None,
+                )?
+            }
+            (
+                &ty::Param(_),
+                Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
+            ) => self.probe_single_ty_param_bound_for_assoc_item(
+                param_did.expect_local(),
+                qself.span,
+                ty::AssocKind::Fn,
+                assoc_ident,
+                span,
+            )?,
+            _ => {
+                if let Err(reported) = qself_ty.error_reported() {
+                    return Err(reported);
+                } else {
+                    // FIXME(return_type_notation): Provide some structured suggestion here.
+                    let err = struct_span_code_err!(
+                        self.dcx(),
+                        span,
+                        E0223,
+                        "ambiguous associated function"
+                    );
+                    return Err(err.emit());
+                }
+            }
+        };
+
+        // Don't let `T::method` resolve to some `for<'a> <T as Tr<'a>>::method`,
+        // which may happen via a higher-ranked where clause or supertrait.
+        // This is the same restrictions as associated types; even though we could
+        // support it, it just makes things a lot more difficult to support in
+        // `resolve_bound_vars`, since we'd need to introduce those as elided
+        // bound vars on the where clause too.
+        if bound.has_bound_vars() {
+            return Err(self.tcx().dcx().emit_err(
+                errors::AssociatedItemTraitUninferredGenericParams {
+                    span,
+                    inferred_sugg: Some(span.with_hi(item_segment.ident.span.lo())),
+                    bound: format!("{}::", tcx.anonymize_bound_vars(bound).skip_binder(),),
+                    mpart_sugg: None,
+                    what: "function",
+                },
+            ));
+        }
+
+        let trait_def_id = bound.def_id();
+        let assoc_ty = self
+            .probe_assoc_item(assoc_ident, ty::AssocKind::Fn, qpath_hir_id, span, trait_def_id)
+            .expect("failed to find associated type");
+
+        Ok((bound, assoc_ty.def_id))
+    }
+
+    /// Do the common parts of lowering an RTN type. This involves extending the
+    /// candidate binder to include all of the early- and late-bound vars that are
+    /// defined on the function itself, and constructing a projection to the RPITIT
+    /// return type of that function.
+    fn lower_return_type_notation_ty(
+        &self,
+        candidate: ty::PolyTraitRef<'tcx>,
+        item_def_id: DefId,
+        path_span: Span,
+    ) -> Result<ty::AliasTy<'tcx>, ErrorGuaranteed> {
+        let tcx = self.tcx();
+        let mut emitted_bad_param_err = None;
+        // If we have an method return type bound, then we need to instantiate
+        // the method's early bound params with suitable late-bound params.
+        let mut num_bound_vars = candidate.bound_vars().len();
+        let args = candidate.skip_binder().args.extend_to(tcx, item_def_id, |param, _| {
+            let arg = match param.kind {
+                ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
+                    tcx,
+                    ty::INNERMOST,
+                    ty::BoundRegion {
+                        var: ty::BoundVar::from_usize(num_bound_vars),
+                        kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name),
+                    },
+                )
+                .into(),
+                ty::GenericParamDefKind::Type { .. } => {
+                    let guar = *emitted_bad_param_err.get_or_insert_with(|| {
+                        self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Type {
+                            span: path_span,
+                            param_span: tcx.def_span(param.def_id),
+                        })
+                    });
+                    Ty::new_error(tcx, guar).into()
+                }
+                ty::GenericParamDefKind::Const { .. } => {
+                    let guar = *emitted_bad_param_err.get_or_insert_with(|| {
+                        self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Const {
+                            span: path_span,
+                            param_span: tcx.def_span(param.def_id),
+                        })
+                    });
+                    ty::Const::new_error(tcx, guar).into()
+                }
+            };
+            num_bound_vars += 1;
+            arg
+        });
+
+        // Next, we need to check that the return-type notation is being used on
+        // an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait).
+        let output = tcx.fn_sig(item_def_id).skip_binder().output();
+        let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
+            && tcx.is_impl_trait_in_trait(alias_ty.def_id)
+        {
+            alias_ty
+        } else {
+            return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
+                span: path_span,
+                ty: tcx.liberate_late_bound_regions(item_def_id, output),
+                fn_span: tcx.hir().span_if_local(item_def_id),
+                note: (),
+            }));
+        };
+
+        // Finally, move the fn return type's bound vars over to account for the early bound
+        // params (and trait ref's late bound params). This logic is very similar to
+        // `rustc_middle::ty::predicate::Clause::instantiate_supertrait`
+        // and it's no coincidence why.
+        let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
+        Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args))
+    }
 }
 
 /// Detect and reject early-bound & escaping late-bound generic params in the type of assoc const bindings.
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 7163352e8a4..35eebcb6be1 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -53,7 +53,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
 use tracing::{debug, debug_span, instrument};
 
 use crate::bounds::Bounds;
-use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
+use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
 use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
 use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
 use crate::middle::resolve_bound_vars as rbv;
@@ -719,6 +719,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             span,
             polarity,
             constness,
+            only_self_bounds,
         );
 
         let mut dup_constraints = FxIndexMap::default();
@@ -813,17 +814,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
     }
 
-    /// Search for a trait bound on a type parameter whose trait defines the associated type given by `assoc_name`.
+    /// Search for a trait bound on a type parameter whose trait defines the associated item
+    /// given by `assoc_name` and `kind`.
     ///
     /// This fails if there is no such bound in the list of candidates or if there are multiple
     /// candidates in which case it reports ambiguity.
     ///
     /// `ty_param_def_id` is the `LocalDefId` of the type parameter.
     #[instrument(level = "debug", skip_all, ret)]
-    fn probe_single_ty_param_bound_for_assoc_ty(
+    fn probe_single_ty_param_bound_for_assoc_item(
         &self,
         ty_param_def_id: LocalDefId,
         ty_param_span: Span,
+        kind: ty::AssocKind,
         assoc_name: Ident,
         span: Span,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
@@ -841,7 +844,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
             },
             AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
-            ty::AssocKind::Type,
+            kind,
             assoc_name,
             span,
             None,
@@ -1081,9 +1084,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             (
                 &ty::Param(_),
                 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
-            ) => self.probe_single_ty_param_bound_for_assoc_ty(
+            ) => self.probe_single_ty_param_bound_for_assoc_item(
                 param_did.expect_local(),
                 qself.span,
+                ty::AssocKind::Type,
                 assoc_ident,
                 span,
             )?,
@@ -1545,48 +1549,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?trait_def_id);
 
         let Some(self_ty) = opt_self_ty else {
-            let path_str = tcx.def_path_str(trait_def_id);
-
-            let def_id = self.item_def_id();
-            debug!(item_def_id = ?def_id);
-
-            // FIXME: document why/how this is different from `tcx.local_parent(def_id)`
-            let parent_def_id =
-                tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id();
-            debug!(?parent_def_id);
-
-            // If the trait in segment is the same as the trait defining the item,
-            // use the `<Self as ..>` syntax in the error.
-            let is_part_of_self_trait_constraints = def_id.to_def_id() == trait_def_id;
-            let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
-
-            let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
-                vec!["Self".to_string()]
-            } else {
-                // Find all the types that have an `impl` for the trait.
-                tcx.all_impls(trait_def_id)
-                    .filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
-                    .filter(|header| {
-                        // Consider only accessible traits
-                        tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
-                            && header.polarity != ty::ImplPolarity::Negative
-                    })
-                    .map(|header| header.trait_ref.instantiate_identity().self_ty())
-                    // We don't care about blanket impls.
-                    .filter(|self_ty| !self_ty.has_non_region_param())
-                    .map(|self_ty| tcx.erase_regions(self_ty).to_string())
-                    .collect()
-            };
-            // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
-            // references the trait. Relevant for the first case in
-            // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
-            let reported = self.report_ambiguous_assoc_ty(
-                span,
-                &type_names,
-                &[path_str],
-                item_segment.ident.name,
-            );
-            return Ty::new_error(tcx, reported);
+            return self.error_missing_qpath_self_ty(trait_def_id, span, item_segment);
         };
         debug!(?self_ty);
 
@@ -1600,6 +1563,53 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         Ty::new_projection_from_args(tcx, item_def_id, item_args)
     }
 
+    fn error_missing_qpath_self_ty(
+        &self,
+        trait_def_id: DefId,
+        span: Span,
+        item_segment: &hir::PathSegment<'tcx>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx();
+        let path_str = tcx.def_path_str(trait_def_id);
+
+        let def_id = self.item_def_id();
+        debug!(item_def_id = ?def_id);
+
+        // FIXME: document why/how this is different from `tcx.local_parent(def_id)`
+        let parent_def_id =
+            tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id();
+        debug!(?parent_def_id);
+
+        // If the trait in segment is the same as the trait defining the item,
+        // use the `<Self as ..>` syntax in the error.
+        let is_part_of_self_trait_constraints = def_id.to_def_id() == trait_def_id;
+        let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
+
+        let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
+            vec!["Self".to_string()]
+        } else {
+            // Find all the types that have an `impl` for the trait.
+            tcx.all_impls(trait_def_id)
+                .filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
+                .filter(|header| {
+                    // Consider only accessible traits
+                    tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
+                        && header.polarity != ty::ImplPolarity::Negative
+                })
+                .map(|header| header.trait_ref.instantiate_identity().self_ty())
+                // We don't care about blanket impls.
+                .filter(|self_ty| !self_ty.has_non_region_param())
+                .map(|self_ty| tcx.erase_regions(self_ty).to_string())
+                .collect()
+        };
+        // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
+        // references the trait. Relevant for the first case in
+        // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
+        let reported =
+            self.report_ambiguous_assoc_ty(span, &type_names, &[path_str], item_segment.ident.name);
+        Ty::new_error(tcx, reported)
+    }
+
     pub fn prohibit_generic_args<'a>(
         &self,
         segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
@@ -1930,7 +1940,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     .tcx()
                     .dcx()
                     .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
-                Ty::new_error(self.tcx(), e)
+                Ty::new_error(tcx, e)
             }
             Res::Def(..) => {
                 assert_eq!(
@@ -2061,6 +2071,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 };
                 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
             }
+            // If we encounter a fully qualified path with RTN generics, then it must have
+            // *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
+            // it's certainly in an illegal position.
+            hir::TyKind::Path(hir::QPath::Resolved(_, path))
+                if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
+                    matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
+                }) =>
+            {
+                let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
+                Ty::new_error(tcx, guar)
+            }
             hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
                 debug!(?maybe_qself, ?path);
                 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
@@ -2085,6 +2106,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 }
             }
+            // If we encounter a type relative path with RTN generics, then it must have
+            // *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
+            // it's certainly in an illegal position.
+            hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
+                if segment.args.is_some_and(|args| {
+                    matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
+                }) =>
+            {
+                let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
+                Ty::new_error(tcx, guar)
+            }
             hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
                 debug!(?qself, ?segment);
                 let ty = self.lower_ty(qself);
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index f39d83a2a6f..81d940a3f9b 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -95,7 +95,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     format!("{v} bits")
                 } else {
                     // `u128` should definitely be able to hold the size of different architectures
-                    // larger sizes should be reported as error `are too big for the current architecture`
+                    // larger sizes should be reported as error `are too big for the target architecture`
                     // otherwise we have a bug somewhere
                     bug!("{:?} overflow for u128", size)
                 }
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index d81052b5e24..ce4ee45c485 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -332,6 +332,9 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
             return;
         }
 
+        // Issue #45127: don't enforce `snake_case` for binary crates as binaries are not intended
+        // to be distributed and depended on like libraries. The lint is not suppressed for cdylib
+        // or staticlib because it's not clear what the desired lint behavior for those are.
         if cx.tcx.crate_types().iter().all(|&crate_type| crate_type == CrateType::Executable) {
             return;
         }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index f9d0cd49708..3d042f21745 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1320,7 +1320,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     }
 
     fn is_internal_abi(&self, abi: SpecAbi) -> bool {
-        matches!(abi, SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustIntrinsic)
+        matches!(
+            abi,
+            SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustCold | SpecAbi::RustIntrinsic
+        )
     }
 
     /// Find any fn-ptr types with external ABIs in `ty`.
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 2b9d9a07a98..39485a324f2 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -103,5 +103,5 @@ middle_unknown_layout =
     the type `{$ty}` has an unknown layout
 
 middle_values_too_big =
-    values of the type `{$ty}` are too big for the current architecture
+    values of the type `{$ty}` are too big for the target architecture
 middle_written_to_path = the full type name has been written to '{$path}'
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index b7d290e58d2..90dff0f5c7d 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -120,9 +120,7 @@ bitflags::bitflags! {
         /// #[ffi_const]: applies clang's `const` attribute to a foreign function
         /// declaration.
         const FFI_CONST                 = 1 << 12;
-        /// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a
-        /// function as an entry function from Non-Secure code.
-        const CMSE_NONSECURE_ENTRY      = 1 << 13;
+        // (Bit 13 was used for `#[cmse_nonsecure_entry]`, but is now unused.)
         // (Bit 14 was used for `#[coverage(off)]`, but is now unused.)
         /// `#[used(linker)]`:
         /// indicates that neither LLVM nor the linker will eliminate this function.
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 183b898253e..63ce47ef327 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -71,7 +71,7 @@ impl<'tcx> BasicBlocks<'tcx> {
     #[inline]
     pub fn reverse_postorder(&self) -> &[BasicBlock] {
         self.cache.reverse_postorder.get_or_init(|| {
-            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK).collect();
+            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, ()).collect();
             rpo.reverse();
             rpo
         })
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e312e65cc21..54dcfaf5d54 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1424,6 +1424,19 @@ impl<'tcx> BasicBlockData<'tcx> {
     pub fn is_empty_unreachable(&self) -> bool {
         self.statements.is_empty() && matches!(self.terminator().kind, TerminatorKind::Unreachable)
     }
+
+    /// Like [`Terminator::successors`] but tries to use information available from the [`Instance`]
+    /// to skip successors like the `false` side of an `if const {`.
+    ///
+    /// This is used to implement [`traversal::mono_reachable`] and
+    /// [`traversal::mono_reachable_reverse_postorder`].
+    pub fn mono_successors(&self, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Successors<'_> {
+        if let Some((bits, targets)) = Body::try_const_mono_switchint(tcx, instance, self) {
+            targets.successors_for_value(bits)
+        } else {
+            self.terminator().successors()
+        }
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 962b93a25aa..c34e22eb873 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -413,6 +413,17 @@ mod helper {
     use super::*;
     pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
     pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
+
+    impl SwitchTargets {
+        /// Like [`SwitchTargets::target_for_value`], but returning the same type as
+        /// [`Terminator::successors`].
+        #[inline]
+        pub fn successors_for_value(&self, value: u128) -> Successors<'_> {
+            let target = self.target_for_value(value);
+            (&[]).into_iter().copied().chain(Some(target))
+        }
+    }
+
     impl<'tcx> TerminatorKind<'tcx> {
         #[inline]
         pub fn successors(&self) -> Successors<'_> {
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 245e9096bad..b8b74da401c 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -104,36 +104,46 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
 /// ```
 ///
 /// A Postorder traversal of this graph is `D B C A` or `D C B A`
-pub struct Postorder<'a, 'tcx> {
+pub struct Postorder<'a, 'tcx, C> {
     basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
     visited: BitSet<BasicBlock>,
     visit_stack: Vec<(BasicBlock, Successors<'a>)>,
     root_is_start_block: bool,
+    extra: C,
 }
 
-impl<'a, 'tcx> Postorder<'a, 'tcx> {
+impl<'a, 'tcx, C> Postorder<'a, 'tcx, C>
+where
+    C: Customization<'tcx>,
+{
     pub fn new(
         basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
         root: BasicBlock,
-    ) -> Postorder<'a, 'tcx> {
+        extra: C,
+    ) -> Postorder<'a, 'tcx, C> {
         let mut po = Postorder {
             basic_blocks,
             visited: BitSet::new_empty(basic_blocks.len()),
             visit_stack: Vec::new(),
             root_is_start_block: root == START_BLOCK,
+            extra,
         };
 
-        let data = &po.basic_blocks[root];
-
-        if let Some(ref term) = data.terminator {
-            po.visited.insert(root);
-            po.visit_stack.push((root, term.successors()));
-            po.traverse_successor();
-        }
+        po.visit(root);
+        po.traverse_successor();
 
         po
     }
 
+    fn visit(&mut self, bb: BasicBlock) {
+        if !self.visited.insert(bb) {
+            return;
+        }
+        let data = &self.basic_blocks[bb];
+        let successors = C::successors(data, self.extra);
+        self.visit_stack.push((bb, successors));
+    }
+
     fn traverse_successor(&mut self) {
         // This is quite a complex loop due to 1. the borrow checker not liking it much
         // and 2. what exactly is going on is not clear
@@ -183,16 +193,15 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
         // since we've already visited `E`, that child isn't added to the stack. The last
         // two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A]
         while let Some(bb) = self.visit_stack.last_mut().and_then(|(_, iter)| iter.next_back()) {
-            if self.visited.insert(bb) {
-                if let Some(term) = &self.basic_blocks[bb].terminator {
-                    self.visit_stack.push((bb, term.successors()));
-                }
-            }
+            self.visit(bb);
         }
     }
 }
 
-impl<'tcx> Iterator for Postorder<'_, 'tcx> {
+impl<'tcx, C> Iterator for Postorder<'_, 'tcx, C>
+where
+    C: Customization<'tcx>,
+{
     type Item = BasicBlock;
 
     fn next(&mut self) -> Option<BasicBlock> {
@@ -232,6 +241,40 @@ pub fn postorder<'a, 'tcx>(
     reverse_postorder(body).rev()
 }
 
+/// Lets us plug in some additional logic and data into a Postorder traversal. Or not.
+pub trait Customization<'tcx>: Copy {
+    fn successors<'a>(_: &'a BasicBlockData<'tcx>, _: Self) -> Successors<'a>;
+}
+
+impl<'tcx> Customization<'tcx> for () {
+    fn successors<'a>(data: &'a BasicBlockData<'tcx>, _: ()) -> Successors<'a> {
+        data.terminator().successors()
+    }
+}
+
+impl<'tcx> Customization<'tcx> for (TyCtxt<'tcx>, Instance<'tcx>) {
+    fn successors<'a>(
+        data: &'a BasicBlockData<'tcx>,
+        (tcx, instance): (TyCtxt<'tcx>, Instance<'tcx>),
+    ) -> Successors<'a> {
+        data.mono_successors(tcx, instance)
+    }
+}
+
+pub fn mono_reachable_reverse_postorder<'a, 'tcx>(
+    body: &'a Body<'tcx>,
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+) -> Vec<BasicBlock> {
+    let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, (tcx, instance));
+    let mut items = Vec::with_capacity(body.basic_blocks.len());
+    while let Some(block) = iter.next() {
+        items.push(block);
+    }
+    items.reverse();
+    items
+}
+
 /// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular
 /// order.
 ///
@@ -358,14 +401,8 @@ impl<'a, 'tcx> Iterator for MonoReachable<'a, 'tcx> {
 
             let data = &self.body[idx];
 
-            if let Some((bits, targets)) =
-                Body::try_const_mono_switchint(self.tcx, self.instance, data)
-            {
-                let target = targets.target_for_value(bits);
-                self.add_work([target]);
-            } else {
-                self.add_work(data.terminator().successors());
-            }
+            let targets = data.mono_successors(self.tcx, self.instance);
+            self.add_work(targets);
 
             return Some((idx, data));
         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 877c54c5649..941091b71d3 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -264,7 +264,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
         match *self {
             LayoutError::Unknown(ty) => write!(f, "the type `{ty}` has an unknown layout"),
             LayoutError::SizeOverflow(ty) => {
-                write!(f, "values of the type `{ty}` are too big for the current architecture")
+                write!(f, "values of the type `{ty}` are too big for the target architecture")
             }
             LayoutError::NormalizationFailure(t, e) => write!(
                 f,
@@ -1191,6 +1191,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
         | RiscvInterruptM
         | RiscvInterruptS
         | CCmseNonSecureCall
+        | CCmseNonSecureEntry
         | Unadjusted => false,
         Rust | RustCall | RustCold | RustIntrinsic => {
             tcx.sess.panic_strategy() == PanicStrategy::Unwind
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 2f4dc8abfcd..841f255dc3a 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -188,9 +188,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 | [sym::rustc_must_implement_one_of, ..]
                 | [sym::rustc_deny_explicit_impl, ..]
                 | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target),
-                [sym::cmse_nonsecure_entry, ..] => {
-                    self.check_cmse_nonsecure_entry(hir_id, attr, span, target)
-                }
                 [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
                 [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
                 [sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
@@ -563,27 +560,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Checks if `#[cmse_nonsecure_entry]` is applied to a function definition.
-    fn check_cmse_nonsecure_entry(
-        &self,
-        hir_id: HirId,
-        attr: &Attribute,
-        span: Span,
-        target: Target,
-    ) {
-        match target {
-            Target::Fn
-            | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {}
-            _ => {
-                self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                    attr_span: attr.span,
-                    defn_span: span,
-                    on_crate: hir_id == CRATE_HIR_ID,
-                });
-            }
-        }
-    }
-
     /// Debugging aid for `object_lifetime_default` query.
     fn check_object_lifetime_default(&self, hir_id: HirId) {
         let tcx = self.tcx;
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 6458c888431..fc9d8f998dc 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -138,6 +138,61 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
         );
         assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation");
     }
+
+    /// Determines whether the const argument `AnonConst` is a simple macro call, optionally
+    /// surrounded with braces.
+    ///
+    /// If this const argument *is* a trivial macro call then the id for the macro call is
+    /// returned along with the information required to build the anon const's def if
+    /// the macro call expands to a non-trivial expression.
+    fn is_const_arg_trivial_macro_expansion(
+        &self,
+        anon_const: &'a AnonConst,
+    ) -> Option<(PendingAnonConstInfo, NodeId)> {
+        let (block_was_stripped, expr) = anon_const.value.maybe_unwrap_block();
+        match expr {
+            Expr { kind: ExprKind::MacCall(..), id, .. } => Some((
+                PendingAnonConstInfo {
+                    id: anon_const.id,
+                    span: anon_const.value.span,
+                    block_was_stripped,
+                },
+                *id,
+            )),
+            _ => None,
+        }
+    }
+
+    /// Determines whether the expression `const_arg_sub_expr` is a simple macro call, sometimes
+    /// surrounded with braces if a set of braces has not already been entered. This is required
+    /// as `{ N }` is treated as equivalent to a bare parameter `N` whereas `{{ N }}` is treated as
+    /// a real block expression and is lowered to an anonymous constant which is not allowed to use
+    /// generic parameters.
+    ///
+    /// If this expression is a trivial macro call then the id for the macro call is
+    /// returned along with the information required to build the anon const's def if
+    /// the macro call expands to a non-trivial expression.
+    fn is_const_arg_sub_expr_trivial_macro_expansion(
+        &self,
+        const_arg_sub_expr: &'a Expr,
+    ) -> Option<(PendingAnonConstInfo, NodeId)> {
+        let pending_anon = self.pending_anon_const_info.unwrap_or_else(||
+            panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"),
+        );
+
+        let (block_was_stripped, expr) = if pending_anon.block_was_stripped {
+            (true, const_arg_sub_expr)
+        } else {
+            const_arg_sub_expr.maybe_unwrap_block()
+        };
+
+        match expr {
+            Expr { kind: ExprKind::MacCall(..), id, .. } => {
+                Some((PendingAnonConstInfo { block_was_stripped, ..pending_anon }, *id))
+            }
+            _ => None,
+        }
+    }
 }
 
 impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
@@ -354,12 +409,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         // items will be messed up, but that's ok because there can't be any if we're just looking
         // for bare idents.
 
-        if matches!(constant.value.maybe_unwrap_block().kind, ExprKind::MacCall(..)) {
-            // See self.pending_anon_const_info for explanation
-            self.pending_anon_const_info =
-                Some(PendingAnonConstInfo { id: constant.id, span: constant.value.span });
-            return visit::walk_anon_const(self, constant);
-        } else if constant.value.is_potential_trivial_const_arg() {
+        if let Some((pending_anon, macro_invoc)) =
+            self.is_const_arg_trivial_macro_expansion(constant)
+        {
+            self.pending_anon_const_info = Some(pending_anon);
+            return self.visit_macro_invoc(macro_invoc);
+        } else if constant.value.is_potential_trivial_const_arg(true) {
             return visit::walk_anon_const(self, constant);
         }
 
@@ -368,23 +423,36 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'a Expr) {
-        if matches!(expr.kind, ExprKind::MacCall(..)) {
-            return self.visit_macro_invoc(expr.id);
+        // If we're visiting the expression of a const argument that was a macro call then
+        // check if it is *still* unknown whether it is a trivial const arg or not. If so
+        // recurse into the macro call and delay creating the anon const def until expansion.
+        if self.pending_anon_const_info.is_some()
+            && let Some((pending_anon, macro_invoc)) =
+                self.is_const_arg_sub_expr_trivial_macro_expansion(expr)
+        {
+            self.pending_anon_const_info = Some(pending_anon);
+            return self.visit_macro_invoc(macro_invoc);
         }
 
-        let grandparent_def = if let Some(pending_anon) = self.pending_anon_const_info.take() {
-            // See self.pending_anon_const_info for explanation
-            if !expr.is_potential_trivial_const_arg() {
+        // See self.pending_anon_const_info for explanation
+        let parent_def = self
+            .pending_anon_const_info
+            .take()
+            // If we already stripped away a set of braces then do not do it again when determining
+            // if the macro expanded to a trivial const arg. This arises in cases such as:
+            // `Foo<{ bar!() }>` where `bar!()` expands to `{ N }`. This should not be considered a
+            // trivial const argument even though `{ N }` by itself *is*.
+            .filter(|pending_anon| {
+                !expr.is_potential_trivial_const_arg(!pending_anon.block_was_stripped)
+            })
+            .map(|pending_anon| {
                 self.create_def(pending_anon.id, kw::Empty, DefKind::AnonConst, pending_anon.span)
-            } else {
-                self.parent_def
-            }
-        } else {
-            self.parent_def
-        };
+            })
+            .unwrap_or(self.parent_def);
 
-        self.with_parent(grandparent_def, |this| {
+        self.with_parent(parent_def, |this| {
             let parent_def = match expr.kind {
+                ExprKind::MacCall(..) => return this.visit_macro_invoc(expr.id),
                 ExprKind::Closure(..) | ExprKind::Gen(..) => {
                     this.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
                 }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index ac03a3ac42c..4c84e3621dc 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -404,6 +404,8 @@ pub(crate) enum PathSource<'a> {
     Delegation,
     /// An arg in a `use<'a, N>` precise-capturing bound.
     PreciseCapturingArg(Namespace),
+    // Paths that end with `(..)`, for return type notation.
+    ReturnTypeNotation,
 }
 
 impl<'a> PathSource<'a> {
@@ -413,7 +415,8 @@ impl<'a> PathSource<'a> {
             PathSource::Expr(..)
             | PathSource::Pat
             | PathSource::TupleStruct(..)
-            | PathSource::Delegation => ValueNS,
+            | PathSource::Delegation
+            | PathSource::ReturnTypeNotation => ValueNS,
             PathSource::TraitItem(ns) => ns,
             PathSource::PreciseCapturingArg(ns) => ns,
         }
@@ -425,7 +428,8 @@ impl<'a> PathSource<'a> {
             | PathSource::Expr(..)
             | PathSource::Pat
             | PathSource::Struct
-            | PathSource::TupleStruct(..) => true,
+            | PathSource::TupleStruct(..)
+            | PathSource::ReturnTypeNotation => true,
             PathSource::Trait(_)
             | PathSource::TraitItem(..)
             | PathSource::Delegation
@@ -471,7 +475,7 @@ impl<'a> PathSource<'a> {
                 },
                 _ => "value",
             },
-            PathSource::Delegation => "function",
+            PathSource::ReturnTypeNotation | PathSource::Delegation => "function",
             PathSource::PreciseCapturingArg(..) => "type or const parameter",
         }
     }
@@ -540,6 +544,10 @@ impl<'a> PathSource<'a> {
                 Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
                 _ => false,
             },
+            PathSource::ReturnTypeNotation => match res {
+                Res::Def(DefKind::AssocFn, _) => true,
+                _ => false,
+            },
             PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
             PathSource::PreciseCapturingArg(ValueNS) => {
                 matches!(res, Res::Def(DefKind::ConstParam, _))
@@ -565,8 +573,8 @@ impl<'a> PathSource<'a> {
             (PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425,
             (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,
             (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
-            (PathSource::TraitItem(..), true) => E0575,
-            (PathSource::TraitItem(..), false) => E0576,
+            (PathSource::TraitItem(..), true) | (PathSource::ReturnTypeNotation, true) => E0575,
+            (PathSource::TraitItem(..), false) | (PathSource::ReturnTypeNotation, false) => E0576,
             (PathSource::PreciseCapturingArg(..), true) => E0799,
             (PathSource::PreciseCapturingArg(..), false) => E0800,
         }
@@ -781,7 +789,20 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
             }
             TyKind::Path(qself, path) => {
                 self.diag_metadata.current_type_path = Some(ty);
-                self.smart_resolve_path(ty.id, qself, path, PathSource::Type);
+
+                // If we have a path that ends with `(..)`, then it must be
+                // return type notation. Resolve that path in the *value*
+                // namespace.
+                let source = if let Some(seg) = path.segments.last()
+                    && let Some(args) = &seg.args
+                    && matches!(**args, GenericArgs::ParenthesizedElided(..))
+                {
+                    PathSource::ReturnTypeNotation
+                } else {
+                    PathSource::Type
+                };
+
+                self.smart_resolve_path(ty.id, qself, path, source);
 
                 // Check whether we should interpret this as a bare trait object.
                 if qself.is_none()
@@ -1920,7 +1941,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::Trait(..)
                 | PathSource::TraitItem(..)
                 | PathSource::Type
-                | PathSource::PreciseCapturingArg(..) => false,
+                | PathSource::PreciseCapturingArg(..)
+                | PathSource::ReturnTypeNotation => false,
                 PathSource::Expr(..)
                 | PathSource::Pat
                 | PathSource::Struct
@@ -4524,7 +4546,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         );
 
         self.resolve_anon_const_manual(
-            constant.value.is_potential_trivial_const_arg(),
+            constant.value.is_potential_trivial_const_arg(true),
             anon_const_kind,
             |this| this.resolve_expr(&constant.value, None),
         )
@@ -4688,7 +4710,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     // that is how they will be later lowered to HIR.
                     if const_args.contains(&idx) {
                         self.resolve_anon_const_manual(
-                            argument.is_potential_trivial_const_arg(),
+                            argument.is_potential_trivial_const_arg(true),
                             AnonConstKind::ConstArg(IsRepeatExpr::No),
                             |this| this.resolve_expr(argument, None),
                         );
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index c05bd9e72ea..3bb1f6b52a7 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -190,6 +190,11 @@ impl InvocationParent {
 
 #[derive(Copy, Debug, Clone)]
 struct PendingAnonConstInfo {
+    // A const arg is only a "trivial" const arg if it has at *most* one set of braces
+    // around the argument. We track whether we have stripped an outter brace so that
+    // if a macro expands to a braced expression *and* the macro was itself inside of
+    // some braces then we can consider it to be a non-trivial const argument.
+    block_was_stripped: bool,
     id: NodeId,
     span: Span,
 }
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index f52cb010a87..e9c3b3ffc1d 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -470,6 +470,7 @@ impl RustcInternal for Abi {
             Abi::AvrInterrupt => rustc_target::spec::abi::Abi::AvrInterrupt,
             Abi::AvrNonBlockingInterrupt => rustc_target::spec::abi::Abi::AvrNonBlockingInterrupt,
             Abi::CCmseNonSecureCall => rustc_target::spec::abi::Abi::CCmseNonSecureCall,
+            Abi::CCmseNonSecureEntry => rustc_target::spec::abi::Abi::CCmseNonSecureEntry,
             Abi::System { unwind } => rustc_target::spec::abi::Abi::System { unwind },
             Abi::RustIntrinsic => rustc_target::spec::abi::Abi::RustIntrinsic,
             Abi::RustCall => rustc_target::spec::abi::Abi::RustCall,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
index 9f554ec6c35..06f01aebf9b 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
@@ -105,6 +105,7 @@ impl<'tcx> Stable<'tcx> for rustc_target::abi::call::Conv {
             Conv::PreserveAll => CallConvention::PreserveAll,
             Conv::ArmAapcs => CallConvention::ArmAapcs,
             Conv::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
+            Conv::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
             Conv::Msp430Intr => CallConvention::Msp430Intr,
             Conv::PtxKernel => CallConvention::PtxKernel,
             Conv::X86Fastcall => CallConvention::X86Fastcall,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index efbb0f244fc..74bdf97ac44 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -910,6 +910,7 @@ impl<'tcx> Stable<'tcx> for rustc_target::spec::abi::Abi {
             abi::Abi::AvrInterrupt => Abi::AvrInterrupt,
             abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
             abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
+            abi::Abi::CCmseNonSecureEntry => Abi::CCmseNonSecureEntry,
             abi::Abi::System { unwind } => Abi::System { unwind },
             abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
             abi::Abi::RustCall => Abi::RustCall,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 060ee4a1bc2..f4469467249 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -779,6 +779,7 @@ pub enum Conv {
     // Target-specific calling conventions.
     ArmAapcs,
     CCmseNonSecureCall,
+    CCmseNonSecureEntry,
 
     Msp430Intr,
 
@@ -972,6 +973,7 @@ impl FromStr for Conv {
             "RustCold" => Ok(Conv::Rust),
             "ArmAapcs" => Ok(Conv::ArmAapcs),
             "CCmseNonSecureCall" => Ok(Conv::CCmseNonSecureCall),
+            "CCmseNonSecureEntry" => Ok(Conv::CCmseNonSecureEntry),
             "Msp430Intr" => Ok(Conv::Msp430Intr),
             "PtxKernel" => Ok(Conv::PtxKernel),
             "X86Fastcall" => Ok(Conv::X86Fastcall),
diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs
index 9436e34d380..5fcf5be101f 100644
--- a/compiler/rustc_target/src/json.rs
+++ b/compiler/rustc_target/src/json.rs
@@ -103,6 +103,7 @@ impl ToJson for crate::abi::call::Conv {
             Self::PreserveAll => "PreserveAll",
             Self::ArmAapcs => "ArmAapcs",
             Self::CCmseNonSecureCall => "CCmseNonSecureCall",
+            Self::CCmseNonSecureEntry => "CCmseNonSecureEntry",
             Self::Msp430Intr => "Msp430Intr",
             Self::PtxKernel => "PtxKernel",
             Self::X86Fastcall => "X86Fastcall",
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs
index cc383f88fbc..cac0cf9959d 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_target/src/spec/abi/mod.rs
@@ -48,6 +48,7 @@ pub enum Abi {
     AvrInterrupt,
     AvrNonBlockingInterrupt,
     CCmseNonSecureCall,
+    CCmseNonSecureEntry,
     System {
         unwind: bool,
     },
@@ -124,6 +125,7 @@ const AbiDatas: &[AbiData] = &[
     AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt" },
     AbiData { abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt" },
     AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call" },
+    AbiData { abi: Abi::CCmseNonSecureEntry, name: "C-cmse-nonsecure-entry" },
     AbiData { abi: Abi::System { unwind: false }, name: "system" },
     AbiData { abi: Abi::System { unwind: true }, name: "system-unwind" },
     AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic" },
@@ -244,6 +246,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
             feature: sym::abi_c_cmse_nonsecure_call,
             explain: "C-cmse-nonsecure-call ABI is experimental and subject to change",
         }),
+        "C-cmse-nonsecure-entry" => Err(AbiDisabled::Unstable {
+            feature: sym::cmse_nonsecure_entry,
+            explain: "C-cmse-nonsecure-entry ABI is experimental and subject to change",
+        }),
         _ => Err(AbiDisabled::Unrecognized),
     }
 }
@@ -286,15 +292,16 @@ impl Abi {
             AvrInterrupt => 23,
             AvrNonBlockingInterrupt => 24,
             CCmseNonSecureCall => 25,
+            CCmseNonSecureEntry => 26,
             // Cross-platform ABIs
-            System { unwind: false } => 26,
-            System { unwind: true } => 27,
-            RustIntrinsic => 28,
-            RustCall => 29,
-            Unadjusted => 30,
-            RustCold => 31,
-            RiscvInterruptM => 32,
-            RiscvInterruptS => 33,
+            System { unwind: false } => 27,
+            System { unwind: true } => 28,
+            RustIntrinsic => 29,
+            RustCall => 30,
+            Unadjusted => 31,
+            RustCold => 32,
+            RiscvInterruptM => 33,
+            RiscvInterruptS => 34,
         };
         debug_assert!(
             AbiDatas
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 1d478f84c43..ec4f5ef79d1 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2724,7 +2724,10 @@ impl Target {
             }
             X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
             Aapcs { .. } => "arm" == self.arch,
-            CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
+            CCmseNonSecureCall | CCmseNonSecureEntry => {
+                ["thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf", "thumbv8m.base-none-eabi"]
+                    .contains(&&self.llvm_target[..])
+            }
             Win64 { .. } | SysV64 { .. } => self.arch == "x86_64",
             PtxKernel => self.arch == "nvptx64",
             Msp430Interrupt => self.arch == "msp430",
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 2de6ee9cf91..1f11ee3f939 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -2269,12 +2269,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     }
                     rustc_transmute::Reason::SrcSizeOverflow => {
                         format!(
-                            "values of the type `{src}` are too big for the current architecture"
+                            "values of the type `{src}` are too big for the target architecture"
                         )
                     }
                     rustc_transmute::Reason::DstSizeOverflow => {
                         format!(
-                            "values of the type `{dst}` are too big for the current architecture"
+                            "values of the type `{dst}` are too big for the target architecture"
                         )
                     }
                     rustc_transmute::Reason::DstHasStricterAlignment {
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 2d0c2e83690..00d38350b20 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -312,6 +312,7 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
         SysV64 { .. } => Conv::X86_64SysV,
         Aapcs { .. } => Conv::ArmAapcs,
         CCmseNonSecureCall => Conv::CCmseNonSecureCall,
+        CCmseNonSecureEntry => Conv::CCmseNonSecureEntry,
         PtxKernel => Conv::PtxKernel,
         Msp430Interrupt => Conv::Msp430Intr,
         X86Interrupt => Conv::X86Intr,
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs
index 317bec3050c..dc73d9c2188 100644
--- a/compiler/stable_mir/src/abi.rs
+++ b/compiler/stable_mir/src/abi.rs
@@ -433,6 +433,7 @@ pub enum CallConvention {
     // Target-specific calling conventions.
     ArmAapcs,
     CCmseNonSecureCall,
+    CCmseNonSecureEntry,
 
     Msp430Intr,
 
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 5bad3d5ae7a..011d19f6143 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -1062,6 +1062,7 @@ pub enum Abi {
     AvrInterrupt,
     AvrNonBlockingInterrupt,
     CCmseNonSecureCall,
+    CCmseNonSecureEntry,
     System { unwind: bool },
     RustIntrinsic,
     RustCall,
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index d58a016b502..83977350832 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2087,7 +2087,31 @@ impl FromUtf8Error {
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "string_from_utf8_lossy_owned", issue = "129436")]
     pub fn into_utf8_lossy(self) -> String {
-        String::from_utf8_lossy_owned(self.bytes)
+        const REPLACEMENT: &str = "\u{FFFD}";
+
+        let mut res = {
+            let mut v = Vec::with_capacity(self.bytes.len());
+
+            // `Utf8Error::valid_up_to` returns the maximum index of validated
+            // UTF-8 bytes. Copy the valid bytes into the output buffer.
+            v.extend_from_slice(&self.bytes[..self.error.valid_up_to()]);
+
+            // SAFETY: This is safe because the only bytes present in the buffer
+            // were validated as UTF-8 by the call to `String::from_utf8` which
+            // produced this `FromUtf8Error`.
+            unsafe { String::from_utf8_unchecked(v) }
+        };
+
+        let iter = self.bytes[self.error.valid_up_to()..].utf8_chunks();
+
+        for chunk in iter {
+            res.push_str(chunk.valid());
+            if !chunk.invalid().is_empty() {
+                res.push_str(REPLACEMENT);
+            }
+        }
+
+        res
     }
 
     /// Returns the bytes that were attempted to convert to a `String`.
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index ffc9a233b66..1d07a7690da 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -28,6 +28,7 @@
 #![feature(iter_next_chunk)]
 #![feature(round_char_boundary)]
 #![feature(slice_partition_dedup)]
+#![feature(string_from_utf8_lossy_owned)]
 #![feature(string_remove_matches)]
 #![feature(const_btree_len)]
 #![feature(const_trait_impl)]
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs
index dc03c4860e8..d996c55f946 100644
--- a/library/alloc/tests/string.rs
+++ b/library/alloc/tests/string.rs
@@ -115,6 +115,43 @@ fn test_from_utf8_lossy() {
 }
 
 #[test]
+fn test_fromutf8error_into_lossy() {
+    fn func(input: &[u8]) -> String {
+        String::from_utf8(input.to_owned()).unwrap_or_else(|e| e.into_utf8_lossy())
+    }
+
+    let xs = b"hello";
+    let ys = "hello".to_owned();
+    assert_eq!(func(xs), ys);
+
+    let xs = "ศไทย中华Việt Nam".as_bytes();
+    let ys = "ศไทย中华Việt Nam".to_owned();
+    assert_eq!(func(xs), ys);
+
+    let xs = b"Hello\xC2 There\xFF Goodbye";
+    assert_eq!(func(xs), "Hello\u{FFFD} There\u{FFFD} Goodbye".to_owned());
+
+    let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
+    assert_eq!(func(xs), "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye".to_owned());
+
+    let xs = b"\xF5foo\xF5\x80bar";
+    assert_eq!(func(xs), "\u{FFFD}foo\u{FFFD}\u{FFFD}bar".to_owned());
+
+    let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
+    assert_eq!(func(xs), "\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz".to_owned());
+
+    let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
+    assert_eq!(func(xs), "\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz".to_owned());
+
+    let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
+    assert_eq!(func(xs), "\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar".to_owned());
+
+    // surrogates
+    let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
+    assert_eq!(func(xs), "\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar".to_owned());
+}
+
+#[test]
 fn test_from_utf16() {
     let pairs = [
         (
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 5451e45f6c8..962da6643dd 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1761,6 +1761,8 @@ mod prim_ref {}
 /// - `i32` is ABI-compatible with `NonZero<i32>`, and similar for all other integer types.
 /// - If `T` is guaranteed to be subject to the [null pointer
 ///   optimization](option/index.html#representation), then `T` and `Option<T>` are ABI-compatible.
+///   Furthermore, if `U` satisfies the requirements [outlined here](result/index.html#representation),
+///   then `T` and `Result<T, U>` and `Result<U, T>` are all ABI-compatible.
 ///
 /// Furthermore, ABI compatibility satisfies the following general properties:
 ///
diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile
index 855465aa38e..475542b3356 100644
--- a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile
@@ -25,5 +25,5 @@ ENV CC_arm_unknown_linux_gnueabihf=arm-unknown-linux-gnueabihf-gcc \
 
 ENV HOSTS=arm-unknown-linux-gnueabihf
 
-ENV RUST_CONFIGURE_ARGS --enable-full-tools --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-full-tools --enable-profiler --disable-docs
 ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md b/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md
index 338fbc4b2bf..ca95ccf33ac 100644
--- a/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md
+++ b/src/doc/unstable-book/src/language-features/cmse-nonsecure-entry.md
@@ -15,10 +15,10 @@ LLVM, the Rust compiler and the linker are providing
 TrustZone-M feature.
 
 One of the things provided, with this unstable feature, is the
-`cmse_nonsecure_entry` attribute.  This attribute marks a Secure function as an
+`C-cmse-nonsecure-entry` ABI. This ABI marks a Secure function as an
 entry function (see [section
 5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
-With this attribute, the compiler will do the following:
+With this ABI, the compiler will do the following:
 * add a special symbol on the function which is the `__acle_se_` prefix and the
   standard function name
 * constrain the number of parameters to avoid using the Non-Secure stack
@@ -38,11 +38,11 @@ gateway veneer.
 <!-- NOTE(ignore) this example is specific to thumbv8m targets -->
 
 ``` rust,ignore
+#![no_std]
 #![feature(cmse_nonsecure_entry)]
 
 #[no_mangle]
-#[cmse_nonsecure_entry]
-pub extern "C" fn entry_function(input: u32) -> u32 {
+pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
     input + 6
 }
 ```
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index e4966690d8c..654fb564848 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -30,7 +30,7 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) -
         locals.len()
     ];
 
-    traversal::Postorder::new(&mir.basic_blocks, location.block)
+    traversal::Postorder::new(&mir.basic_blocks, location.block, ())
         .collect::<Vec<_>>()
         .into_iter()
         .rev()
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index c3276d82d4f..76fe17316ac 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-c0838c8ebec23fb87855bb6de3a287981cb1df98
+6ce376774c0bc46ac8be247bca93ff5a1287a8fc
diff --git a/src/tools/miri/rustfmt.toml b/src/tools/miri/rustfmt.toml
index be5af7379ea..3f9311d9d1a 100644
--- a/src/tools/miri/rustfmt.toml
+++ b/src/tools/miri/rustfmt.toml
@@ -1,4 +1,4 @@
-version = "Two"
+style_edition = "2024"
 use_small_heuristics = "Max"
 match_arm_blocks = false
 match_arm_leading_pipes = "Preserve"
diff --git a/src/tools/miri/tests/fail/type-too-large.stderr b/src/tools/miri/tests/fail/type-too-large.stderr
index 15ad8f1764d..cd27b246389 100644
--- a/src/tools/miri/tests/fail/type-too-large.stderr
+++ b/src/tools/miri/tests/fail/type-too-large.stderr
@@ -1,8 +1,8 @@
-error: post-monomorphization error: values of the type `[u8; 2305843011361177600]` are too big for the current architecture
+error: post-monomorphization error: values of the type `[u8; 2305843011361177600]` are too big for the target architecture
   --> tests/fail/type-too-large.rs:LL:CC
    |
 LL |     _fat = [0; (1u64 << 61) as usize + (1u64 << 31) as usize];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843011361177600]` are too big for the current architecture
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843011361177600]` are too big for the target architecture
    |
    = note: BACKTRACE:
    = note: inside `main` at tests/fail/type-too-large.rs:LL:CC
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 2f4e764f4ce..26ab02558a1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -377,6 +377,7 @@ pub enum FnAbi {
     AvrNonBlockingInterrupt,
     C,
     CCmseNonsecureCall,
+    CCmseNonsecureEntry,
     CDecl,
     CDeclUnwind,
     CUnwind,
@@ -434,6 +435,7 @@ impl FnAbi {
             s if *s == sym::avr_dash_interrupt => FnAbi::AvrInterrupt,
             s if *s == sym::avr_dash_non_dash_blocking_dash_interrupt => FnAbi::AvrNonBlockingInterrupt,
             s if *s == sym::C_dash_cmse_dash_nonsecure_dash_call => FnAbi::CCmseNonsecureCall,
+            s if *s == sym::C_dash_cmse_dash_nonsecure_dash_entry => FnAbi::CCmseNonsecureEntry,
             s if *s == sym::C_dash_unwind => FnAbi::CUnwind,
             s if *s == sym::C => FnAbi::C,
             s if *s == sym::cdecl_dash_unwind => FnAbi::CDeclUnwind,
@@ -477,6 +479,7 @@ impl FnAbi {
             FnAbi::AvrNonBlockingInterrupt => "avr-non-blocking-interrupt",
             FnAbi::C => "C",
             FnAbi::CCmseNonsecureCall => "C-cmse-nonsecure-call",
+            FnAbi::CCmseNonsecureEntry => "C-cmse-nonsecure-entry",
             FnAbi::CDecl => "C-decl",
             FnAbi::CDeclUnwind => "cdecl-unwind",
             FnAbi::CUnwind => "C-unwind",
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
index 1a06e0a3a0e..b0e417e6b33 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
@@ -32,6 +32,7 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
     "riscv-interrupt-m",
     "riscv-interrupt-s",
     "C-cmse-nonsecure-call",
+    "C-cmse-nonsecure-entry",
     "wasm",
     "system",
     "system-unwind",
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index 7eb8e4a5e2e..c066f504891 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -94,6 +94,7 @@ define_symbols! {
     avr_dash_interrupt = "avr-interrupt",
     avr_dash_non_dash_blocking_dash_interrupt = "avr-non-blocking-interrupt",
     C_dash_cmse_dash_nonsecure_dash_call = "C-cmse-nonsecure-call",
+    C_dash_cmse_dash_nonsecure_dash_entry = "C-cmse-nonsecure-entry",
     C_dash_unwind = "C-unwind",
     cdecl_dash_unwind = "cdecl-unwind",
     fastcall_dash_unwind = "fastcall-unwind",
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index b2de3457dec..3879f350e94 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -467,7 +467,6 @@ ui/closures/issue-87814-2.rs
 ui/closures/issue-90871.rs
 ui/closures/issue-97607.rs
 ui/closures/issue-99565.rs
-ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs
 ui/codegen/auxiliary/issue-97708-aux.rs
 ui/codegen/issue-101585-128bit-repeat.rs
 ui/codegen/issue-16602-1.rs
@@ -552,7 +551,6 @@ ui/const-generics/infer/issue-77092.rs
 ui/const-generics/issue-102124.rs
 ui/const-generics/issue-105689.rs
 ui/const-generics/issue-106419-struct-with-multiple-const-params.rs
-ui/const-generics/issue-112505-overflow.rs
 ui/const-generics/issue-46511.rs
 ui/const-generics/issue-66451.rs
 ui/const-generics/issue-70408.rs
@@ -2717,7 +2715,6 @@ ui/limits/issue-15919-32.rs
 ui/limits/issue-15919-64.rs
 ui/limits/issue-17913.rs
 ui/limits/issue-55878.rs
-ui/limits/issue-56762.rs
 ui/limits/issue-69485-var-size-diffs-too-large.rs
 ui/limits/issue-75158-64.rs
 ui/linkage-attr/auxiliary/issue-12133-dylib.rs
diff --git a/tests/assembly/cmse.rs b/tests/assembly/cmse.rs
new file mode 100644
index 00000000000..acad77b2513
--- /dev/null
+++ b/tests/assembly/cmse.rs
@@ -0,0 +1,26 @@
+//@ assembly-output: emit-asm
+//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1
+//@ needs-llvm-components: arm
+#![crate_type = "lib"]
+#![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)]
+#![no_core]
+#[lang = "sized"]
+pub trait Sized {}
+#[lang = "copy"]
+pub trait Copy {}
+
+// CHECK-LABEL: __acle_se_entry_point
+// CHECK: bxns
+#[no_mangle]
+pub extern "C-cmse-nonsecure-entry" fn entry_point() -> i64 {
+    0
+}
+
+// CHECK-LABEL: call_nonsecure
+// CHECK: blxns
+#[no_mangle]
+pub fn call_nonsecure(
+    f: unsafe extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u64,
+) -> u64 {
+    unsafe { f(0, 1, 2, 3) }
+}
diff --git a/tests/codegen/constant-branch.rs b/tests/codegen/constant-branch.rs
index a2710cc4b25..8fc8fb4f57a 100644
--- a/tests/codegen/constant-branch.rs
+++ b/tests/codegen/constant-branch.rs
@@ -7,18 +7,19 @@
 // CHECK-LABEL: @if_bool
 #[no_mangle]
 pub fn if_bool() {
-    // CHECK: br label %{{.+}}
+    // CHECK-NOT: br i1
+    // CHECK-NOT: switch
     _ = if true { 0 } else { 1 };
 
-    // CHECK: br label %{{.+}}
     _ = if false { 0 } else { 1 };
 }
 
 // CHECK-LABEL: @if_constant_int_eq
 #[no_mangle]
 pub fn if_constant_int_eq() {
+    // CHECK-NOT: br i1
+    // CHECK-NOT: switch
     let val = 0;
-    // CHECK: br label %{{.+}}
     _ = if val == 0 { 0 } else { 1 };
 
     // CHECK: br label %{{.+}}
@@ -28,23 +29,20 @@ pub fn if_constant_int_eq() {
 // CHECK-LABEL: @if_constant_match
 #[no_mangle]
 pub fn if_constant_match() {
-    // CHECK: br label %{{.+}}
+    // CHECK-NOT: br i1
+    // CHECK-NOT: switch
     _ = match 1 {
         1 => 2,
         2 => 3,
         _ => 4,
     };
 
-    // CHECK: br label %{{.+}}
     _ = match 1 {
         2 => 3,
         _ => 4,
     };
 
-    // CHECK: br label %[[MINUS1:.+]]
     _ = match -1 {
-        // CHECK: [[MINUS1]]:
-        // CHECK: store i32 1
         -1 => 1,
         _ => 0,
     }
diff --git a/tests/codegen/no-alloca-inside-if-false.rs b/tests/codegen/no-alloca-inside-if-false.rs
new file mode 100644
index 00000000000..a231c7e808a
--- /dev/null
+++ b/tests/codegen/no-alloca-inside-if-false.rs
@@ -0,0 +1,27 @@
+//@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 -Cpanic=abort
+// Check that there's an alloca for the reference and the vector, but nothing else.
+// We use panic=abort because unwinding panics give hint::black_box a cleanup block, which has
+// another alloca.
+
+#![crate_type = "lib"]
+
+#[inline(never)]
+fn test<const SIZE: usize>() {
+    // CHECK-LABEL: no_alloca_inside_if_false::test
+    // CHECK: start:
+    // CHECK-NEXT: alloca [{{12|24}} x i8]
+    // CHECK-NOT: alloca
+    if const { SIZE < 4096 } {
+        let arr = [0u8; SIZE];
+        std::hint::black_box(&arr);
+    } else {
+        let vec = vec![0u8; SIZE];
+        std::hint::black_box(&vec);
+    }
+}
+
+// CHECK-LABEL: @main
+#[no_mangle]
+pub fn main() {
+    test::<8192>();
+}
diff --git a/tests/crashes/125476.rs b/tests/crashes/125476.rs
index aa9a081388d..ad739639b72 100644
--- a/tests/crashes/125476.rs
+++ b/tests/crashes/125476.rs
@@ -1,4 +1,4 @@
 //@ known-bug: rust-lang/rust#125476
 //@ only-x86_64
-pub struct Data([u8; usize::MAX >> 16]);
+pub struct Data([u8; usize::MAX >> 2]);
 const _: &'static [Data] = &[];
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs
index a8c8a85c5aa..af64901ace0 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs
+++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs
@@ -16,4 +16,22 @@ fn bar<T: Trait<method() -> (): Send>>() {}
 fn baz<T: Trait<method(): Send>>() {}
 //~^ ERROR return type notation arguments must be elided with `..`
 
+fn foo_path<T: Trait>() where T::method(i32): Send {}
+//~^ ERROR argument types not allowed with return type notation
+
+fn bar_path<T: Trait>() where T::method() -> (): Send {}
+//~^ ERROR return type not allowed with return type notation
+
+fn baz_path<T: Trait>() where T::method(): Send {}
+//~^ ERROR return type notation arguments must be elided with `..`
+
+fn foo_qualified<T: Trait>() where <T as Trait>::method(i32): Send {}
+//~^ ERROR expected associated type
+
+fn bar_qualified<T: Trait>() where <T as Trait>::method() -> (): Send {}
+//~^ ERROR expected associated type
+
+fn baz_qualified<T: Trait>() where <T as Trait>::method(): Send {}
+//~^ ERROR expected associated type
+
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr
index 7e1695984f1..68081470087 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr
@@ -1,3 +1,21 @@
+error[E0575]: expected associated type, found associated function `Trait::method`
+  --> $DIR/bad-inputs-and-output.rs:28:36
+   |
+LL | fn foo_qualified<T: Trait>() where <T as Trait>::method(i32): Send {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type
+
+error[E0575]: expected associated type, found associated function `Trait::method`
+  --> $DIR/bad-inputs-and-output.rs:31:36
+   |
+LL | fn bar_qualified<T: Trait>() where <T as Trait>::method() -> (): Send {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type
+
+error[E0575]: expected associated type, found associated function `Trait::method`
+  --> $DIR/bad-inputs-and-output.rs:34:36
+   |
+LL | fn baz_qualified<T: Trait>() where <T as Trait>::method(): Send {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^ not a associated type
+
 warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/bad-inputs-and-output.rs:3:12
    |
@@ -25,5 +43,24 @@ error: return type notation arguments must be elided with `..`
 LL | fn baz<T: Trait<method(): Send>>() {}
    |                       ^^ help: add `..`: `(..)`
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: argument types not allowed with return type notation
+  --> $DIR/bad-inputs-and-output.rs:19:40
+   |
+LL | fn foo_path<T: Trait>() where T::method(i32): Send {}
+   |                                        ^^^^^ help: remove the input types: `()`
+
+error: return type not allowed with return type notation
+  --> $DIR/bad-inputs-and-output.rs:22:42
+   |
+LL | fn bar_path<T: Trait>() where T::method() -> (): Send {}
+   |                                          ^^^^^^ help: remove the return type
+
+error: return type notation arguments must be elided with `..`
+  --> $DIR/bad-inputs-and-output.rs:25:40
+   |
+LL | fn baz_path<T: Trait>() where T::method(): Send {}
+   |                                        ^^ help: add `..`: `(..)`
+
+error: aborting due to 9 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0575`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs b/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs
index f507d82afec..185c0523633 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs
+++ b/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs
@@ -10,17 +10,12 @@ trait Tr {
 fn foo<T: Tr>()
 where
     T::method(..): Send,
-    //~^ ERROR return type notation not allowed in this position yet
-    //~| ERROR expected type, found function
     <T as Tr>::method(..): Send,
-    //~^ ERROR return type notation not allowed in this position yet
-    //~| ERROR expected associated type, found associated function `Tr::method`
 {
     let _ = T::CONST::(..);
     //~^ ERROR return type notation not allowed in this position yet
     let _: T::method(..);
     //~^ ERROR return type notation not allowed in this position yet
-    //~| ERROR expected type, found function
 }
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr b/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr
index cb45de59c7e..dca2bdeab0a 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr
@@ -1,9 +1,3 @@
-error[E0575]: expected associated type, found associated function `Tr::method`
-  --> $DIR/bare-path.rs:15:5
-   |
-LL |     <T as Tr>::method(..): Send,
-   |     ^^^^^^^^^^^^^^^^^^^^^ not a associated type
-
 warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/bare-path.rs:1:12
    |
@@ -14,53 +8,16 @@ LL | #![feature(return_type_notation)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error: return type notation not allowed in this position yet
-  --> $DIR/bare-path.rs:19:23
+  --> $DIR/bare-path.rs:15:23
    |
 LL |     let _ = T::CONST::(..);
    |                       ^^^^
 
 error: return type notation not allowed in this position yet
-  --> $DIR/bare-path.rs:21:21
+  --> $DIR/bare-path.rs:17:12
    |
 LL |     let _: T::method(..);
-   |                     ^^^^
-
-error: return type notation not allowed in this position yet
-  --> $DIR/bare-path.rs:12:14
-   |
-LL |     T::method(..): Send,
-   |              ^^^^
-
-error: return type notation not allowed in this position yet
-  --> $DIR/bare-path.rs:15:22
-   |
-LL |     <T as Tr>::method(..): Send,
-   |                      ^^^^
-
-error: expected type, found function
-  --> $DIR/bare-path.rs:12:8
-   |
-LL |     T::method(..): Send,
-   |        ^^^^^^ unexpected function
-   |
-note: the associated function is defined here
-  --> $DIR/bare-path.rs:7:5
-   |
-LL |     fn method() -> impl Sized;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: expected type, found function
-  --> $DIR/bare-path.rs:21:15
-   |
-LL |     let _: T::method(..);
-   |               ^^^^^^ unexpected function
-   |
-note: the associated function is defined here
-  --> $DIR/bare-path.rs:7:5
-   |
-LL |     fn method() -> impl Sized;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0575`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs b/tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs
new file mode 100644
index 00000000000..d4f21f47c6c
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs
@@ -0,0 +1,52 @@
+//@ check-pass
+
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Trait<'a> {
+    fn late<'b>(&'b self, _: &'a ()) -> impl Sized;
+    fn early<'b: 'b>(&'b self, _: &'a ()) -> impl Sized;
+}
+
+#[allow(refining_impl_trait_internal)]
+impl<'a> Trait<'a> for () {
+    fn late<'b>(&'b self, _: &'a ()) -> i32 { 1 }
+    fn early<'b: 'b>(&'b self, _: &'a ()) -> i32 { 1 }
+}
+
+trait Other<'c> {}
+impl Other<'_> for i32 {}
+
+fn test<T>(t: &T)
+where
+    T: for<'a, 'c> Trait<'a, late(..): Other<'c>>,
+    // which is basically:
+    // for<'a, 'c> Trait<'a, for<'b> method<'b>: Other<'c>>,
+    T: for<'a, 'c> Trait<'a, early(..): Other<'c>>,
+    // which is basically:
+    // for<'a, 'c> Trait<'a, for<'b> method<'b>: Other<'c>>,
+{
+    is_other_impl(t.late(&()));
+    is_other_impl(t.early(&()));
+}
+
+fn test_path<T>(t: &T)
+where
+T: for<'a> Trait<'a>,
+    for<'a, 'c> <T as Trait<'a>>::late(..): Other<'c>,
+    // which is basically:
+    // for<'a, 'b, 'c> <T as Trait<'a>>::method::<'b>: Other<'c>
+    for<'a, 'c> <T as Trait<'a>>::early(..): Other<'c>,
+    // which is basically:
+    // for<'a, 'b, 'c> <T as Trait<'a>>::method::<'b>: Other<'c>
+{
+    is_other_impl(t.late(&()));
+    is_other_impl(t.early(&()));
+}
+
+fn is_other_impl(_: impl for<'c> Other<'c>) {}
+
+fn main() {
+    test(&());
+    test(&());
+}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.stderr b/tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.stderr
new file mode 100644
index 00000000000..c67231c07f7
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/higher-ranked-bound-works.rs:3:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.rs b/tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.rs
new file mode 100644
index 00000000000..9bdc2d00233
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.rs
@@ -0,0 +1,42 @@
+//@ check-pass
+
+#![allow(non_camel_case_types)]
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Foo {
+    type test;
+
+    fn test() -> impl Bar;
+}
+
+fn call_path<T: Foo>()
+where
+    T::test(..): Bar,
+{
+}
+
+fn call_bound<T: Foo<test(..): Bar>>() {}
+
+trait Bar {}
+struct NotBar;
+struct YesBar;
+impl Bar for YesBar {}
+
+impl Foo for () {
+    type test = NotBar;
+
+    // Use refinement here so we can observe `YesBar: Bar`.
+    #[allow(refining_impl_trait_internal)]
+    fn test() -> YesBar {
+        YesBar
+    }
+}
+
+fn main() {
+    // If `T::test(..)` resolved to the GAT (erroneously), then this would be
+    // an error since `<() as Foo>::bar` -- the associated type -- does not
+    // implement `Bar`, but the return type of the method does.
+    call_path::<()>();
+    call_bound::<()>();
+}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.stderr b/tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.stderr
new file mode 100644
index 00000000000..f4ece074b28
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/namespace-conflict.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/namespace-conflict.rs:4:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs
index d283c6eab37..35d6dd799c7 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs
+++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs
@@ -5,7 +5,10 @@ trait Trait {
     fn method() {}
 }
 
-fn test<T: Trait<method(..): Send>>() {}
-//~^ ERROR  return type notation used on function that is not `async` and does not return `impl Trait`
+fn bound<T: Trait<method(..): Send>>() {}
+//~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait`
+
+fn path<T>() where T: Trait, T::method(..): Send {}
+//~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait`
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr
index 79ced3c96ed..e308c927bf0 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr
@@ -8,15 +8,26 @@ LL | #![feature(return_type_notation)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error: return type notation used on function that is not `async` and does not return `impl Trait`
-  --> $DIR/non-rpitit.rs:8:18
+  --> $DIR/non-rpitit.rs:8:19
    |
 LL |     fn method() {}
    |     ----------- this function must be `async` or return `impl Trait`
 ...
-LL | fn test<T: Trait<method(..): Send>>() {}
-   |                  ^^^^^^^^^^^^^^^^
+LL | fn bound<T: Trait<method(..): Send>>() {}
+   |                   ^^^^^^^^^^^^^^^^
    |
    = note: function returns `()`, which is not compatible with associated type return bounds
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: return type notation used on function that is not `async` and does not return `impl Trait`
+  --> $DIR/non-rpitit.rs:11:30
+   |
+LL |     fn method() {}
+   |     ----------- this function must be `async` or return `impl Trait`
+...
+LL | fn path<T>() where T: Trait, T::method(..): Send {}
+   |                              ^^^^^^^^^^^^^
+   |
+   = note: function returns `()`, which is not compatible with associated type return bounds
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/associated-type-bounds/return-type-notation/not-a-method.rs b/tests/ui/associated-type-bounds/return-type-notation/not-a-method.rs
new file mode 100644
index 00000000000..d94ec6b74d9
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/not-a-method.rs
@@ -0,0 +1,42 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+fn function() {}
+
+fn not_a_method()
+where
+    function(..): Send,
+    //~^ ERROR expected function, found function `function`
+    //~| ERROR return type notation not allowed in this position yet
+{
+}
+
+fn not_a_method_and_typoed()
+where
+    function(): Send,
+    //~^ ERROR expected type, found function `function`
+{
+}
+
+trait Tr {
+    fn method();
+}
+
+// Forgot the `T::`
+fn maybe_method_overlaps<T: Tr>()
+where
+    method(..): Send,
+    //~^ ERROR cannot find function `method` in this scope
+    //~| ERROR return type notation not allowed in this position yet
+{
+}
+
+// Forgot the `T::`, AND typoed `(..)` to `()`
+fn maybe_method_overlaps_and_typoed<T: Tr>()
+where
+    method(): Send,
+    //~^ ERROR cannot find type `method` in this scope
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/not-a-method.stderr b/tests/ui/associated-type-bounds/return-type-notation/not-a-method.stderr
new file mode 100644
index 00000000000..8add2d46296
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/not-a-method.stderr
@@ -0,0 +1,49 @@
+error[E0575]: expected function, found function `function`
+  --> $DIR/not-a-method.rs:8:5
+   |
+LL |     function(..): Send,
+   |     ^^^^^^^^^^^^ not a function
+
+error[E0573]: expected type, found function `function`
+  --> $DIR/not-a-method.rs:16:5
+   |
+LL |     function(): Send,
+   |     ^^^^^^^^^^ not a type
+
+error[E0576]: cannot find function `method` in this scope
+  --> $DIR/not-a-method.rs:28:5
+   |
+LL |     method(..): Send,
+   |     ^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `method` in this scope
+  --> $DIR/not-a-method.rs:37:5
+   |
+LL |     method(): Send,
+   |     ^^^^^^ not found in this scope
+
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/not-a-method.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: return type notation not allowed in this position yet
+  --> $DIR/not-a-method.rs:8:5
+   |
+LL |     function(..): Send,
+   |     ^^^^^^^^^^^^
+
+error: return type notation not allowed in this position yet
+  --> $DIR/not-a-method.rs:28:5
+   |
+LL |     method(..): Send,
+   |     ^^^^^^^^^^
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0412, E0573, E0575, E0576.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.rs b/tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.rs
new file mode 100644
index 00000000000..cb42c33e364
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.rs
@@ -0,0 +1,27 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait A {
+    fn method() -> impl Sized;
+}
+trait B {
+    fn method() -> impl Sized;
+}
+
+fn ambiguous<T: A + B>()
+where
+    T::method(..): Send,
+    //~^ ERROR ambiguous associated function `method` in bounds of `T`
+{
+}
+
+trait Sub: A + B {}
+
+fn ambiguous_via_supertrait<T: Sub>()
+where
+    T::method(..): Send,
+    //~^ ERROR ambiguous associated function `method` in bounds of `T`
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.stderr
new file mode 100644
index 00000000000..e841049ac66
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-ambiguous.stderr
@@ -0,0 +1,54 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-ambiguous.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0221]: ambiguous associated function `method` in bounds of `T`
+  --> $DIR/path-ambiguous.rs:13:5
+   |
+LL |     fn method() -> impl Sized;
+   |     -------------------------- ambiguous `method` from `A`
+...
+LL |     fn method() -> impl Sized;
+   |     -------------------------- ambiguous `method` from `B`
+...
+LL |     T::method(..): Send,
+   |     ^^^^^^^^^^^^^ ambiguous associated function `method`
+   |
+help: use fully-qualified syntax to disambiguate
+   |
+LL |     <T as B>::method(..): Send,
+   |     ~~~~~~~~~~
+help: use fully-qualified syntax to disambiguate
+   |
+LL |     <T as A>::method(..): Send,
+   |     ~~~~~~~~~~
+
+error[E0221]: ambiguous associated function `method` in bounds of `T`
+  --> $DIR/path-ambiguous.rs:22:5
+   |
+LL |     fn method() -> impl Sized;
+   |     -------------------------- ambiguous `method` from `A`
+...
+LL |     fn method() -> impl Sized;
+   |     -------------------------- ambiguous `method` from `B`
+...
+LL |     T::method(..): Send,
+   |     ^^^^^^^^^^^^^ ambiguous associated function `method`
+   |
+help: use fully-qualified syntax to disambiguate
+   |
+LL |     <T as B>::method(..): Send,
+   |     ~~~~~~~~~~
+help: use fully-qualified syntax to disambiguate
+   |
+LL |     <T as A>::method(..): Send,
+   |     ~~~~~~~~~~
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0221`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.rs b/tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.rs
new file mode 100644
index 00000000000..56abd167fb6
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Trait {
+    fn method() -> impl Sized;
+}
+
+fn is_send(_: impl Send) {}
+
+struct W<T>(T);
+
+impl<T> W<T> {
+    fn test()
+    where
+        T: Trait,
+        T::method(..): Send,
+    {
+        is_send(T::method());
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.stderr
new file mode 100644
index 00000000000..3db033d8cf5
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-constrained-in-method.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-constrained-in-method.rs:3:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.rs b/tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.rs
new file mode 100644
index 00000000000..a4d8f005371
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.rs
@@ -0,0 +1,25 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait A<'a> {
+    fn method() -> impl Sized;
+}
+trait B: for<'a> A<'a> {}
+
+fn higher_ranked<T>()
+where
+    T: for<'a> A<'a>,
+    T::method(..): Send,
+    //~^ ERROR cannot use the associated function of a trait with uninferred generic parameters
+{
+}
+
+fn higher_ranked_via_supertrait<T>()
+where
+    T: B,
+    T::method(..): Send,
+    //~^ ERROR cannot use the associated function of a trait with uninferred generic parameters
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.stderr
new file mode 100644
index 00000000000..22de6165503
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-higher-ranked.stderr
@@ -0,0 +1,34 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-higher-ranked.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0212]: cannot use the associated function of a trait with uninferred generic parameters
+  --> $DIR/path-higher-ranked.rs:12:5
+   |
+LL |     T::method(..): Send,
+   |     ^^^^^^^^^^^^^
+   |
+help: use a fully qualified path with inferred lifetimes
+   |
+LL |     <T as A<'_>>::method(..): Send,
+   |     ~~~~~~~~~~~~~~
+
+error[E0212]: cannot use the associated function of a trait with uninferred generic parameters
+  --> $DIR/path-higher-ranked.rs:20:5
+   |
+LL |     T::method(..): Send,
+   |     ^^^^^^^^^^^^^
+   |
+help: use a fully qualified path with inferred lifetimes
+   |
+LL |     <T as A<'_>>::method(..): Send,
+   |     ~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0212`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-missing.rs b/tests/ui/associated-type-bounds/return-type-notation/path-missing.rs
new file mode 100644
index 00000000000..c1a7b95ca2d
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-missing.rs
@@ -0,0 +1,25 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait A {
+    #[allow(non_camel_case_types)]
+    type bad;
+}
+
+fn fully_qualified<T: A>()
+where
+    <T as A>::method(..): Send,
+    //~^ ERROR cannot find method or associated constant `method` in trait `A`
+    <T as A>::bad(..): Send,
+    //~^ ERROR expected method or associated constant, found associated type `A::bad`
+{
+}
+
+fn type_dependent<T: A>()
+where
+    T::method(..): Send,
+    //~^ associated function `method` not found for `T`
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr
new file mode 100644
index 00000000000..0130c3bc614
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-missing.stderr
@@ -0,0 +1,33 @@
+error[E0576]: cannot find method or associated constant `method` in trait `A`
+  --> $DIR/path-missing.rs:11:15
+   |
+LL |     <T as A>::method(..): Send,
+   |               ^^^^^^ not found in `A`
+
+error[E0575]: expected method or associated constant, found associated type `A::bad`
+  --> $DIR/path-missing.rs:13:5
+   |
+LL |     <T as A>::bad(..): Send,
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-missing.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0220]: associated function `method` not found for `T`
+  --> $DIR/path-missing.rs:20:8
+   |
+LL |     T::method(..): Send,
+   |        ^^^^^^ associated function `method` not found
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0220, E0575, E0576.
+For more information about an error, try `rustc --explain E0220`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-no-qself.rs b/tests/ui/associated-type-bounds/return-type-notation/path-no-qself.rs
new file mode 100644
index 00000000000..d2636789c10
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-no-qself.rs
@@ -0,0 +1,15 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Trait {
+    fn method() -> impl Sized;
+}
+
+fn test()
+where
+    Trait::method(..): Send,
+    //~^ ERROR ambiguous associated type
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-no-qself.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-no-qself.stderr
new file mode 100644
index 00000000000..d66b0a109fc
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-no-qself.stderr
@@ -0,0 +1,23 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-no-qself.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0223]: ambiguous associated type
+  --> $DIR/path-no-qself.rs:10:5
+   |
+LL |     Trait::method(..): Send,
+   |     ^^^^^^^^^^^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL |     <Example as Trait>::method: Send,
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.rs b/tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.rs
new file mode 100644
index 00000000000..b0e6ea852b0
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.rs
@@ -0,0 +1,21 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Trait {
+    fn method() -> impl Sized;
+}
+
+struct Adt;
+
+fn non_param_qself()
+where
+    <()>::method(..): Send,
+    //~^ ERROR ambiguous associated function
+    i32::method(..): Send,
+    //~^ ERROR ambiguous associated function
+    Adt::method(..): Send,
+    //~^ ERROR ambiguous associated function
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.stderr
new file mode 100644
index 00000000000..cd1aa9813e3
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.stderr
@@ -0,0 +1,30 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-non-param-qself.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0223]: ambiguous associated function
+  --> $DIR/path-non-param-qself.rs:12:5
+   |
+LL |     <()>::method(..): Send,
+   |     ^^^^^^^^^^^^^^^^
+
+error[E0223]: ambiguous associated function
+  --> $DIR/path-non-param-qself.rs:14:5
+   |
+LL |     i32::method(..): Send,
+   |     ^^^^^^^^^^^^^^^
+
+error[E0223]: ambiguous associated function
+  --> $DIR/path-non-param-qself.rs:16:5
+   |
+LL |     Adt::method(..): Send,
+   |     ^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-self-qself.rs b/tests/ui/associated-type-bounds/return-type-notation/path-self-qself.rs
new file mode 100644
index 00000000000..0cf84457ba7
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-self-qself.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Foo {
+    fn method() -> impl Sized;
+}
+
+trait Bar: Foo {
+    fn other()
+    where
+        Self::method(..): Send;
+}
+
+fn is_send(_: impl Send) {}
+
+impl<T: Foo> Bar for T {
+    fn other()
+    where
+        Self::method(..): Send,
+    {
+        is_send(Self::method());
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-self-qself.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-self-qself.stderr
new file mode 100644
index 00000000000..ab33647583c
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-self-qself.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-self-qself.rs:3:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-type-param.rs b/tests/ui/associated-type-bounds/return-type-notation/path-type-param.rs
new file mode 100644
index 00000000000..693a300eb1d
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-type-param.rs
@@ -0,0 +1,22 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Foo {
+    fn method<T>() -> impl Sized;
+}
+
+fn test<T: Foo>()
+where
+    <T as Foo>::method(..): Send,
+    //~^ ERROR return type notation is not allowed for functions that have type parameters
+{
+}
+
+fn test_type_dependent<T: Foo>()
+where
+    <T as Foo>::method(..): Send,
+    //~^ ERROR return type notation is not allowed for functions that have type parameters
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-type-param.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-type-param.stderr
new file mode 100644
index 00000000000..0d33d4f97d7
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-type-param.stderr
@@ -0,0 +1,29 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-type-param.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: return type notation is not allowed for functions that have type parameters
+  --> $DIR/path-type-param.rs:10:5
+   |
+LL |     fn method<T>() -> impl Sized;
+   |               - type parameter declared here
+...
+LL |     <T as Foo>::method(..): Send,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: return type notation is not allowed for functions that have type parameters
+  --> $DIR/path-type-param.rs:17:5
+   |
+LL |     fn method<T>() -> impl Sized;
+   |               - type parameter declared here
+...
+LL |     <T as Foo>::method(..): Send,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.rs b/tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.rs
new file mode 100644
index 00000000000..a5b0b0e4e25
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.rs
@@ -0,0 +1,25 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Trait {
+    fn method() -> impl Sized;
+}
+
+struct DoesntWork;
+impl Trait for DoesntWork {
+    fn method() -> impl Sized {
+        std::ptr::null_mut::<()>()
+        // This isn't `Send`.
+    }
+}
+
+fn test<T: Trait>()
+where
+    T::method(..): Send,
+{
+}
+
+fn main() {
+    test::<DoesntWork>();
+    //~^ ERROR `*mut ()` cannot be sent between threads safely
+}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.stderr
new file mode 100644
index 00000000000..7d32a428555
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-unsatisfied.stderr
@@ -0,0 +1,36 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-unsatisfied.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `*mut ()` cannot be sent between threads safely
+  --> $DIR/path-unsatisfied.rs:23:12
+   |
+LL |     fn method() -> impl Sized {
+   |                    ---------- within this `impl Sized`
+...
+LL |     test::<DoesntWork>();
+   |            ^^^^^^^^^^ `*mut ()` cannot be sent between threads safely
+   |
+   = help: within `impl Sized`, the trait `Send` is not implemented for `*mut ()`, which is required by `impl Sized: Send`
+note: required because it appears within the type `impl Sized`
+  --> $DIR/path-unsatisfied.rs:10:20
+   |
+LL |     fn method() -> impl Sized {
+   |                    ^^^^^^^^^^
+note: required by a bound in `test`
+  --> $DIR/path-unsatisfied.rs:18:20
+   |
+LL | fn test<T: Trait>()
+   |    ---- required by a bound in this function
+LL | where
+LL |     T::method(..): Send,
+   |                    ^^^^ required by this bound in `test`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-works.rs b/tests/ui/associated-type-bounds/return-type-notation/path-works.rs
new file mode 100644
index 00000000000..027bc89f13e
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-works.rs
@@ -0,0 +1,23 @@
+//@ check-pass
+
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+trait Trait {
+    fn method() -> impl Sized;
+}
+
+struct Works;
+impl Trait for Works {
+    fn method() -> impl Sized {}
+}
+
+fn test<T: Trait>()
+where
+    T::method(..): Send,
+{
+}
+
+fn main() {
+    test::<Works>();
+}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/path-works.stderr b/tests/ui/associated-type-bounds/return-type-notation/path-works.stderr
new file mode 100644
index 00000000000..b1ec8069ba0
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/path-works.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/path-works.rs:3:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/attributes/issue-105594-invalid-attr-validation.rs b/tests/ui/attributes/issue-105594-invalid-attr-validation.rs
index bea5faf7253..cb196471fd7 100644
--- a/tests/ui/attributes/issue-105594-invalid-attr-validation.rs
+++ b/tests/ui/attributes/issue-105594-invalid-attr-validation.rs
@@ -1,13 +1,7 @@
 // This checks that the attribute validation ICE in issue #105594 doesn't
 // recur.
-//
-//@ ignore-thumbv8m.base-none-eabi
-#![feature(cmse_nonsecure_entry)]
 
 fn main() {}
 
 #[track_caller] //~ ERROR attribute should be applied to a function
 static _A: () = ();
-
-#[cmse_nonsecure_entry] //~ ERROR attribute should be applied to a function
-static _B: () = (); //~| ERROR #[cmse_nonsecure_entry]` is only valid for targets
diff --git a/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr b/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr
index c6b2d6e7813..1248967c47b 100644
--- a/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr
+++ b/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr
@@ -1,26 +1,11 @@
 error[E0739]: attribute should be applied to a function definition
-  --> $DIR/issue-105594-invalid-attr-validation.rs:9:1
+  --> $DIR/issue-105594-invalid-attr-validation.rs:6:1
    |
 LL | #[track_caller]
    | ^^^^^^^^^^^^^^^
 LL | static _A: () = ();
    | ------------------- not a function definition
 
-error: attribute should be applied to a function definition
-  --> $DIR/issue-105594-invalid-attr-validation.rs:12:1
-   |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-LL | static _B: () = ();
-   | ------------------- not a function definition
-
-error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension
-  --> $DIR/issue-105594-invalid-attr-validation.rs:12:1
-   |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0739, E0775.
-For more information about an error, try `rustc --explain E0739`.
+For more information about this error, try `rustc --explain E0739`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs
new file mode 100644
index 00000000000..37c8319d98d
--- /dev/null
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs
@@ -0,0 +1,20 @@
+//@ build-pass
+//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
+//@ needs-llvm-components: arm
+#![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items, intrinsics)]
+#![no_core]
+#[lang = "sized"]
+pub trait Sized {}
+#[lang = "copy"]
+pub trait Copy {}
+impl Copy for u32 {}
+
+#[no_mangle]
+pub extern "C-cmse-nonsecure-entry" fn test(
+    f: extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u32,
+    a: u32,
+    b: u32,
+    c: u32,
+) -> u32 {
+    f(a, b, c, 42)
+}
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.rs
index 02d5f20febc..6061451b2e9 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.rs
@@ -1,10 +1,9 @@
 // gate-test-cmse_nonsecure_entry
 
 #[no_mangle]
-#[cmse_nonsecure_entry]
-//~^ ERROR [E0775]
-//~| ERROR [E0658]
-pub extern "C" fn entry_function(input: u32) -> u32 {
+pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+    //~^ ERROR [E0570]
+    //~| ERROR [E0658]
     input + 6
 }
 
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.stderr
index beb9716d590..dabf16cab30 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.stderr
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/gate_test.stderr
@@ -1,20 +1,20 @@
-error[E0658]: the `#[cmse_nonsecure_entry]` attribute is an experimental feature
-  --> $DIR/gate_test.rs:4:1
+error[E0658]: C-cmse-nonsecure-entry ABI is experimental and subject to change
+  --> $DIR/gate_test.rs:4:12
    |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
+LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #75835 <https://github.com/rust-lang/rust/issues/75835> for more information
    = help: add `#![feature(cmse_nonsecure_entry)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension
+error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
   --> $DIR/gate_test.rs:4:1
    |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
+LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0658, E0775.
-For more information about an error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0570, E0658.
+For more information about an error, try `rustc --explain E0570`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs
deleted file mode 100644
index a839406cd0a..00000000000
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Regression test for the ICE described in #83475.
-
-#![crate_type="lib"]
-
-#![feature(cmse_nonsecure_entry)]
-#[cmse_nonsecure_entry]
-//~^ ERROR: attribute should be applied to a function definition
-struct XEmpty2;
-//~^ NOTE: not a function definition
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr
deleted file mode 100644
index 26d3bfe7837..00000000000
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: attribute should be applied to a function definition
-  --> $DIR/issue-83475.rs:6:1
-   |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-LL |
-LL | struct XEmpty2;
-   | --------------- not a function definition
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs
index e197f94096d..de6888fae62 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs
@@ -3,14 +3,14 @@
 //@ needs-llvm-components: arm
 #![feature(cmse_nonsecure_entry, no_core, lang_items)]
 #![no_core]
-#[lang="sized"]
-trait Sized { }
-#[lang="copy"]
-trait Copy { }
+#![crate_type = "lib"]
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
 impl Copy for u32 {}
 
 #[no_mangle]
-#[cmse_nonsecure_entry]
-pub extern "C" fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
+pub extern "C-cmse-nonsecure-entry" fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
     d
 }
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs
index e2da3ebb6ae..4413c461c04 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs
@@ -3,14 +3,19 @@
 //@ needs-llvm-components: arm
 #![feature(cmse_nonsecure_entry, no_core, lang_items)]
 #![no_core]
-#[lang="sized"]
-trait Sized { }
-#[lang="copy"]
-trait Copy { }
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
 impl Copy for u32 {}
 
 #[no_mangle]
-#[cmse_nonsecure_entry]
-pub extern "C" fn entry_function(_: u32, _: u32, _: u32, _: u32, e: u32) -> u32 {
+pub extern "C-cmse-nonsecure-entry" fn entry_function(
+    _: u32,
+    _: u32,
+    _: u32,
+    _: u32,
+    e: u32,
+) -> u32 {
     e
 }
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr
new file mode 100644
index 00000000000..26409279fbe
--- /dev/null
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr
@@ -0,0 +1,9 @@
+error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
+  --> $DIR/trustzone-only.rs:20:1
+   |
+LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs
index 87eccb4fc6e..a4ea7a1757d 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs
@@ -1,10 +1,25 @@
-//@ ignore-thumbv8m.main-none-eabi
-#![feature(cmse_nonsecure_entry)]
+//@ revisions: x86 aarch64 thumb7
+//
+//@[x86] compile-flags: --target x86_64-unknown-linux-gnu
+//@[x86] needs-llvm-components: x86
+//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64] needs-llvm-components: aarch64
+//@[thumb7] compile-flags: --target thumbv7em-none-eabi
+//@[thumb7] needs-llvm-components: arm
+#![feature(no_core, lang_items, rustc_attrs, cmse_nonsecure_entry)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for u32 {}
 
 #[no_mangle]
-#[cmse_nonsecure_entry] //~ ERROR [E0775]
-pub extern "C" fn entry_function(input: u32) -> u32 {
-    input + 6
+pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+    //~^ ERROR [E0570]
+    input
 }
 
 fn main() {}
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr
deleted file mode 100644
index 3e6954394f4..00000000000
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension
-  --> $DIR/trustzone-only.rs:5:1
-   |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0775`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr
new file mode 100644
index 00000000000..26409279fbe
--- /dev/null
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr
@@ -0,0 +1,9 @@
+error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
+  --> $DIR/trustzone-only.rs:20:1
+   |
+LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr
new file mode 100644
index 00000000000..26409279fbe
--- /dev/null
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr
@@ -0,0 +1,9 @@
+error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
+  --> $DIR/trustzone-only.rs:20:1
+   |
+LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
deleted file mode 100644
index db4f90e9923..00000000000
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-//@ needs-llvm-components: arm
-#![feature(cmse_nonsecure_entry, no_core, lang_items)]
-#![no_core]
-#[lang = "sized"]
-trait Sized {}
-
-#[lang = "copy"]
-trait Copy {}
-
-#[no_mangle]
-#[cmse_nonsecure_entry]
-//~^ ERROR `#[cmse_nonsecure_entry]` requires C ABI [E0776]
-pub fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
-    d
-}
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
deleted file mode 100644
index c3fae3d8bbb..00000000000
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0776]: `#[cmse_nonsecure_entry]` requires C ABI
-  --> $DIR/wrong-abi.rs:12:1
-   |
-LL | #[cmse_nonsecure_entry]
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0776`.
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.rs b/tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.rs
new file mode 100644
index 00000000000..33630205369
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.rs
@@ -0,0 +1,14 @@
+macro_rules! y {
+    () => {
+        N
+    };
+}
+
+struct A<const N: usize>;
+
+fn foo<const N: usize>() -> A<{ y!() }> {
+    A::<1>
+    //~^ ERROR: mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.stderr b/tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.stderr
new file mode 100644
index 00000000000..4461477f3e9
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-braced-expansion.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/trivial-const-arg-macro-braced-expansion.rs:10:5
+   |
+LL | fn foo<const N: usize>() -> A<{ y!() }> {
+   |                             ----------- expected `A<N>` because of return type
+LL |     A::<1>
+   |     ^^^^^^ expected `N`, found `1`
+   |
+   = note: expected struct `A<N>`
+              found struct `A<1>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.rs b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.rs
new file mode 100644
index 00000000000..5a9e62561dc
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.rs
@@ -0,0 +1,15 @@
+macro_rules! y {
+    () => {
+        N
+        //~^ ERROR: generic parameters may not be used in const operations
+    };
+}
+
+struct A<const N: usize>;
+
+#[rustfmt::skip]
+fn foo<const N: usize>() -> A<{{ y!() }}> {
+    A::<1>
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr
new file mode 100644
index 00000000000..e40d05924b1
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr
@@ -0,0 +1,15 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/trivial-const-arg-macro-nested-braces-2.rs:3:9
+   |
+LL |         N
+   |         ^ cannot perform const operation using `N`
+...
+LL | fn foo<const N: usize>() -> A<{{ y!() }}> {
+   |                                  ---- in this macro invocation
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.rs b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.rs
new file mode 100644
index 00000000000..45c0768dde4
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.rs
@@ -0,0 +1,15 @@
+#[rustfmt::skip]
+macro_rules! y {
+    () => {
+        { N }
+        //~^ ERROR: generic parameters may not be used in const operations
+    };
+}
+
+struct A<const N: usize>;
+
+fn foo<const N: usize>() -> A<{ y!() }> {
+    A::<1>
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr
new file mode 100644
index 00000000000..b91d6c7a024
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr
@@ -0,0 +1,15 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/trivial-const-arg-macro-nested-braces.rs:4:11
+   |
+LL |         { N }
+   |           ^ cannot perform const operation using `N`
+...
+LL | fn foo<const N: usize>() -> A<{ y!() }> {
+   |                                 ---- in this macro invocation
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/const-generics/early/trivial-const-arg-nested-braces.rs b/tests/ui/const-generics/early/trivial-const-arg-nested-braces.rs
new file mode 100644
index 00000000000..941ba6bfea7
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-nested-braces.rs
@@ -0,0 +1,9 @@
+struct A<const N: usize>;
+
+#[rustfmt::skip]
+fn foo<const N: usize>() -> A<{ { N } }> {
+    //~^ ERROR: generic parameters may not be used in const operations
+    A::<1>
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr b/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr
new file mode 100644
index 00000000000..d60516ba4bc
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/trivial-const-arg-nested-braces.rs:4:35
+   |
+LL | fn foo<const N: usize>() -> A<{ { N } }> {
+   |                                   ^ cannot perform const operation using `N`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `N`
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/const-generics/issue-112505-overflow.rs b/tests/ui/const-generics/issue-112505-overflow.rs
deleted file mode 100644
index 0dd7776d595..00000000000
--- a/tests/ui/const-generics/issue-112505-overflow.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#![feature(transmute_generic_consts)]
-
-fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 239] {
-    unsafe { std::mem::transmute(v) } //~ ERROR cannot transmute between types of different sizes
-}
-
-fn main() { }
diff --git a/tests/ui/const-generics/issue-112505-overflow.stderr b/tests/ui/const-generics/issue-112505-overflow.stderr
deleted file mode 100644
index 0bd3f6eddd4..00000000000
--- a/tests/ui/const-generics/issue-112505-overflow.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/issue-112505-overflow.rs:4:14
-   |
-LL |     unsafe { std::mem::transmute(v) }
-   |              ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[u32; 8888888]; 9999999]` are too big for the current architecture)
-   = note: target type: `[[[u32; 9999999]; 777777777]; 239]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/const-generics/transmute-fail.rs b/tests/ui/const-generics/transmute-fail.rs
index 7faf670e468..95c71160567 100644
--- a/tests/ui/const-generics/transmute-fail.rs
+++ b/tests/ui/const-generics/transmute-fail.rs
@@ -1,3 +1,8 @@
+// ignore-tidy-linelength
+//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
+//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
+
+
 #![feature(transmute_generic_consts)]
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features)]
@@ -31,6 +36,11 @@ fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 7777
     }
 }
 
+fn overflow_more(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 239] {
+    unsafe { std::mem::transmute(v) } //~ ERROR cannot transmute between types of different sizes
+}
+
+
 fn transpose<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
     unsafe {
         std::mem::transmute(v)
diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr
index 4a20034910d..638ce790345 100644
--- a/tests/ui/const-generics/transmute-fail.stderr
+++ b/tests/ui/const-generics/transmute-fail.stderr
@@ -1,11 +1,11 @@
 error: the constant `W` is not of type `usize`
-  --> $DIR/transmute-fail.rs:12:42
+  --> $DIR/transmute-fail.rs:17:42
    |
 LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
    |                                          ^^^^^^^^^^^^^ expected `usize`, found `bool`
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:7:9
+  --> $DIR/transmute-fail.rs:12:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -14,13 +14,13 @@ LL |         std::mem::transmute(v)
    = note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1])
 
 error: the constant `W` is not of type `usize`
-  --> $DIR/transmute-fail.rs:15:9
+  --> $DIR/transmute-fail.rs:20:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:22:9
+  --> $DIR/transmute-fail.rs:27:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -29,16 +29,25 @@ LL |         std::mem::transmute(v)
    = note: target type: `[u32; W * H * H]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:29:9
+  --> $DIR/transmute-fail.rs:34:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[u32; 8888888]; 9999999]` are too big for the current architecture)
-   = note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
+   = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type $REALLY_TOO_BIG are too big for the target architecture)
+   = note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type $REALLY_TOO_BIG are too big for the target architecture)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:36:9
+  --> $DIR/transmute-fail.rs:40:14
+   |
+LL |     unsafe { std::mem::transmute(v) }
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type $REALLY_TOO_BIG are too big for the target architecture)
+   = note: target type: `[[[u32; 9999999]; 777777777]; 239]` (values of the type $REALLY_TOO_BIG are too big for the target architecture)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/transmute-fail.rs:46:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -47,7 +56,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:47:9
+  --> $DIR/transmute-fail.rs:57:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -56,7 +65,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[u32; W * H]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:54:9
+  --> $DIR/transmute-fail.rs:64:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -65,7 +74,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:63:9
+  --> $DIR/transmute-fail.rs:73:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -74,7 +83,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:72:9
+  --> $DIR/transmute-fail.rs:82:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -83,7 +92,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:79:9
+  --> $DIR/transmute-fail.rs:89:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -92,7 +101,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[u8; L * 2]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:86:9
+  --> $DIR/transmute-fail.rs:96:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -101,7 +110,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[u16; L]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:93:9
+  --> $DIR/transmute-fail.rs:103:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -110,7 +119,7 @@ LL |         std::mem::transmute(v)
    = note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:102:9
+  --> $DIR/transmute-fail.rs:112:9
    |
 LL |         std::mem::transmute(v)
    |         ^^^^^^^^^^^^^^^^^^^
@@ -118,6 +127,6 @@ LL |         std::mem::transmute(v)
    = note: source type: `[[u32; 2 * H]; W + W]` (size can vary because of [u32; 2 * H])
    = note: target type: `[[u32; W + W]; 2 * H]` (size can vary because of [u32; W + W])
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
 For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
index dc68f6cf71f..a1922c98ef6 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs
@@ -3,7 +3,7 @@
 
 //@ compile-flags:-C debuginfo=2
 //@ build-fail
-//@ error-pattern: too big for the current architecture
+//@ error-pattern: too big for the target architecture
 //@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE"
 //@ normalize-stderr-32bit: "4294967295" -> "SIZE"
 
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr
index 06aad9616cb..a3772e509ed 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[u8; usize::MAX]` are too big for the current architecture
+error: values of the type `[u8; usize::MAX]` are too big for the target architecture
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
index 2b6e85362b6..3456cd55b75 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
@@ -5,7 +5,7 @@
 
 //@ compile-flags:-C debuginfo=2
 //@ build-fail
-//@ error-pattern: too big for the current architecture
+//@ error-pattern: too big for the target architecture
 //@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE"
 //@ normalize-stderr-32bit: "4294967295" -> "SIZE"
 
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr
index 06aad9616cb..a3772e509ed 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[u8; usize::MAX]` are too big for the current architecture
+error: values of the type `[u8; usize::MAX]` are too big for the target architecture
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/extern/extern-static-size-overflow.rs b/tests/ui/extern/extern-static-size-overflow.rs
index a96ce0cf47e..f33e482aa66 100644
--- a/tests/ui/extern/extern-static-size-overflow.rs
+++ b/tests/ui/extern/extern-static-size-overflow.rs
@@ -4,31 +4,13 @@ struct ReallyBig {
 }
 
 // The limit for "too big for the current architecture" is dependent on the target pointer size
-// however it's artificially limited on 64 bits
-// logic copied from rustc_target::abi::TargetDataLayout::obj_size_bound()
+// but is artificially limited due to LLVM's internal architecture
+// logic based on rustc_target::abi::TargetDataLayout::obj_size_bound()
 const fn max_size() -> usize {
-    #[cfg(target_pointer_width = "16")]
-    {
-        1 << 15
-    }
-
-    #[cfg(target_pointer_width = "32")]
-    {
-        1 << 31
-    }
-
-    #[cfg(target_pointer_width = "64")]
-    {
-        1 << 47
-    }
-
-    #[cfg(not(any(
-        target_pointer_width = "16",
-        target_pointer_width = "32",
-        target_pointer_width = "64"
-    )))]
-    {
-        isize::MAX as usize
+    if usize::BITS < 61 {
+        1 << (usize::BITS - 1)
+    } else {
+        1 << 61
     }
 }
 
diff --git a/tests/ui/extern/extern-static-size-overflow.stderr b/tests/ui/extern/extern-static-size-overflow.stderr
index 1c926399591..c6490e96a8e 100644
--- a/tests/ui/extern/extern-static-size-overflow.stderr
+++ b/tests/ui/extern/extern-static-size-overflow.stderr
@@ -1,17 +1,17 @@
-error: extern static is too large for the current architecture
-  --> $DIR/extern-static-size-overflow.rs:38:5
+error: extern static is too large for the target architecture
+  --> $DIR/extern-static-size-overflow.rs:20:5
    |
 LL |     static BAZ: [u8; max_size()];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: extern static is too large for the current architecture
-  --> $DIR/extern-static-size-overflow.rs:39:5
+error: extern static is too large for the target architecture
+  --> $DIR/extern-static-size-overflow.rs:21:5
    |
 LL |     static UWU: [usize; usize::MAX];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: extern static is too large for the current architecture
-  --> $DIR/extern-static-size-overflow.rs:40:5
+error: extern static is too large for the target architecture
+  --> $DIR/extern-static-size-overflow.rs:22:5
    |
 LL |     static A: ReallyBig;
    |     ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/layout/size-of-val-raw-too-big.rs b/tests/ui/layout/size-of-val-raw-too-big.rs
index 8d82c78d953..dfca6d6eb76 100644
--- a/tests/ui/layout/size-of-val-raw-too-big.rs
+++ b/tests/ui/layout/size-of-val-raw-too-big.rs
@@ -1,7 +1,7 @@
 //@ build-fail
 //@ compile-flags: --crate-type lib
 //@ only-32bit Layout computation rejects this layout for different reasons on 64-bit.
-//@ error-pattern: too big for the current architecture
+//@ error-pattern: too big for the target architecture
 #![feature(core_intrinsics)]
 #![allow(internal_features)]
 
diff --git a/tests/ui/layout/size-of-val-raw-too-big.stderr b/tests/ui/layout/size-of-val-raw-too-big.stderr
index aa9abd644fa..886bba9ec9d 100644
--- a/tests/ui/layout/size-of-val-raw-too-big.stderr
+++ b/tests/ui/layout/size-of-val-raw-too-big.stderr
@@ -1,4 +1,4 @@
-error: values of the type `Example` are too big for the current architecture
+error: values of the type `Example` are too big for the target architecture
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/too-big-with-padding.rs b/tests/ui/layout/too-big-with-padding.rs
index 76703100145..8423ad2e1d6 100644
--- a/tests/ui/layout/too-big-with-padding.rs
+++ b/tests/ui/layout/too-big-with-padding.rs
@@ -10,7 +10,7 @@
 #[repr(C, align(2))]
 pub struct Example([u8; 0x7fffffff]);
 
-pub fn lib(_x: Example) {} //~ERROR: too big for the current architecture
+pub fn lib(_x: Example) {} //~ERROR: too big for the target architecture
 
 #[lang = "sized"]
 pub trait Sized {}
diff --git a/tests/ui/layout/too-big-with-padding.stderr b/tests/ui/layout/too-big-with-padding.stderr
index 71309788dac..fc3b4db049a 100644
--- a/tests/ui/layout/too-big-with-padding.stderr
+++ b/tests/ui/layout/too-big-with-padding.stderr
@@ -1,4 +1,4 @@
-error: values of the type `Example` are too big for the current architecture
+error: values of the type `Example` are too big for the target architecture
   --> $DIR/too-big-with-padding.rs:13:1
    |
 LL | pub fn lib(_x: Example) {}
diff --git a/tests/ui/limits/huge-array-simple-32.rs b/tests/ui/limits/huge-array-simple-32.rs
index 6ff981cd160..db75cc57e9a 100644
--- a/tests/ui/limits/huge-array-simple-32.rs
+++ b/tests/ui/limits/huge-array-simple-32.rs
@@ -4,6 +4,6 @@
 #![allow(arithmetic_overflow)]
 
 fn main() {
-    let _fat: [u8; (1<<31)+(1<<15)] = //~ ERROR too big for the current architecture
+    let _fat: [u8; (1<<31)+(1<<15)] = //~ ERROR too big for the target architecture
         [0; (1u32<<31) as usize +(1u32<<15) as usize];
 }
diff --git a/tests/ui/limits/huge-array-simple-32.stderr b/tests/ui/limits/huge-array-simple-32.stderr
index 1b86b02297f..33979915feb 100644
--- a/tests/ui/limits/huge-array-simple-32.stderr
+++ b/tests/ui/limits/huge-array-simple-32.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[u8; 2147516416]` are too big for the current architecture
+error: values of the type `[u8; 2147516416]` are too big for the target architecture
   --> $DIR/huge-array-simple-32.rs:7:9
    |
 LL |     let _fat: [u8; (1<<31)+(1<<15)] =
diff --git a/tests/ui/limits/huge-array-simple-64.rs b/tests/ui/limits/huge-array-simple-64.rs
index 13b284503bf..d2838e0d41e 100644
--- a/tests/ui/limits/huge-array-simple-64.rs
+++ b/tests/ui/limits/huge-array-simple-64.rs
@@ -4,6 +4,6 @@
 #![allow(arithmetic_overflow)]
 
 fn main() {
-    let _fat: [u8; (1<<61)+(1<<31)] = //~ ERROR too big for the current architecture
+    let _fat: [u8; (1<<61)+(1<<31)] = //~ ERROR too big for the target architecture
         [0; (1u64<<61) as usize +(1u64<<31) as usize];
 }
diff --git a/tests/ui/limits/huge-array-simple-64.stderr b/tests/ui/limits/huge-array-simple-64.stderr
index 8d395c3c6a9..46df288d4f7 100644
--- a/tests/ui/limits/huge-array-simple-64.stderr
+++ b/tests/ui/limits/huge-array-simple-64.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[u8; 2305843011361177600]` are too big for the current architecture
+error: values of the type `[u8; 2305843011361177600]` are too big for the target architecture
   --> $DIR/huge-array-simple-64.rs:7:9
    |
 LL |     let _fat: [u8; (1<<61)+(1<<31)] =
diff --git a/tests/ui/limits/huge-array.stderr b/tests/ui/limits/huge-array.stderr
index 2ebaf17a138..ce0c0d650c2 100644
--- a/tests/ui/limits/huge-array.stderr
+++ b/tests/ui/limits/huge-array.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[[u8; 1518599999]; 1518600000]` are too big for the current architecture
+error: values of the type `[[u8; 1518599999]; 1518600000]` are too big for the target architecture
   --> $DIR/huge-array.rs:4:9
    |
 LL |     let s: [T; 1518600000] = [t; 1518600000];
diff --git a/tests/ui/limits/huge-enum.rs b/tests/ui/limits/huge-enum.rs
index cf6e637388c..5664d0ba516 100644
--- a/tests/ui/limits/huge-enum.rs
+++ b/tests/ui/limits/huge-enum.rs
@@ -6,9 +6,9 @@
 type BIG = Option<[u32; (1<<29)-1]>;
 
 #[cfg(target_pointer_width = "64")]
-type BIG = Option<[u32; (1<<45)-1]>;
+type BIG = Option<[u32; (1<<59)-1]>;
 
 fn main() {
     let big: BIG = None;
-    //~^ ERROR are too big for the current architecture
+    //~^ ERROR are too big for the target architecture
 }
diff --git a/tests/ui/limits/huge-enum.stderr b/tests/ui/limits/huge-enum.stderr
index fcd40607af4..18168b3fa5c 100644
--- a/tests/ui/limits/huge-enum.stderr
+++ b/tests/ui/limits/huge-enum.stderr
@@ -1,4 +1,4 @@
-error: values of the type `Option<TYPE>` are too big for the current architecture
+error: values of the type `Option<TYPE>` are too big for the target architecture
   --> $DIR/huge-enum.rs:12:9
    |
 LL |     let big: BIG = None;
diff --git a/tests/ui/limits/issue-56762.rs b/tests/ui/limits/huge-static.rs
index 17b3ad8b01e..4709b46e59d 100644
--- a/tests/ui/limits/issue-56762.rs
+++ b/tests/ui/limits/huge-static.rs
@@ -1,6 +1,9 @@
-//@ only-x86_64
+//@ only-64bit
 
-const HUGE_SIZE: usize = !0usize / 8;
+// This test validates we gracefully fail computing a const or static of absurdly large size.
+// The oddly-specific number is because of LLVM measuring object sizes in bits.
+
+const HUGE_SIZE: usize = 1 << 61;
 
 
 pub struct TooBigArray {
diff --git a/tests/ui/limits/issue-56762.stderr b/tests/ui/limits/huge-static.stderr
index 3a6c3559ac1..684efeeb4a3 100644
--- a/tests/ui/limits/issue-56762.stderr
+++ b/tests/ui/limits/huge-static.stderr
@@ -1,14 +1,14 @@
 error[E0080]: could not evaluate static initializer
-  --> $DIR/issue-56762.rs:16:1
+  --> $DIR/huge-static.rs:19:1
    |
 LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693952]` are too big for the target architecture
 
 error[E0080]: could not evaluate static initializer
-  --> $DIR/issue-56762.rs:19:1
+  --> $DIR/huge-static.rs:22:1
    |
 LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693952]` are too big for the target architecture
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/limits/huge-struct.rs b/tests/ui/limits/huge-struct.rs
index b9e90b3e9d1..f7ce4f26db1 100644
--- a/tests/ui/limits/huge-struct.rs
+++ b/tests/ui/limits/huge-struct.rs
@@ -1,7 +1,9 @@
+// ignore-tidy-linelength
 //@ build-fail
 //@ normalize-stderr-test: "S32" -> "SXX"
 //@ normalize-stderr-test: "S1M" -> "SXX"
-//@ error-pattern: too big for the current
+//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
+//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
 
 struct S32<T> {
     v0: T,
@@ -44,6 +46,6 @@ struct S1M<T> { val: S1k<S1k<T>> }
 
 fn main() {
     let fat: Option<S1M<S1M<S1M<u32>>>> = None;
-    //~^ ERROR are too big for the current architecture
+    //~^ ERROR are too big for the target architecture
 
 }
diff --git a/tests/ui/limits/huge-struct.stderr b/tests/ui/limits/huge-struct.stderr
index 782db20c7f3..b10455ffd2d 100644
--- a/tests/ui/limits/huge-struct.stderr
+++ b/tests/ui/limits/huge-struct.stderr
@@ -1,5 +1,5 @@
-error: values of the type `SXX<SXX<SXX<u32>>>` are too big for the current architecture
-  --> $DIR/huge-struct.rs:46:9
+error: values of the type $REALLY_TOO_BIG are too big for the target architecture
+  --> $DIR/huge-struct.rs:48:9
    |
 LL |     let fat: Option<SXX<SXX<SXX<u32>>>> = None;
    |         ^^^
diff --git a/tests/ui/limits/issue-15919-32.stderr b/tests/ui/limits/issue-15919-32.stderr
index abd65ff3c9e..f162838d37d 100644
--- a/tests/ui/limits/issue-15919-32.stderr
+++ b/tests/ui/limits/issue-15919-32.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[usize; usize::MAX]` are too big for the current architecture
+error: values of the type `[usize; usize::MAX]` are too big for the target architecture
   --> $DIR/issue-15919-32.rs:5:9
    |
 LL |     let x = [0usize; 0xffff_ffff];
diff --git a/tests/ui/limits/issue-15919-64.stderr b/tests/ui/limits/issue-15919-64.stderr
index d1f0cc39c18..cd443f2065b 100644
--- a/tests/ui/limits/issue-15919-64.stderr
+++ b/tests/ui/limits/issue-15919-64.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[usize; usize::MAX]` are too big for the current architecture
+error: values of the type `[usize; usize::MAX]` are too big for the target architecture
   --> $DIR/issue-15919-64.rs:5:9
    |
 LL |     let x = [0usize; 0xffff_ffff_ffff_ffff];
diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs
index 325923f32f3..24fd3b542e6 100644
--- a/tests/ui/limits/issue-17913.rs
+++ b/tests/ui/limits/issue-17913.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 //@ normalize-stderr-test: "\[&usize; \d+\]" -> "[&usize; usize::MAX]"
-//@ error-pattern: too big for the current architecture
+//@ error-pattern: too big for the target architecture
 
 #[cfg(target_pointer_width = "64")]
 fn main() {
diff --git a/tests/ui/limits/issue-17913.stderr b/tests/ui/limits/issue-17913.stderr
index 893730cbbd2..e9c3c14e181 100644
--- a/tests/ui/limits/issue-17913.stderr
+++ b/tests/ui/limits/issue-17913.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[&usize; usize::MAX]` are too big for the current architecture
+error: values of the type `[&usize; usize::MAX]` are too big for the target architecture
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/limits/issue-55878.rs b/tests/ui/limits/issue-55878.rs
index 4d91a173240..81696e226fd 100644
--- a/tests/ui/limits/issue-55878.rs
+++ b/tests/ui/limits/issue-55878.rs
@@ -2,7 +2,7 @@
 //@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE"
 //@ normalize-stderr-32bit: "4294967295" -> "SIZE"
 
-//@ error-pattern: are too big for the current architecture
+//@ error-pattern: are too big for the target architecture
 fn main() {
     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
 }
diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr
index 97ca0f4fb59..0a5f17be804 100644
--- a/tests/ui/limits/issue-55878.stderr
+++ b/tests/ui/limits/issue-55878.stderr
@@ -1,7 +1,7 @@
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
    |
-   = note: values of the type `[u8; usize::MAX]` are too big for the current architecture
+   = note: values of the type `[u8; usize::MAX]` are too big for the target architecture
    |
 note: inside `std::mem::size_of::<[u8; usize::MAX]>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
diff --git a/tests/ui/limits/issue-69485-var-size-diffs-too-large.rs b/tests/ui/limits/issue-69485-var-size-diffs-too-large.rs
index 9c150c119d0..6133183a55c 100644
--- a/tests/ui/limits/issue-69485-var-size-diffs-too-large.rs
+++ b/tests/ui/limits/issue-69485-var-size-diffs-too-large.rs
@@ -3,7 +3,7 @@
 //@ compile-flags: -Zmir-opt-level=0
 
 fn main() {
-    Bug::V([0; !0]); //~ ERROR are too big for the current
+    Bug::V([0; !0]); //~ ERROR are too big for the target
 }
 
 enum Bug {
diff --git a/tests/ui/limits/issue-69485-var-size-diffs-too-large.stderr b/tests/ui/limits/issue-69485-var-size-diffs-too-large.stderr
index 7b9b8f76d0c..7fa0ab95981 100644
--- a/tests/ui/limits/issue-69485-var-size-diffs-too-large.stderr
+++ b/tests/ui/limits/issue-69485-var-size-diffs-too-large.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[u8; usize::MAX]` are too big for the current architecture
+error: values of the type `[u8; usize::MAX]` are too big for the target architecture
   --> $DIR/issue-69485-var-size-diffs-too-large.rs:6:5
    |
 LL |     Bug::V([0; !0]);
diff --git a/tests/ui/limits/issue-75158-64.stderr b/tests/ui/limits/issue-75158-64.stderr
index 06aad9616cb..a3772e509ed 100644
--- a/tests/ui/limits/issue-75158-64.stderr
+++ b/tests/ui/limits/issue-75158-64.stderr
@@ -1,4 +1,4 @@
-error: values of the type `[u8; usize::MAX]` are too big for the current architecture
+error: values of the type `[u8; usize::MAX]` are too big for the target architecture
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin.rs
deleted file mode 100644
index f8aad88ecee..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-//@ check-pass
-#![crate_name = "NonSnakeCase"]
-
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin2.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin2.rs
deleted file mode 100644
index c077d81e9e5..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin2.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-//@ compile-flags: --crate-name NonSnakeCase
-//@ check-pass
-
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin3.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin3.rs
deleted file mode 100644
index 278f7cfd3ee..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-bin3.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-//@ check-pass
-#![crate_type = "bin"]
-#![crate_name = "NonSnakeCase"]
-
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.rs
deleted file mode 100644
index 781c6794fc2..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-#![crate_type = "cdylib"]
-#![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.rs
deleted file mode 100644
index 3f65295f068..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-#![crate_type = "dylib"]
-#![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.rs
deleted file mode 100644
index 20c58e66aa6..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-#![crate_type = "lib"]
-#![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.rs
deleted file mode 100644
index f0f2fa4393e..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-#![crate_type = "proc-macro"]
-#![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.stderr
deleted file mode 100644
index e0091057bc9..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-proc-macro.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate-proc-macro.rs:3:18
-   |
-LL | #![crate_name = "NonSnakeCase"]
-   |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
-   |
-note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate-proc-macro.rs:5:9
-   |
-LL | #![deny(non_snake_case)]
-   |         ^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.rs
deleted file mode 100644
index 1a558def3d0..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-#![crate_type = "rlib"]
-#![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.rs
deleted file mode 100644
index 2ec53c15eb8..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ only-x86_64-unknown-linux-gnu
-#![crate_type = "staticlib"]
-#![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name
-#![deny(non_snake_case)]
-
-fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.stderr
deleted file mode 100644
index 4ee6d5bd4d4..00000000000
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-staticlib.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate-staticlib.rs:3:18
-   |
-LL | #![crate_name = "NonSnakeCase"]
-   |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
-   |
-note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate-staticlib.rs:5:9
-   |
-LL | #![deny(non_snake_case)]
-   |         ^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
index a68c0e832b8..9bccb270627 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-lib.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate-lib.rs:3:18
+  --> $DIR/lint-non-snake-case-crate.rs:25:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate-lib.rs:5:9
+  --> $DIR/lint-non-snake-case-crate.rs:27:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
index 6e9d54bd5bc..9bccb270627 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-rlib.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate-rlib.rs:3:18
+  --> $DIR/lint-non-snake-case-crate.rs:25:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate-rlib.rs:5:9
+  --> $DIR/lint-non-snake-case-crate.rs:27:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
index 4ee1a9cb3dd..9bccb270627 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-dylib.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate-dylib.rs:3:18
+  --> $DIR/lint-non-snake-case-crate.rs:25:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate-dylib.rs:5:9
+  --> $DIR/lint-non-snake-case-crate.rs:27:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
index f9167aa8df3..9bccb270627 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate-cdylib.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate-cdylib.rs:3:18
+  --> $DIR/lint-non-snake-case-crate.rs:25:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate-cdylib.rs:5:9
+  --> $DIR/lint-non-snake-case-crate.rs:27:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
new file mode 100644
index 00000000000..9bccb270627
--- /dev/null
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
@@ -0,0 +1,14 @@
+error: crate `NonSnakeCase` should have a snake case name
+  --> $DIR/lint-non-snake-case-crate.rs:25:18
+   |
+LL | #![crate_name = "NonSnakeCase"]
+   |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-non-snake-case-crate.rs:27:9
+   |
+LL | #![deny(non_snake_case)]
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
new file mode 100644
index 00000000000..57604d99a07
--- /dev/null
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
@@ -0,0 +1,29 @@
+//! Don't lint on binary crate with non-snake-case names.
+//!
+//! See <https://github.com/rust-lang/rust/issues/45127>.
+
+//@ revisions: bin_ cdylib_ dylib_ lib_ proc_macro_ rlib_ staticlib_
+
+// Should not fire on binary crates.
+//@[bin_] compile-flags: --crate-type=bin
+//@[bin_] check-pass
+
+// But should fire on non-binary crates.
+
+//@[cdylib_] ignore-musl (dylibs are not supported)
+//@[dylib_] ignore-musl (dylibs are not supported)
+//@[dylib_] ignore-wasm (dylib is not supported)
+//@[proc_macro_] ignore-wasm (dylib is not supported)
+
+//@[cdylib_] compile-flags: --crate-type=cdylib
+//@[dylib_] compile-flags: --crate-type=dylib
+//@[lib_] compile-flags: --crate-type=lib
+//@[proc_macro_] compile-flags: --crate-type=proc-macro
+//@[rlib_] compile-flags: --crate-type=rlib
+//@[staticlib_] compile-flags: --crate-type=staticlib
+
+#![crate_name = "NonSnakeCase"]
+//[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name
+#![deny(non_snake_case)]
+
+fn main() {}
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
new file mode 100644
index 00000000000..9bccb270627
--- /dev/null
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
@@ -0,0 +1,14 @@
+error: crate `NonSnakeCase` should have a snake case name
+  --> $DIR/lint-non-snake-case-crate.rs:25:18
+   |
+LL | #![crate_name = "NonSnakeCase"]
+   |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-non-snake-case-crate.rs:27:9
+   |
+LL | #![deny(non_snake_case)]
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/rust-cold-fn-accept-improper-ctypes.rs b/tests/ui/lint/rust-cold-fn-accept-improper-ctypes.rs
new file mode 100644
index 00000000000..dc929e14527
--- /dev/null
+++ b/tests/ui/lint/rust-cold-fn-accept-improper-ctypes.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+#![feature(rust_cold_cc)]
+
+// extern "rust-cold" is a "Rust" ABI so we accept `repr(Rust)` types as arg/ret without warnings.
+
+pub extern "rust-cold" fn f(_: ()) -> Result<(), ()> {
+    Ok(())
+}
+
+extern "rust-cold" {
+    pub fn g(_: ()) -> Result<(), ()>;
+}
+
+fn main() {}
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
new file mode 100644
index 00000000000..ff28548b795
--- /dev/null
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
@@ -0,0 +1,6 @@
+//@ error-pattern: circular modules
+// Regression test for #97589: a doc-comment on a circular module bypassed cycle detection
+
+#![crate_type = "lib"]
+
+pub mod recursive;
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr
new file mode 100644
index 00000000000..02d6406775a
--- /dev/null
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr
@@ -0,0 +1,8 @@
+error: circular modules: $DIR/recursive.rs -> $DIR/recursive.rs
+  --> $DIR/recursive.rs:6:1
+   |
+LL | mod recursive;
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
new file mode 100644
index 00000000000..3d758be8c05
--- /dev/null
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
@@ -0,0 +1,6 @@
+//@ ignore-test: this is an auxiliary file for circular-module-with-doc-comment-issue-97589.rs
+
+//! this comment caused the circular dependency checker to break
+
+#[path = "recursive.rs"]
+mod recursive;
diff --git a/tests/ui/print-calling-conventions.stdout b/tests/ui/print-calling-conventions.stdout
index da67a57f420..4415b3c858e 100644
--- a/tests/ui/print-calling-conventions.stdout
+++ b/tests/ui/print-calling-conventions.stdout
@@ -1,5 +1,6 @@
 C
 C-cmse-nonsecure-call
+C-cmse-nonsecure-entry
 C-unwind
 Rust
 aapcs
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs
index 348bf839b69..ea3cbabf302 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs
@@ -39,7 +39,6 @@ impl const Foo for NonConstAdd {
 #[const_trait]
 trait Baz {
     type Qux: Add;
-    //~^ ERROR the trait bound
 }
 
 impl const Baz for NonConstAdd {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
index 405212b52c7..c20b53c210f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -12,17 +12,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
    = note: the next trait solver must be enabled globally for the effects feature to work correctly
    = help: use `-Znext-solver` to enable
 
-error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied
-  --> $DIR/assoc-type.rs:41:15
-   |
-LL |     type Qux: Add;
-   |               ^^^ the trait `Compat` is not implemented for `Add::{synthetic#0}`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait Baz where Add::{synthetic#0}: Compat {
-   |           ++++++++++++++++++++++++++++++++
-
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 1 previous error; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/suggestions/let-binding-init-expr-as-ty.rs b/tests/ui/suggestions/let-binding-init-expr-as-ty.rs
index 06ee421fc32..71e5a0c728d 100644
--- a/tests/ui/suggestions/let-binding-init-expr-as-ty.rs
+++ b/tests/ui/suggestions/let-binding-init-expr-as-ty.rs
@@ -1,8 +1,8 @@
 pub fn foo(num: i32) -> i32 {
     let foo: i32::from_be(num);
     //~^ ERROR expected type, found local variable `num`
-    //~| ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| ERROR ambiguous associated type
+    //~| ERROR argument types not allowed with return type notation
+    //~| ERROR return type notation not allowed in this position yet
     foo
 }
 
diff --git a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr
index b90ae051fb7..83a5441e3c0 100644
--- a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr
+++ b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr
@@ -6,29 +6,22 @@ LL |     let foo: i32::from_be(num);
    |            |
    |            help: use `=` if you meant to assign
 
-error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/let-binding-init-expr-as-ty.rs:2:19
+error: argument types not allowed with return type notation
+  --> $DIR/let-binding-init-expr-as-ty.rs:2:26
    |
 LL |     let foo: i32::from_be(num);
-   |                   ^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |                          ^^^^^ help: remove the input types: `()`
    |
-help: use angle brackets instead
-   |
-LL |     let foo: i32::from_be<num>;
-   |                          ~   ~
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = help: add `#![feature(return_type_notation)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0223]: ambiguous associated type
+error: return type notation not allowed in this position yet
   --> $DIR/let-binding-init-expr-as-ty.rs:2:14
    |
 LL |     let foo: i32::from_be(num);
    |              ^^^^^^^^^^^^^^^^^
-   |
-help: if there were a trait named `Example` with associated type `from_be` implemented for `i32`, you could use the fully-qualified path
-   |
-LL |     let foo: <i32 as Example>::from_be;
-   |              ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0214, E0223, E0573.
-For more information about an error, try `rustc --explain E0214`.
+For more information about this error, try `rustc --explain E0573`.
diff --git a/tests/ui/transmutability/arrays/huge-len.stderr b/tests/ui/transmutability/arrays/huge-len.stderr
index 1fa16c649d4..2f8a86df0a7 100644
--- a/tests/ui/transmutability/arrays/huge-len.stderr
+++ b/tests/ui/transmutability/arrays/huge-len.stderr
@@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded`
   --> $DIR/huge-len.rs:21:41
    |
 LL |     assert::is_maybe_transmutable::<(), ExplicitlyPadded>();
-   |                                         ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture
+   |                                         ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the target architecture
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/huge-len.rs:8:14
@@ -17,7 +17,7 @@ error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
   --> $DIR/huge-len.rs:24:55
    |
 LL |     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
-   |                                                       ^^ values of the type `ExplicitlyPadded` are too big for the current architecture
+   |                                                       ^^ values of the type `ExplicitlyPadded` are too big for the target architecture
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/huge-len.rs:8:14